在深度学习中,经常遇到一些专有名词,用这个博客总结一下。

一、context vector 上下文向量

在神经网络(尤其是序列模型、注意力机制、Transformer 等领域)中,context vector(上下文向量) 是一个非常核心的概念。它的作用是:
浓缩和表示输入序列中与当前预测任务相关的信息。

1. context vector 的来源和直觉

最早的 context vector 出现在 Encoder–Decoder(编码器–解码器)结构的神经机器翻译模型中。

  • Encoder(编码器)将一个输入序列(例如一句英文)转换成若干隐藏状态向量 h 1 , h 2 , . . . , h T h_1, h_2, ..., h_T h1,h2,...,hT
  • Decoder(解码器) 需要根据这些编码信息生成目标序列(例如一句中文)。

在最早的 seq2seq 模型(没有注意力机制时):

编码器最后一个隐藏状态 h T h_T hT 被直接拿来当成一个固定长度的 context vector

这个向量 c = h T c = h_T c=hT 被认为代表整个输入句子的语义。

缺点:当句子很长时,信息压缩太严重,模型难以记住所有上下文。

2. 注意力机制下的 context vector

在引入 Attention(注意力) 后,context vector 的定义变得更加灵活、强大。

对于解码器在生成第 t t t 个词时,我们不再只依赖编码器的最后一个状态,而是根据注意力权重从所有隐藏状态中“加权求和”出一个上下文表示:

c t = ∑ i = 1 T α t , i h i c_t = \sum_{i=1}^{T} \alpha_{t,i} h_i ct=i=1Tαt,ihi

其中:

  • h i h_i hi:编码器第 i i i 个时间步的隐藏状态;
  • α t , i \alpha_{t,i} αt,i:表示在生成第 ( t ) 个词时,对输入第 ( i ) 个词的注意力权重(权重之和为 1); α t , i \alpha_{t,i} αt,i 是由编码器的当前隐藏状态 h t h_t ht 与解码器的隐藏状态 s t − 1 s_{t-1} st1 求得。
  • c t c_t ct:第 t t t 个时刻的 context vector,也就是“当前输出所需的上下文信息”。

然后解码器用 c t c_t ct 和自己当前的隐藏状态 s t s_t st 一起生成输出。

这个 s t s_t st 是解码器的隐藏状态,一般是 s t − 1 s_{t-1} st1 y ^ t − 1 \hat{y}_{t-1} y^t1 的表达式

二、 batch size 批量大小

在训练神经网络时,我们通常有一个训练集,包含很多样本:
{ ( x 1 , y 1 ) , ( x 2 , y 2 ) , . . . , ( x N , y N ) } \{(x_1, y_1), (x_2, y_2), ..., (x_N, y_N)\} {(x1,y1),(x2,y2),...,(xN,yN)}

一般情况下,每一个训练集样本都能计算得到参数 θ \theta θ 的梯度:
∇ θ ℓ ( x i , y i ) \nabla_\theta \ell(x_i, y_i) θ(xi,yi)
然后更新参数;或者将全部训练集的梯度求平均,然后更新参数。但现实中,数据量通常非常大(成千上万甚至上亿样本), 于是我们采用一种折中方案,我们把数据分成若干个小批(batch):

Batch 1 : { ( x 1 , y 1 ) , … , ( x B , y B ) } Batch 2 : { ( x B + 1 , y B + 1 ) , …   } \text{Batch 1}: \{(x_1, y_1), \dots, (x_B, y_B)\} \\ \text{Batch 2}: \{(x_{B+1}, y_{B+1}), \dots\} Batch 1:{(x1,y1),,(xB,yB)}Batch 2:{(xB+1,yB+1),}

每个批次包含 B B B个样本,这个 B B B 就是 batch size

然后每次迭代时,我们只用这个批次的数据计算平均损失与梯度:

∇ θ L batch = 1 B ∑ i = 1 B ∇ θ ℓ ( x i , y i ) \nabla_\theta L_{\text{batch}} = \frac{1}{B} \sum_{i=1}^{B} \nabla_\theta \ell(x_i, y_i) θLbatch=B1i=1Bθ(xi,yi)

并更新参数:
θ ← θ − η   ∇ θ L batch \theta \leftarrow \theta - \eta \, \nabla_\theta L_{\text{batch}} θθηθLbatch

这样模型在遍历完所有批次后,等效地看过了整个训练集。

1. batch 的优势

在深度学习中,计算的主要瓶颈是:

  • 矩阵乘法(Matrix Multiplication)
  • 卷积(Convolution)

