qinghuan
← 回到知识探索

AI 直觉 / 动手实验

同批输入补了零,为什么计算时还得遮住?

补齐长度方便一起计算,另记有效位置,才能知道哪些数字该参与平均、哪些预测该计入损失。

展开本文目录
  1. 先动手看看
  2. 长度一样,不代表每个位置都有内容
  3. 先排除占位,再数分母
  4. 能参考的位置,和要计分的位置
  5. 全部都是占位时,别写成零误差
  6. 记住这三点
  7. 别把例子用过头
  8. 自己试一小步
  9. 查原始资料
  10. 找一份资料继续练
开始前,会这些就够了
  • 知道平均数怎样计算
  • 能阅读 Python 列表
遇到不熟悉的词,先看这 1 个解释
填充与有效位置掩码
把长短不同的记录补成相同长度,方便一起处理;再用与数据对齐的标记说明哪些位置是真实内容,哪些只是占位。
打开完整术语小抄 ↗

假设一批输入里,第一条记录有三个数字,第二条只有一个。为了排成整齐的表,程序给第二条补上两个零。这种补齐叫 padding。但补出来的零不是第二条记录的新内容,只是暂时占个位置。

像登记表里的空格:为了让每一行同样宽而画出格子,不代表空格里真的记录了一次零分。机器不会凭外观猜出区别,因此通常还要保留一份“哪些格子有效”的标记。

零是原来的内容,还是后来补上的?

原始记录是 [4, 0, 8] 和 [6],都排成三格。第一条里的 0 是真实内容;第二条后面的两个 0 是填充。固定预测为 [3, 2, 9] 和 [4, 0, 0]。

观察没有真实记录的边界
来源标记保持独立;颜色之外,每行也写明是否纳入本次统计
位置目标数字来源预测数字误差平方本次统计
第 1 行第 1 格4真实内容31纳入
第 1 行第 2 格0真实内容,确实为024纳入
第 1 行第 3 格8真实内容91纳入
第 2 行第 1 格6真实内容44纳入
第 2 行第 2 格0补齐的占位00忽略
第 2 行第 3 格0补齐的占位00忽略

真实位置有 4 个;当前规则纳入 4 个位置。

目标均值:4.50(18 ÷ 4)。平均平方误差(MSE):2.50(10 ÷ 4)。

保留了真实的 0,同时排除了两个占位。每个有效位置按同样权重计算。

这里仅计算固定数字的均值与误差平方,没有运行神经网络。当前选择的是统计位置:注意力掩码控制哪些位置可被参考,损失掩码控制哪些目标计分,两者不能互相代替。误差平方越小也不能单独证明真实模型更好。

长度一样,不代表每个位置都有内容

掩码(mask)就是与数据对齐的一排标记。本例用1表示有效位置、0表示填充位置,而且根据原来的长度生成标记。第一行的数字0是真实内容,照样标成1;不能用“数值等于0”来猜哪个位置是补的。

文字模型通常用专门的填充符号及其编号补齐,编号不一定是0。Hugging Face 的文档列出了补到本批最长长度、补到指定长度等方式。补齐增加占位,截断则删掉超长部分,二者对内容的影响不同。

先排除占位,再数分母

下面是原创数字实验:两条记录分别为[4, 0, 8]和[6],统一补到三个位置。直接除以全部六个位置,会把平均值压低;只选有效位置后,应除以四。真实的零仍然算一个有效位置,不能顺手丢掉。

损失是给预测误差计分的数字。这里采用“预测减目标,再平方”的简单方法。两个填充位置的误差恰好为零,但把它们算进分母,仍会让平均损失显得更小。程序只演示按位置统计,没有训练模型,也没有实现注意力。

小实验 · python
def masked_mean(values, mask):
    if len(values) != len(mask) or any(m not in (0, 1) for m in mask):
        raise ValueError('values and a 0/1 mask must align')
    kept = [value for value, active in zip(values, mask) if active]
    return sum(kept) / len(kept) if kept else None


rows = [[4, 0, 8], [6]]
width = max(map(len, rows))
padded = [row + [0] * (width - len(row)) for row in rows]
masks = [[1] * len(row) + [0] * (width - len(row)) for row in rows]
values = [value for row in padded for value in row]
valid = [active for row in masks for active in row]
predictions = [3, 2, 9, 4, 0, 0]
losses = [(pred - target) ** 2 for pred, target in zip(predictions, values)]

