标签平滑的 temperature 参数怎么调?太平滑模型学不到东西、太尖锐又容易过拟合

有一阵子我干过一件蠢事:把训练配置里的 label_smoothing 从 0.1 一路调到 0.5,心想“越平滑越稳健”,总不会错吧。结果验证集准确率掉了一截,训练 loss 卡在一个高度上死活下不去。

AI technology illustration

后来我才想明白:标签平滑里的 ε 根本不是“平滑程度”,它设的是模型置信度的天花板。你把它推到 0.5,等于告诉模型“正确答案也只值一半的信任”,那模型的最优策略当然是装傻。

这件事还让我意识到,标题里问的“temperature”其实混了两个不同的旋钮:一个在训练目标里(ε),一个在 softmax 里(T)。它们都能让标签变“软”,但机制完全不同,调法也不一样。这篇就把它们拆开讲清楚。

ε 设的不是“平滑程度”,是置信度天花板

假设 K 类分类,真实标签是 y。one-hot 向量只在 y 位置是 1,其余全是 0。标签平滑把它改成:

qi = 1 − ε(当 i = y),qi = ε/(K−1)(当 i ≠ y)

说白了,你不再要求模型对正确类输出 100% 的概率,而是留出 ε 的空间让它“怀疑”。这个操作出自 Szegedy 2016 年的 Inception 论文,当时 ε=0.1 效果最好,之后成了事实标准——PyTorch 1.10 开始在 CrossEntropyLoss 里内置了这个参数,默认是 0。

ε 大一点会怎样?直接看表:

ε 模型最自信也就到 典型后果
0 100%(one-hot) 过度自信、校准差、容易过拟合
0.1 90% 泛化和校准都改善,最常用
0.3 70% 难任务开始欠拟合
0.5 50% 类间差异学不动,loss 下不去
0.9 10% 等于在学先验分布,基本没在学

太平滑为什么学不到东西:目标里根本没有“要自信”这一条

看梯度就懂了。对正确类别的 logit zy,交叉熵梯度是 (py − qy) = py − (1−ε)。训练把 py 推向 1−ε,一旦接近,梯度就趋近于零——模型觉得自己“已经完成任务了”。

所以这不是“没学好”,而是训练目标本身就不要求它自信。拿二分类举极端例子:ε=0.5 时目标分布就是 0.5/0.5,最优解是对任何样本都输出 50%,loss 的下界是 log(2)≈0.69,再低就不可能了。模型不是学得慢,是被要求装傻。

temperature 是另一个世界的旋钮:它决定“细节能不能被看见”

temperature 住在 softmax 的指数里:

pi = exp(zi/T) / Σj exp(zj/T)

T 越大,分布越接近均匀——这是“平滑”;T 越小越尖锐,T→0 就是 one-hot。但注意,T 不改变“谁排第一”,它改变的是小概率之间微小差别的可读性。

这个性质在蒸馏里是命根子。Hinton 2015 年的蒸馏论文说得很清楚:老师的 soft target 携带“暗知识”——比如一张手写数字 2,老师输出 0.8 给 2、0.15 给 3、0.05 给 7,这个“2 比 7 更像 3”的相对信息,正是学生该学的。

大意是:汽车可能被认成卡车,但几乎不可能被认成狗。这层“更像谁”的结构,在 one-hot 标签里完全不存在,只存在于 soft target 的相对大小里。

T 太低,soft target 退化成 one-hot,暗知识全丢;T 太高,分布糊成 uniform,暗知识被稀释。所以蒸馏调 T,调的其实是“暗知识的分辨率”——跟 ε 调的“置信度天花板”完全是两回事。

最阴险的坑:平滑过的老师,教不出好学生

Müller、Kornblith 和 Hinton 2019 年的论文专门研究了这个组合,结论有点反直觉:标签平滑能提升泛化和校准,但它会毁掉蒸馏。

机制也不难懂:标签平滑把所有错误类一视同仁,各自分到 ε/(K−1) 的概率。老师输出里“哪个错误类更接近正确类”这个自由度被抹掉了,学生自然学不到类间相似结构。论文里学生掉点接近一个百分点。

所以只要你有蒸馏的计划,老师模型就别用标签平滑,或者把 ε 压到 0.05 以下。否则你就是辛辛苦苦培养了一个口齿不清的老师。

所以到底怎么调?一份能直接上手的清单

  1. 只是普通分类训练:ε=0.1 起步。判断标准别只看 acc,还要看预测概率的校准误差(ECE)——校准变好而 acc 略降,是正常现象。
  2. 模型过度自信、预测概率普遍虚高:先用 post-hoc 的 temperature scaling(Guo et al., 2017)做校准,别一上来就动 ε。后处理校准不牺牲表达能力。
  3. 标签本身有噪声:ε 可以试 0.2–0.3,但别超过 0.5。超过 0.5 模型就开始装傻了。
  4. 要做蒸馏:老师别平滑,或 ε≤0.05;蒸馏温度从 T=3 起步,在 2–8 之间扫。原论文里 T=20 也能用,前提是老师足够强、小概率仍然可靠;实践里 T 太低等于 hard label,T 太高等于 uniform,中间那段才是暗知识最清楚的地方。
  5. 如果你调的是生成采样的 temperature:那是推理阶段的旋钮,跟训练 loss 没关系。文本生成常见 0.7–1.0,太低会复读,太高会胡诌。它跟标签平滑唯一的相关性是名字里的同一个词。
# 训练:标签平滑的 ε(PyTorch 1.10+)
loss_fn = nn.CrossEntropyLoss(label_smoothing=0.1)

# 蒸馏:用温度 T 把老师的 logits 软化成目标分布
soft_targets = F.softmax(teacher_logits / T, dim=-1)

# 推理:生成采样时给 logits 除以温度,控制随机性
logits = logits / sampling_temperature

为什么我的框架里只有 label_smoothing,没有 temperature?

因为大多数训练框架把 ε 实现成正则项,而 temperature 属于蒸馏和采样场景,不在标准分类训练的接口里。当你的代码里出现“用老师或模型自己的 logits 生成目标”这个动作时,你才会碰 T。

蒸馏的 T 和生成采样的 T 能互相参考吗?

不能。蒸馏的 T 决定学习信号里暗知识的清晰度;采样的 T 决定输出分布的随机性。一个影响模型学到什么,一个影响模型说什么。同一个项目里同时出现时,它们是两个独立旋钮。

我的结论

Müller 那篇论文的核心发现,我一直当座右铭用:标签平滑通过压缩表示空间来改善泛化和校准——同类样本的特征被拉得更紧,代价是模型对类间细粒度差异变钝。想清楚这句话,你就知道什么时候该调 ε、什么时候别动它。

把三个旋钮记成三个问题:ε 回答“模型敢多自信”,蒸馏温度回答“暗知识能不能被看见”,采样温度回答“输出有多随机”。它们共享同一个名字,却是三种完全不同的机制——这大概是这个领域最坑新人的地方。

进阶阅读(按需展开)

原创文章,作者:guanweilu,如若转载,请注明出处:https://guanweilu.cn/article/694.html

(0)
上一篇 10小时前
下一篇 10小时前

相关推荐