而这些操作在 GPU / TPU 上都能 高度并行化 —— GPU 最擅长的就是同时处理很多相似的计算任务。

CPU:中央处理器,GPU (graphics processing unit) 图形处理器,TPU (tensor processing unit) 张量处理器

如果每次只输入 1 个样本(即 batch size = 1):

  • GPU 大部分计算单元(CUDA cores)都闲着;
  • 计算效率极低。

但如果你一次喂进去一批样本(batch):

  • 你就可以在一轮前向传播和反向传播中 并行计算多个样本的梯度
  • GPU 计算单元能被充分利用,吞吐量大幅提升 。

假设我们有一个线性层:
y = W x + b y = Wx + b y=Wx+b
其中:

  • W W W 是矩阵
  • x x x 是输入向量,形状是 [ d in , 1 ] [d_{\text{in}}, 1] [din,1]

当 batch size = 1 时,输入只有一个样本:
x = [ x 1 , x 2 , … , x d in ] x = [x_1, x_2, \dots, x_{d_{\text{in}}}] x=[x1,x2,,xdin]
计算是一个矩阵–向量乘法(matrix–vector product),效率较低。

当 batch size = B 时,输入是多个样本堆叠成一个矩阵:
X = [ x ( 1 ) x ( 2 ) ⋮ x ( B ) ] 形状: [ B , d in ] X = \begin{bmatrix} x^{(1)} \\ x^{(2)} \\ \vdots \\ x^{(B)} \end{bmatrix} \quad \text{形状:} [B, d_{\text{in}}] X= x(1)x(2)x(B) 形状:[B,din]

现在计算变成:
Y = X W T + b Y = XW^T + b Y=XWT+b
这是一个 矩阵–矩阵乘法(matrix–matrix product), 可以一次性计算出所有样本的输出 Y ∈ R B × d out Y \in \mathbb{R}^{B \times d_{\text{out}}} YRB×dout。 GPU 对矩阵–矩阵乘法的优化极好,因此速度非常快。

Batch size 的并行优势总结:

优势说明
高效利用 GPU 并行计算能力一次计算多个样本的梯度,提高吞吐量
降低显存访问开销一次加载多个样本的数据,减少 I/O 延迟
减少参数更新频率每个 batch 更新一次参数,减少同步/通信成本(在多 GPU 训练中尤为明显)
梯度估计更稳定多个样本平均后的梯度方差更小,使优化更平滑

2. 常见的三种训练方式

方式Batch size特点
全批次(Batch GD)= N(全数据集)准确但非常慢、内存占用极大
小批次(Mini-batch GD)例如 32、64、128训练稳定、高效(常用方式)
随机梯度(SGD)= 1每个样本单独更新,噪声大但有助于跳出局部最优

3. 对学习率的影响

  • 大 batch → 通常需要 更大的学习率
  • 小 batch → 需要 较小的学习率 才稳定

4. 常见经验值(深度学习实践)

模型类型常见 batch size 范围
MLP / 小型 CNN32 ~ 128
ResNet / 图像分类128 ~ 1024(取决于 GPU 内存)
Transformer / NLP16 ~ 512(经常取 32 或 64)
大模型预训练(BERT, GPT 等)1024 ~ 8192(跨多 GPU 并行)

5. batch_first=True

在 PyTorch 的 RNN / LSTM / GRU 中,batch_first=True 是一个非常常用的参数,它控制 输入张量的维度顺序.

RNN / LSTM / GRU 的输入通常是一个三维张量:

(input_seq) shape = (seq_len, batch_size, input_size)
  • seq_len:序列长度(时间步数)

  • batch_size:一次送入网络的样本数量

  • input_size:每个时间步的特征维度

也就是说,如果不指定 batch_first=True,默认第一维是时间步,第二维是 batch;如果指定了,则输入张量的 shape 就变成:

(batch_size, seq_len, input_size)

这通常更符合常见的数据组织方式。

三、 embedding 嵌入

在机器学习中,embedding 主要是将一些分类数据或高维数据转化为稠密向量。

  • 稠密向量是大部分元素为非零的向量

通过 embedding,很多非数值型数据,例如文字,图形,季节等,都可以转化为数值向量,进而可以方便进行一些机器学习操作,例如比较不同文本的语义相似性等。

  • 对于类别数据,嵌入向量的数量一般为类别数,而维度一般为向量数量的一半
  • 每个 embedding 向量在开始时是随机的,默认使用的是均匀分布初始化:U(-sqrt(1/num_embeddings), sqrt(1/num_embeddings))
  • 这些向量会在训练过程中被模型更新和学习,逐渐获得语义或分类意义;更新公式类似神经元的阈值 b b b,只不过embedding 向量一般是所有神经元共享的值。