print('padded:', padded)
print('mask:', masks)
print(f'all-position mean: {sum(values) / len(values):.2f}')
print(f'valid-position mean: {masked_mean(values, valid):.2f}')
print(f'all-position loss: {sum(losses) / len(losses):.2f}')
print(f'valid-position loss: {masked_mean(losses, valid):.2f}')
empty = masked_mean([0, 0], [0, 0])
print('all-padding:', 'no valid positions' if empty is None else empty)

怎样运行:保存为 padding_positions.py,用 Python 3.10 或更新版本运行:python padding_positions.py。仅用标准库,不联网。

运行后对照结果
padded: [[4, 0, 8], [6, 0, 0]]
mask: [[1, 1, 1], [1, 0, 0]]
all-position mean: 3.00
valid-position mean: 4.50
all-position loss: 1.67
valid-position loss: 2.50
all-padding: no valid positions

能参考的位置,和要计分的位置

注意力掩码(attention mask)控制注意力计算能参考哪些位置,例如不把补齐的格子当作可读取的内容。损失掩码(loss mask)控制哪些目标位置参与误差计分。一个管信息怎样参与计算,一个管训练目标怎样计分,不能只设置其中一个就假定另一个也处理好了。

例如某项任务让前面的文字提供提示,只对后面的回答计分;提示仍可能需要被参考,却不作为本次损失的目标。具体规则要看模型与任务。所引 PyTorch 损失接口支持忽略指定的目标编号,但这不是所有损失函数通用的开关,也不等于把输入数字设成零。

全部都是占位时,别写成零误差

若没有任何有效位置,平均数就没有可用的分母。本例返回 None,并显示提示。实际训练应明确选择跳过、拒绝还是另行处理,不能把没有评分对象记成“预测全部正确”。不同任务的空样本规则需要单独确认。

还要说明你平均的单位:本例把每个有效位置看作一份;先算每条记录的平均,再平均各条记录,会给长短记录同样的权重,两种结果可能不同。继续读文档时,可分别寻找 padding、attention_mask 和忽略目标的参数,确认它们各自在处理什么。

记住这三点

  • 补齐只解决长度对齐,还需要根据原始长度或明确标记识别有效位置。
  • 忽略填充时,平均值的分子与分母都要按同一套有效位置统计。
  • 注意力掩码与损失掩码职责不同,全填充输入和平均单位也要明确处理。

别把例子用过头

  • 真实内容也可能是零;填充编号和掩码取值含义要以具体接口为准。
  • 本例的误差平方不等于语言模型常用的分类损失,没有复现训练或完整 Transformer。
  • 屏蔽注意力中的填充位置,不保证其输出自动为零,也不代表后续平均或损失已自动忽略它。

自己试一小步

当一条记录变长、另一条变空时,怎样确认填充没有偷偷影响你的统计?

  1. 在真实内容中再放入一个零,保持它的有效标记为1。
  2. 只增加填充位置,比较按有效位置计算的均值和损失。
  3. 加入空记录,分别写清按有效位置平均与按记录平均的处理规则。

做到这些,就算完成

  • 真实的零是否仍被保留?
  • 是否解释了每次除法的分母,并处理没有有效位置的情况?
  • 是否能说明本例的统计掩码与模型中的注意力掩码有什么区别?

查原始资料

想确认一个细节,先看这份资料对应的部分,不必从头读完所有文档。

  • Hugging Face:Padding and truncation (新标签页)↗Hugging Face · 英文

    变长批次的补齐、特殊填充符号、补到批次最长或指定长度,以及补齐和截断的区别。

    2026-09-26 已读 main 版本正文的三项参数与策略表;默认版本入口当次未提供该页。阅读不需要安装库。

  • Hugging Face:Glossary / attention mask (新标签页)↗Hugging Face · 英文

    attention mask 指定可被参考的位置;BERT 分词示例中的1/0标记与补齐编号。

    2026-09-26 已读 attention mask 小节、补齐 input_ids 与对应标记;未下载或运行其模型。

  • PyTorch:CrossEntropyLoss (新标签页)↗PyTorch · 英文

    目标为类别编号时 ignore_index 排除目标位置,mean 按非忽略目标及相应权重汇总;与输入补齐分开设置。

    2026-09-26 已读类别编号目标公式、ignore_index 与 reduction 参数;本文用标准库误差平方演示,不声称执行了此接口。

找一份资料继续练

先选一项,按下面的范围继续学;不必从头读完整门课程。