序列 Padding 与 Mask
把变长序列补齐成规则张量,并明确有效位置、padding 和 causal mask 语义。
学习目标
- 两条序列的有效位置计数
- 只把 padding embedding 置零够吗?
- 说明:补齐只解决形状,mask 的方向和应用位置仍需按每个算子确认。
为什么需要这个概念
padding 为变长样本补上占位值,mask 标注哪些位置有效。有效位置、禁止注意力位置与损失忽略位置是相关但不同的接口。
学习前需要掌握
背景与问题
同一批句子长度不同,直接堆叠会失败。padding 把形状补齐,但补出来的位置不是真实内容,必须避免它们影响表示、损失和指标。
概念定义
padding 为变长样本补上占位值,mask 标注哪些位置有效。有效位置、禁止注意力位置与损失忽略位置是相关但不同的接口。
直观理解
补齐的空座位只是为了让每排长度相同,统计乘客数量时不能把空座也当人。
核心原理
右侧 padding 时,可用位置索引小于长度生成 valid mask。动态按批内最大长度补齐可减少浪费;若按固定全局最大长度,短样本会承担较多无用计算。左 padding 则可能需要重新定义位置编号。
序列求均值时用 mask 控制分子和分母,token 级损失可使用 ignore_index 或 masked reduction,评估同样只计有效 token。只在模型输入置零并不足够,因为偏置、位置编码和注意力仍能让 padding 产生非零表示。
不同 API 对 bool mask 的方向约定可能相反。应明确 valid 的 True 表示有效,转换成某个模块的屏蔽 mask 时再取反,避免同一个变量在不同上下文混用。全空序列还需要单独的数据策略。
数学表达
核心公式
padding 为变长样本补上占位值,mask 标注哪些位置有效。有效位置、禁止注意力位置与损失忽略位置是相关但不同的接口。
变量含义
length_n第 n 条真实长度m有效 mask
计算步骤
- 1valid mask 为 (真,真,真)、(真,假,假)。
- 2按有效数计算平均,分别除以 3 和 1。
代码对应位置
示例 1两条序列的有效位置计数的最小验证:使用完整构造输入核对两条序列的有效位置计数,输出只表示本例计算。
变量解释
| 变量 | 含义 |
|---|---|
length_n | 第 n 条真实长度 |
m | 有效 mask |
完整数值示例
两条序列的有效位置计数
已知条件
- 长度分别为 3 和 1
- 补齐到长度 3,数值为 (1,2,3)、(4,0,0)
计算步骤
- valid mask 为 (真,真,真)、(真,假,假)。
- 按有效数计算平均,分别除以 3 和 1。
计算结果
有效均值为 2 和 4;不加 mask 的第二条均值仅为 1.3333。
处理前后对比
- 补齐只解决形状,mask 的方向和应用位置仍需按每个算子确认。
两条序列的有效位置计数
即使 padding 恰好是零,错误也已存在于分母。若后续加了位置向量,分子同样会被污染,所以应贯穿模型、池化、损失和评估检查 mask。
本例没有全空样本。代码分母使用 clamp_min 避免数值除零,但不会因此把空序列变成有意义的数据;真实输入应事先决定是否拒绝或映射为空标记。
计算与实现步骤
- valid mask 为 (真,真,真)、(真,假,假)。
- 按有效数计算平均,分别除以 3 和 1。
代码实现
示例 1
两条序列的有效位置计数的最小验证
example_01.py用途:使用完整构造输入核对两条序列的有效位置计数,输出只表示本例计算。
import torch
lengths = torch.tensor([3, 1])
x = torch.tensor([[1., 2., 3.], [4., 0., 0.]])
valid = torch.arange(3)[None, :] < lengths[:, None]
means = (x * valid).sum(1) / valid.sum(1).clamp_min(1)
print(valid.tolist())
print("valid counts:", valid.sum(1).tolist())
print("masked means:", means.tolist())代码解析
解析始终位于完整代码下方,并按实际代码段逐项对应。
输入数据与任务
使用完整构造输入核对两条序列的有效位置计数,输出只表示本例计算。
Step 1 · 1–8 行
导入当前步骤需要的数值计算、预处理、模型或评价工具。依赖集中写在代码开头,便于复现。
import torch
lengths = torch.tensor([3, 1])
x = torch.tensor([[1., 2., 3.], [4., 0., 0.]])
valid = torch.arange(3)[None, :] < lengths[:, None]
means = (x * valid).sum(1) / valid.sum(1).clamp_min(1)
print(valid.tolist())
print("valid counts:", valid.sum(1).tolist())
print("masked means:", means.tolist())代码与数学原理
减去训练均值并除以训练标准差,对应代码中的 mean/std 或 StandardScaler。
预期输出或运行结果
[[True, True, True], [True, False, False]] valid counts: [3, 1] masked means: [2.0, 4.0]
常见错误 · 5 条
- 不要在测试集上调用 fit 或 fit_transform;测试集只能复用训练参数。
- mask 方向反
- padding 入 Accuracy
- 空序列
- mask 轴错
实际应用
- 变长文本的动态组批
- token 级损失和序列池化
常见错误
- mask 方向反
- padding 入 Accuracy
- 空序列
- mask 轴错
常见问题
只把 padding embedding 置零够吗?
不够。平均的分母、注意力归一化、后续偏置与损失都可能继续受影响,应在相应运算上显式排除。
这个示例能说明什么边界?
补齐只解决形状,mask 的方向和应用位置仍需按每个算子确认。
推荐学习资料
参考库不会生成虚假资源或无效外部链接。