"""
@Python version : 3.12
@Author  : Zhen Chen
@Email   : chen.zhen5526@gmail.com
@Time    : 08/11/2025, 17:13
@Desc    : 

"""
import torch
import torch.nn as nn

# 假设:
# season 有 4 种类别(春=0, 夏=1, 秋=2, 冬=3)
# weekday 有 7 种类别(周一=0, 周二=1, ... 周日=6)
season_embedding = nn.Embedding(num_embeddings=4, embedding_dim=2)  # 4类 → 2维向量
weekday_embedding = nn.Embedding(num_embeddings=7, embedding_dim=3) # 7类 → 3维向量

# 举例:今天是“夏季”(1),星期三(2)
season_id = torch.tensor([1])
weekday_id = torch.tensor([2])

# 获取 embedding 向量
season_vec = season_embedding(season_id)
weekday_vec = weekday_embedding(weekday_id)

print("Season embedding:", season_vec)
print("Weekday embedding:", weekday_vec)

# 拼接成最终时间特征向量
# dim=-1 表示“最后一个维度",等价于按列拼接 dim = 1
time_feature = torch.cat([season_vec, weekday_vec], dim= -1)
print("Combined time feature:", time_feature)

输出:

Season embedding: tensor([[-0.4688, 1.2908]], grad_fn=)
Weekday embedding: tensor([[-0.0352, 0.5716, 0.4113]], grad_fn=)
Combined time feature: tensor([[-0.4688, 1.2908, -0.0352, 0.5716, 0.4113]], grad_fn=)

四 、token 标记

token 是深度学习模型输入的“文本最小单位”,是模型理解语言的基础。在深度学习,尤其是自然语言处理(NLP)中,token(标记) 是将文本切分后得到的最小处理单位。模型并不是直接处理原始句子,而是处理一串 token。

例如,输入这句话:

我现在的这句话如何切分成token的?

先被切分为不同的分词:

["我", "现在", "的", "这", "句", "话", "如", "何", "切", "分", "成", "token", "的", "?"]

不同的分词对应不同的 id:

[ 29724, 31245, 32238, 30566, 30891, 30840, 30455,
  30322, 32011, 30992, 30788, 10792, 32238, 30915 ]
  • 中文中一个汉字通常是 1 个 token,但某些特殊字符可能更多
  • 一个标点符号通常是一个 token
  • 英文中一个单词或者子词可能是 1 个 token
    • 例如:“unbelievable” → [“un”, “believ”, “able”]
  • 不同的大语言模型的 token 字典可能不一样

五 、one hot

One-hot(独热编码) 是机器学习中最常用的类别特征编码方式,用来把“不能直接输入模型的分类变量”转换为模型可以理解的数字向量。

例如,一个天气类别:

天气 = {晴天, 阴天, 雨天}

其中的三个天气类别的 one-hot 编码分别是:

{1, 0, 0}
{0, 1, 0}
{0, 0, 1}

六、torch.32 与 torch.64

torch.float32:也叫单精度浮点数 (single precision float)

  • 32 位(4 字节)表示一个浮点数

  • 精度大约 7 位有效数字

  • 范围约 1.2e-38 到 3.4e38

torch.float64:也叫 双精度浮点数 (double precision float)

  • 64 位(8 字节)

  • 精度大约 16 位有效数字

  • 范围约 2.2e-308 到 1.8e30

属性torch.float32torch.float64
占用内存4 bytes8 bytes
精度~7 位有效数字~16 位有效数字
计算速度更快(尤其是 GPU)较慢
用途深度学习训练/推理高精度科学计算/数值分析

大部分神经网络训练中,精度在 float32 就够用了

unsqueeze()

unsqueeze(dim) 的作用是:在指定位置 dim,新增一个 size = 1 的维度。它不会改变数据,只是改变 tensor 的形状 (shape)。

注意:pytorch 的维度从 0 开始

下面的例子,x 的 shape 是 (3,),只有一个维度: 维度0,使用 unsqueeze(1) 后,增加了一个维度 1,shape 变成了 (3, 1),相当于转置了。

x = torch.tensor([1, 2, 3])
x.unsqueeze(1)
Out[12]: 
tensor([[1],
        [2],
        [3]])

参考文献1


  1. https://www.geeksforgeeks.org/machine-learning/what-are-embeddings-in-machine-learning/ ↩︎

更多推荐