0x02 理解 embedding 层中 padding_idx 的作用
#1 官方描述
使用 nn.Embedding 层,会涉及到一个位置参数 padding_idx。其官方文档中的描述为:
padding_idx (int, optional) – If specified, the entries at padding_idx do not contribute to the gradient; therefore, the embedding vector at padding_idx is not updated during training, i.e. it remains as a fixed “pad”. For a newly constructed Embedding, the embedding vector at padding_idx will default to all zeros, but can be updated to another value to be used as the padding vector.
翻译成中文:
若指定该参数,则 padding_idx 位置上的条目不会参与梯度计算;因此在训练过程中,padding_idx 处的嵌入向量不会更新,即保持为固定的“填充”状态。对于新构建的 Embedding 层,padding_idx 处的嵌入向量默认初始化为全零,但可被更新为其他数值作为填充向量使用。
#2 为什么需要填充?
深度学习模型要求输入数据形状统一,但现实中的文本序列(如句子、段落)长度各异。例如:
- 句子 1:“我 爱 北京” → 长度 3
- 句子 2:“今天 天气 不错 适合 出门” → 长度 5
为了将这些句子批量输入模型,需要用特殊符号将短句子补到与长句子相同的长度:
# 填充后的索引表示(假设"我"=1, "爱"=2, ..., "PAD"=0)padded_sentences = [ [1, 2, 3, 0, 0], # 句子1填充2个0 [4, 5, 6, 7, 8] # 句子2无需填充]#3 核心作用
当在 nn.Embedding 中设置 padding_idx=0 时,PyTorch 会自动:
- 将索引 0 对应的词向量设为全零:
import torch.nn as nn
embedding = nn.Embedding(num_embeddings=10, embedding_dim=5, padding_idx=0)print(embedding.weight[0]) # 输出全零向量:tensor([0., 0., 0., 0., 0.])-
在训练过程中不更新这个向量:填充符号(如 0)没有实际语义,若模型学习它的表示,会引入噪声,甚至影响其他有效词的学习。
-
在计算损失时忽略填充位置:例如,在序列标注任务中,填充位置的预测结果不会计入损失函数,避免模型“关注”无意义的填充内容。
#4 直观例子
假设你有以下填充后的句子数据:
sentences = [ [1, 2, 3, 0, 0], # "我 爱 北京 <PAD> <PAD>" [4, 5, 6, 7, 8] # "今天 天气 不错 适合 出门"]不设置 padding_idx 的问题:
- 模型会尝试学习索引 0 的语义,导致其他词的表示可能被干扰。
- 填充位置的预测可能影响损失计算,降低模型性能。
设置 padding_idx=0 的效果:
- 索引 0 对应的向量始终是
[0, 0, 0, ...],不参与训练。 - 模型专注学习有效词(如“我”“爱”“北京”)的表示,提高效率和准确性。
为什么选择索引 0 作为填充? 这是一种约定俗成的做法,主要原因:
- 索引 0 通常未被使用:大多数词表从索引 1 开始分配(如
<UNK>= 1, “我” = 2, “爱” = 3),索引 0 自然成为填充的最佳选择。 - 代码简洁性:使用 0 作为填充值,可以直接用
torch.zeros()创建初始向量,无需额外处理。
参考文献
[1] MYH516. embedding padding idx=0 到底有什么意义[EB]//CSDN. (2025-06-28). https://blog.csdn.net/mayaohao/article/details/148983595.
支持与分享
如果这篇文章对你有帮助,欢迎分享给更多人或赞助支持!