Embedding 与序列数据
把 token id 映射为可学习向量,并用 padding、长度和 mask 组成 batch。
学习目标
- 带 padding 的向量平均
- Embedding 是否等价于对 one-hot 做线性变换?
- 说明:Embedding 只是表示学习组件,不自动理解语义、位置或 padding 的下游含义。
为什么需要这个概念
Embedding 是从离散索引到可学习稠密向量的查表映射。词表大小 V、向量维度 D 对应一个 V×D 参数矩阵,每个索引取出一行。
学习前需要掌握
背景与问题
文本 token、商品和离散类别通常先表示为整数编号。整数大小本身没有距离意义,不能把编号 100 直接当成比编号 2 强五十倍的连续特征。
概念定义
Embedding 是从离散索引到可学习稠密向量的查表映射。词表大小 V、向量维度 D 对应一个 V×D 参数矩阵,每个索引取出一行。
直观理解
编号是书架位置,向量是书的内容表示;编号相邻不保证语义相近,向量相近要由训练目标形成。
核心原理
输入索引通常为 long 类型,形状 经 Embedding 后变为 。反向把梯度写回本次使用的行,重复索引的贡献会累计;词表与编号映射必须在训练、验证和部署保持一致。
padding_idx 可阻止默认梯度更新该填充行,但不会自动给后续注意力、池化或损失添加 mask。即使填充向量为零,直接平均仍会把分母增大,缩小短序列表示。
普通 token embedding 不包含顺序。若把向量直接无序求和,“猫追狗”与“狗追猫”可能无法区分;需要位置表示、RNN 或其他顺序机制。未登录词也应有事先定义的处理规则,不能临时分配与训练冲突的 ID。
数学表达
核心公式
Embedding 是从离散索引到可学习稠密向量的查表映射。词表大小 V、向量维度 D 对应一个 V×D 参数矩阵,每个索引取出一行。
变量含义
V词表大小Dembedding 维
计算步骤
- 1查表得到三个二维向量。
- 2仅对前两个有效向量求平均。
- 3与对全部三个位置求平均比较。
代码对应位置
示例 1带 padding 的向量平均的最小验证:使用完整构造输入核对带 padding 的向量平均,输出只表示本例计算。
变量解释
| 变量 | 含义 |
|---|---|
V | 词表大小 |
D | embedding 维 |
完整数值示例
带 padding 的向量平均
已知条件
- 词表三行向量为 (0,0)、(1,2)、(3,4)
- 序列编号为 (1,2,0),0 为 padding
计算步骤
- 查表得到三个二维向量。
- 仅对前两个有效向量求平均。
- 与对全部三个位置求平均比较。
计算结果
有效平均为 (2,3);直接平均变成约 (1.3333,2)。
处理前后对比
- Embedding 只是表示学习组件,不自动理解语义、位置或 padding 的下游含义。
带 padding 的向量平均
padding_idx 让填充向量为零,却不会告诉 mean 应除以 2 而不是 3。这个错误不会改变输出 shape,因此要从有效位置数量核对数值。
如果一批中存在全 padding 样本,还需明确处理策略。用 clamp_min(1) 可以避免除零,但空序列是否允许、应输出什么,仍是数据契约问题。
计算与实现步骤
- 查表得到三个二维向量。
- 仅对前两个有效向量求平均。
- 与对全部三个位置求平均比较。
代码实现
示例 1
带 padding 的向量平均的最小验证
example_01.py用途:使用完整构造输入核对带 padding 的向量平均,输出只表示本例计算。
import torch
from torch import nn
embedding = nn.Embedding(3, 2, padding_idx=0)
with torch.no_grad():
embedding.weight.copy_(torch.tensor([[0., 0.], [1., 2.], [3., 4.]]))
ids = torch.tensor([[1, 2, 0]])
x = embedding(ids)
valid = ids.ne(0)
masked = (x * valid.unsqueeze(-1)).sum(1) / valid.sum(1, keepdim=True).clamp_min(1)
print("shape:", tuple(x.shape))
print("masked mean:", masked.detach().tolist())
print("plain mean:", [[round(v, 4) for v in row] for row in x.mean(1).detach().tolist()])代码解析
解析始终位于完整代码下方,并按实际代码段逐项对应。
输入数据与任务
使用完整构造输入核对带 padding 的向量平均,输出只表示本例计算。
mean- 训练特征逐列均值。
Step 1 · 1–12 行
导入当前步骤需要的数值计算、预处理、模型或评价工具。依赖集中写在代码开头,便于复现。
import torch
from torch import nn
embedding = nn.Embedding(3, 2, padding_idx=0)
with torch.no_grad():
embedding.weight.copy_(torch.tensor([[0., 0.], [1., 2.], [3., 4.]]))
ids = torch.tensor([[1, 2, 0]])
x = embedding(ids)
valid = ids.ne(0)
masked = (x * valid.unsqueeze(-1)).sum(1) / valid.sum(1, keepdim=True).clamp_min(1)
print("shape:", tuple(x.shape))
print("masked mean:", masked.detach().tolist())
print("plain mean:", [[round(v, 4) for v in row] for row in x.mean(1).detach().tolist()])代码与数学原理
减去训练均值并除以训练标准差,对应代码中的 mean/std 或 StandardScaler。
预期输出或运行结果
shape: (1, 3, 2) masked mean: [[2.0, 3.0]] plain mean: [[1.3333, 2.0]]
常见错误 · 7 条
- 不要在测试集上调用 fit 或 fit_transform;测试集只能复用训练参数。
- id 当连续值
- 测试建词表
- 词表重建
- padding 入平均
- id 越界
- 确认样本轴、特征轴以及 X 与 y 的第一维完全对应。
实际应用
- 文本 token 表示
- 商品与离散类别的可学习特征
常见错误
- id 当连续值
- 测试建词表
- 词表重建
- padding 入平均
- id 越界
常见问题
Embedding 是否等价于对 one-hot 做线性变换?
在不含偏置的相同权重约定下,索引查表等价于选取 one-hot 对应行,但查表不必显式构造庞大的 one-hot 张量。
这个示例能说明什么边界?
Embedding 只是表示学习组件,不自动理解语义、位置或 padding 的下游含义。
推荐学习资料
Attention Is All You Need
提出完全基于注意力机制的 Transformer 架构,并用于序列建模和机器翻译。
Vaswani et al. · arXiv / NeurIPS