想象一所学校里有两类老师。第一类是“铁面判官”:批改选择题只认标准答案,对是 100 分,错是 0 分,中间地带一概没有。学生的应对策略自然是死记硬背,一旦押中了某个答案,就自信到认为自己天下无敌——这个“过度自信”的毛病,正是很多深度学习模型训练时的通病。 第二类是“温和的引路人”:哪怕学生答对了,他也不会给满分 100,而是给 90 分,再把剩下的 10 分平均分给其他选项。他的逻辑是:标准答案本身也可能有噪声,与其让学生把话说死,不如让它的答案分布“软”一点。这位温和老师的做法,就是本文的主角——Label Smoothing(标签平滑)。 标签平滑看似只是“把标签改一改”,背后却连着 KL 散度的数学推导、模型校准的可靠性评估、以及工程实践中的大量细节。读完本文,你会理解:为什么给 one-hot 标签“掺点水”能让模型更谦虚稳健,什么时候该用、什么时候不该用,以及如何亲手实现它。

岗位关联

对 AI 从业者而言,Label Smoothing 是几乎每个分类模型都能用到的“性价比最高”的正则化技巧之一。掌握它的原理,能帮你提升模型的泛化能力与预测可靠性,在训练调参和模型上线时少踩许多坑。

目录
  1. 可视化演示
  2. 标准交叉熵:铁面判官式打分
  3. 标签平滑:给标准答案掺点水
  4. KL散度推导:数学钥匙揭开本质
  5. 模型校准:让预测的自信货真价实
  6. 超参选择:epsilon 的玄机
  7. 适用场景:什么任务吃这套
  8. 损失搭配:双剑合璧的艺术
  9. 工程实现:代码里的细节
  10. AI 应用场景
  11. Python 演示
  12. 常见误区
  13. 面试题

可视化演示

对比标准交叉熵与Label Smoothing损失曲线,展示平滑标签对模型校准度的提升机制及适用场景。

本节配有交互动效(进入视口后自动加载,约 3KB)。

交叉熵 vs Label Smoothing 损失对比 标准交叉熵:目标分布为one-hot,正确类概率目标为1.0,过度自信 Label Smoothing:将目标分布平滑化,正确类目标从1.0降至1-α+α/K 核心效果:限制模型对正确类输出过大logit,防止过拟合 LS_target = (1-α)·one_hot + α/K α为平滑系数,K为类别数。

标准交叉熵:铁面判官式打分

还记得那位“铁面判官”老师吗?标准交叉熵损失正是这样一位老师。它拿着 one-hot 编码的“标准答案”来批改模型的预测:正确答案是 1,其余全是 0,没有任何中间地带。模型预测得越接近这个极端分布,得分越高;只要偏离一点,损失就毫不留情地飙升。

从数学上看,这位判官的打分规则叫交叉熵。它衡量的是“模型给出的概率分布 p”与“真实标签分布 y”之间的差异。由于 y 只在真实类别处为 1,其余位置为 0,损失函数就退化成“只关心真实类别那一处的预测概率”:预测得越准,交叉熵越小。

这位判官的教学副作用很快显现:模型被训练得“非黑即白”,只要真实类别的预测概率达到 0.99,它就觉得自己稳了。可在现实世界,这种过度自信往往翻车——模型以为自己 99% 是对的,实际上只有 90% 的把握。铁面判官的极端标准答案,正是过度自信的温床。

L=−∑i=1Kyilog⁡piL = -\sum_{i=1}^{K} y_i \log p_i
这个公式通俗理解:真实标签 y 中只有一个是 1,其余是 0,所以求和时只有真实类别的 log p 被保留,负号让“预测越准损失越小”。
  1. 求和符号把类别从 1 到 K 全部遍历一遍,依次计算每个类别的贡献:
    ∑i=1K\sum_{i=1}^{K}
  2. 真实标签 y_ione-hot 向量中第 i 个分量的值,正确类是 1,其余是 0:
    yi={1i=c0i≠cy_i = \begin{cases} 1 & i = c \\ 0 & i \neq c \end{cases}
  3. 预测概率 p_i模型对第 i 类的预测概率,所有 p_i 之和为 1:
    pi>0,∑i=1Kpi=1p_i > 0, \quad \sum_{i=1}^{K} p_i = 1
  4. 对数运算的作用log 把“概率连乘”变成“损失相加”,且当 p 接近 1 时 log p 接近 0,损失趋近于 0:
    log⁡pi\log p_i
  5. 负号的意义因为 log 的结果是负数,加负号让损失变成正数,便于优化:
    L=−∑i=1Kyilog⁡piL = -\sum_{i=1}^{K} y_i \log p_i

标签平滑:给标准答案掺点水

温和老师决定改革:标准答案又不是真理,为什么要给学生灌输“非 0 即 1”的教条?她的做法是给 one-hot 标签“掺点水”——把真实类别的 1 换成略小于 1 的数,把省下来的概率均匀分给其他所有类别。这样标签从“极端独裁”变成了“温和民主”。

这个“掺水比例”就是 ε(epsilon),通常取 0.1。如果总共有 K 个类别,那么正确类别的新标签是 1-ε+ε/K,其他每个类别的标签是 ε/K。你可能会好奇:为什么正确类不是简单地变成 1-ε?因为 ε 那一部分还要在 K 个类别上均分,正确类自己也分到了一小份 ε/K。

有了软标签 q,温和老师对应的损失函数也变了:不再是只盯着真实类别的对数概率,而是让模型预测 p 去逼近软标签 q。于是损失变成了“标准交叉熵”与“对均匀分布的平均交叉熵”的加权组合。模型不再被逼迫着把预测概率推向 1,学到的特征表征也会更内聚、更稳健。

qi={1−ε+εKi=cεKi≠cq_i = \begin{cases} 1-\varepsilon+\dfrac{\varepsilon}{K} & i = c \\[6pt] \dfrac{\varepsilon}{K} & i \neq c \end{cases}
通俗理解:原本 100% 的信任值被扣掉 ε(比如 10%),这 10% 在所有 K 个类别上平分,正确类拿回其中的一份,所以最终是 1-ε+ε/K。
  1. 平滑系数 ε控制“掺水”多少,ε 越大标签越软,取 0 时退化为标准交叉熵:
    0≤ε≤10 \le \varepsilon \le 1
  2. 类别总数 K分类任务的类别数量,分母 K 保证所有标签之和仍为 1:
    K=类别数K = \text{类别数}
  3. 正确类别的新标签正确类的目标概率从 1 降为 1-ε+ε/K,多出来的 ε/K 是“示好”:
    qc=1−ε+εKq_c = 1 - \varepsilon + \frac{\varepsilon}{K}
  4. 错误类别的新标签所有错误类都分到 ε/K,不再是 0,给模型传递“这些类也可能沾边”的信号:
    qi=εK(i≠c)q_i = \frac{\varepsilon}{K} \quad (i \neq c)

KL散度推导:数学钥匙揭开本质

温和老师的“掺水”策略听着很 intuitive,但它凭什么在数学上成立?这就要请出信息论里的“分歧度尺子”——KL 散度。KL 散度衡量两个概率分布之间的距离:如果目标分布是 q,模型分布是 p,KL 散度越小,说明 p 越接近 q。

Label Smoothing 的本质,就是让模型分布 p 尽量接近“软目标 q”。把这个目标写成 KL 散度,再展开化简,你会发现一个惊喜:KL 散度的一部分是常数(与模型无关),剩下的部分恰好等价于“标准交叉熵 + 均匀分布交叉熵”的加权组合。

这条推导链让 Label Smoothing 不再是“拍脑袋的 trick”:它本质上是给模型设了一个更温和的目标分布 q,然后老老实实地用 KL 散度去度量差距。常数项中 q 的熵(即“目标标签自身的信息量”)被证明与模型无关,这解释了为什么我们只需要修改损失函数,而不需要修改网络结构。

KL(q∥p)=∑i=1Kqilog⁡qipi=∑i=1Kqilog⁡qi⏟常数项−∑i=1Kqilog⁡piKL(q \parallel p) = \sum_{i=1}^{K} q_i \log \frac{q_i}{p_i}= \underbrace{\sum_{i=1}^{K} q_i \log q_i}_{\text{常数项}} - \sum_{i=1}^{K} q_i \log p_i
通俗理解:KL 散度像“两位老师批阅同一份答卷的分歧”;其中“目标分布自带的信息量”与模型无关,是常数,真正需要优化的只剩后半部分。
  1. KL 散度定义对每个类别,求 q 与 p 之比的 log,再按 q 加权求和:
    KL(q∥p)=∑i=1Kqilog⁡qipiKL(q \parallel p) = \sum_{i=1}^{K} q_i \log \frac{q_i}{p_i}
  2. 拆开对数log(q/p) 等于 log q 减 log p,把两项目分开:
    qilog⁡qipi=qilog⁡qi−qilog⁡piq_i \log \frac{q_i}{p_i} = q_i \log q_i - q_i \log p_i
  3. 常数项识别第一项只含 q 不含 p,模型无论怎么学都不会改变它,因此优化时可忽略:
    ∑i=1Kqilog⁡qi=常数\sum_{i=1}^{K} q_i \log q_i = \text{常数}
  4. 保留有效项剩下的是负的交叉熵项,等价于最小化交叉熵:
    −∑i=1Kqilog⁡pi-\sum_{i=1}^{K} q_i \log p_i
  5. 代入软标签 q把 q_i=(1-ε)y_i+ε/K 代入,就能得到最终的平滑损失:
    LLS=(1−ε)H(y,p)+εH(u,p),u=1KL_{LS} = (1-\varepsilon)H(y, p) + \varepsilon H(u, p), \quad u = \frac{1}{K}

模型校准:让预测的自信货真价实

温和老师的教育成果,要拿什么指标来衡量?答案是“校准度”。一个模型说它有 90% 的把握时,实际正确率也应该接近 90%——这种“说到做到”的品质叫校准良好。铁面判官教出来的模型常常“口出狂言”:说 99% 把握,实际只有 92%,这就是过度自信带来的校准偏差。

校准度最常用的量化指标叫 ECE(期望校准误差)。它的思路很朴素:把样本按预测置信度分成若干个桶,比如置信度 0.9~1.0 的放一桶,0.8~0.9 的放一桶,然后比较每个桶的“平均预测置信度”和“实际准确率”,差距越小越好。

Label Smoothing 之所以能显著改善 ECE,是因为它从一开始就不允许模型把正确类的输出概率推到 1 附近。模型的峰值置信度被“人为压低”,整体预测分布变得更平滑,因此在很多研究(如 MIT 对 ResNet 系模型的研究)中,LS 把 ECE 从 0.11 附近降到 0.03 以下。温和老师教的“谦虚”最终转化为了统计意义上的可靠性。

ECE=∑m=1M∣Bm∣N∣acc(Bm)−conf(Bm)∣ECE = \sum_{m=1}^{M} \frac{|B_m|}{N} \left| \text{acc}(B_m) - \text{conf}(B_m) \right|
通俗理解:把学生按“自称的信心”分组,检查每组“嘴上说的”和“实际考的”差多少,差值加权平均就是 ECE。
  1. 分桶操作把预测按置信度分成 M 个区间桶,B_m 是第 m 个桶:
    Bm={置信度落在第 m 区间的样本}B_m = \{ \text{置信度落在第 } m \text{ 区间的样本} \}
  2. 桶内实际准确率该桶中预测正确的样本占比:
    acc(Bm)=1∣Bm∣∑j∈Bm1(y^j=yj)\text{acc}(B_m) = \frac{1}{|B_m|} \sum_{j \in B_m} \mathbb{1}(\hat{y}_j = y_j)
  3. 桶内平均置信度该桶中模型给出的平均预测概率最大值:
    conf(Bm)=1∣Bm∣∑j∈Bmmax⁡kpj(k)\text{conf}(B_m) = \frac{1}{|B_m|} \sum_{j \in B_m} \max_k p_j(k)
  4. 加权求和按桶大小占比加权,让大桶对误差贡献更大:
    ∑m=1M∣Bm∣N⋅∣acc(Bm)−conf(Bm)∣\sum_{m=1}^{M} \frac{|B_m|}{N} \cdot |\text{acc}(B_m) - \text{conf}(B_m)|

超参选择:epsilon 的玄机

温和老师的“掺水量”也不是越大越好。ε 太小,比如 0.01,标签几乎还是 one-hot,“掺水”效果约等于没有;ε 太大,比如 0.5,正确类的目标概率直接掉到 0.5 上下,模型会严重“佛系”,训练损失降不下去,甚至欠拟合。工程界的经验值是 ε=0.1,这是无数实验试出来的“黄金比例”。

从有效置信度的角度能更直观地理解 ε 的上限。加了平滑之后,即使模型完全学到位,它对正确类最好的预测也只是 1-ε+ε/K。这是模型“能做到的最大自信”,也就是有效置信度的天花板。

在实践中,调 ε 可以遵循一个简单直觉:先固定 0.1 跑通基线;如果模型严重过拟合且预测概率集中到 0.99 以上,可以适当加大到 0.15~0.2;如果训练损失已经降不下去,说明水掺多了,回调到 0.05。另外,学习率和训练轮次也要跟着微调,因为软标签会让损失曲线整体抬升,需要更长的训练时间来收敛。

confmax⁡=1−ε+εK\text{conf}_{\max} = 1 - \varepsilon + \frac{\varepsilon}{K}
通俗理解:学生再优秀,温柔老师也只给 90 出头的分;分越低,学生越不敢骄傲,但也可能因此失去冲劲。
  1. 保留的信任度 1-ε从 100% 的满分中扣除 ε 的“怀疑额度”:
    1−ε1 - \varepsilon
  2. 拿回来的份额 ε/K被扣掉的 ε 要分给 K 个类别,正确类也分回一份:
    εK\frac{\varepsilon}{K}
  3. 有效置信度上限两者相加,就是正确类标签的最终目标值:
    1−ε+εK1 - \varepsilon + \frac{\varepsilon}{K}
  4. 与 K 的关系类别数 K 越大,正确类拿回的份额越小,标签越极端,因此超大类别任务往往需要调大 ε:
    lim⁡K→∞(1−ε+εK)=1−ε\lim_{K \to \infty} \left(1-\varepsilon+\frac{\varepsilon}{K}\right) = 1-\varepsilon

适用场景:什么任务吃这套

温和老师的教育方法并非放之四海皆准。在大多数标准分类任务中,比如 ImageNet 图像分类、CIFAR 分类、文本分类,Label Smoothing 都能带来稳定的准确率提升和校准改善,尤其适合类别语义相近的任务——因为标签之间本来就有相似性,软标签恰好让模型学会“这题跟那题有点像”。

但在知识蒸馏场景中,LS 反而可能帮倒忙。知识蒸馏让学生模型去模仿教师模型的软输出(soft label),而教师输出已经蕴含了丰富的类间相似度信息。此时再叠加 Label Smoothing,等于把本来就很丰富的信息又抹平了一层,学生学到的知识会被“稀释”。就好比温和老师对着一个已经表达得很含蓄的学生,又补了一句“别太较真”——信息更加模糊。

在标签噪声严重的数据集上也要小心。Label Smoothing 假设噪声是“均匀撒在各类别上”的,但真实世界的标注噪声往往是偏斜的——比如“猫”更容易被标成“狗”。此时均匀分配的 ε/K 会把错误信号放大,反而不如直接用噪声鲁棒损失。判断要不要用 LS,核心问题就一个:你的标准答案,真的“标准”吗?

pi=exp⁡(zi/T)∑j=1Kexp⁡(zj/T)p_i = \frac{\exp(z_i / T)}{\sum_{j=1}^{K} \exp(z_j / T)}
通俗理解:蒸馏的温度 T 和 LS 的 ε 都是在“软化分布”,但一个是从预测端软化,一个是从标签端软化,两者叠加可能过度稀释信息。
  1. logits 输入 z_i模型最后一层输出的原始分数,未经过 Softmax:
    ziz_i
  2. 温度参数 TT 越大,Softmax 输出的分布越平坦、越“软”:
    T>1T > 1
  3. 软化后的概率除以 T 后再做 Softmax,得到更平滑的预测分布:
    pi=exp⁡(zi/T)∑jexp⁡(zj/T)p_i = \frac{\exp(z_i / T)}{\sum_{j} \exp(z_j / T)}
  4. 与 LS 的对比蒸馏软化的是“模型输出”,LS 软化的是“训练目标”,作用的层面不同:
    p 软化 ↔q 软化p \text{ 软化 } \leftrightarrow q \text{ 软化}

损失搭配:双剑合璧的艺术

Label Smoothing 不是只能单打独斗。在类别不平衡的任务中,它常和 Focal Loss 组成“双剑合璧”的组合。Focal Loss 针对的是“难易样本不平衡”问题:大量简单负样本主导了梯度,让模型学不到难样本。它的做法是给每个样本的损失乘上一个调制因子,让“容易被分对的样本”贡献小一点,“分不对的难样本”贡献大一点。

Label Smoothing 和 Focal Loss 关注的是两个不同的痛点:一个管标签太极端,一个管样本太难。因此它们可以分别起作用,形成互补——先用 LS 把标签软化,再用 FL 给难样本加权,两者各司其职。

组合使用时注意顺序和系数:通常在 Focal Loss 的框架内,把其中的标准 CE 项替换成 LS 损失。但也要警惕“过度正则化”——两个技巧都偏向压低模型置信度,叠加后模型可能变得过于保守。建议先单独调好 ε,再引入 γ,每次只动一个旋钮,观察验证集的变化。

FL(pt)=−(1−pt)γlog⁡ptFL(p_t) = -(1 - p_t)^{\gamma} \log p_t
通俗理解:Focal Loss 是“专攻难题的老师”——容易题少给分,难题多给分;LS 是“语气温柔的老师”——答案别说得太满。两位老师可以同时在场。
  1. 真实类别概率 p_t模型对真实类别给出的预测概率:
    pt=pyp_t = p_{y}
  2. 聚焦参数 γγ 越大,简单样本被压得越狠,模型越聚焦难样本:
    γ≥0\gamma \ge 0
  3. 调制因子当 p_t 接近 1(样本很容易),(1-p_t)^γ 趋近 0,损失被压低:
    (1−pt)γ(1 - p_t)^{\gamma}
  4. 结合 LS 的整体损失先平滑标签,再对每个样本乘上调制因子:
    L=−1N∑n=1N(1−pt,n)γ[(1−ε)log⁡pcn+εK∑i=1Klog⁡pi,n]L = -\frac{1}{N} \sum_{n=1}^{N} (1 - p_{t,n})^{\gamma} \left[ (1-\varepsilon) \log p_{c_n} + \frac{\varepsilon}{K} \sum_{i=1}^{K} \log p_{i,n} \right]

工程实现:代码里的细节

温和老师的方法落地到代码,比想象中更简单——几行 PyTorch 就能搞定。核心是把“平滑损失”拆成两项:第一项是标准负对数似然(NLL Loss),只关心正确类;第二项是对所有类别的对数概率求平均,代表“对均匀分布的拟合”。两者按 1-ε 和 ε 加权求和。

数值稳定性是工程实现的关键。千万不要先算 softmax 再取 log,这样在极端概率下会出现 log(0) 的数值灾难。正确做法是直接使用 log_softmax,它内部做了数值平移保护,既稳定又高效。

实现完成后,建议在训练日志里同时打印“平均置信度”和“准确率”两个指标。如果置信度 ≈ 准确率,说明模型校准良好;如果差距逐渐拉大,就该检查 ε 是否太小。工程落地这件事,温和老师告诉我们一个朴素道理:不把话说死,才经得起实际检验。

LLS=−1N∑n=1N[(1−ε)log⁡pcn+εK∑i=1Klog⁡pi,n]L_{LS} = -\frac{1}{N} \sum_{n=1}^{N} \left[ (1-\varepsilon) \log p_{c_n} + \frac{\varepsilon}{K} \sum_{i=1}^{K} \log p_{i,n} \right]
通俗理解:每个样本的损失 = 正确类的对数概率(打 1-ε 折扣)+ 所有类对数概率的平均值(打 ε 折扣),再对所有样本取平均。
  1. 正确类 log 项∇ 只对正确类别 c 的对数概率负责,是损失的主体:
    log⁡pcn\log p_{c_n}
  2. 均匀项对所有 K 个类别的对数概率求平均,让模型“雨露均沾”:
    1K∑i=1Klog⁡pi,n\frac{1}{K} \sum_{i=1}^{K} \log p_{i,n}
  3. 加权系数1-ε 给主项,ε 给均匀项,两者之和为 1:
    (1−ε)+ε=1(1-\varepsilon) + \varepsilon = 1
  4. 批量取平均对 N 个样本的损失取均值,便于与学习率匹配:
    1N∑n=1N\frac{1}{N} \sum_{n=1}^{N}

AI 应用场景

图像分类中的模型校准

阶段:模型训练与调优

解决的问题:在 ImageNet 等大规模图像分类任务中,标准交叉熵训练的模型准确率虽高,但输出概率严重虚高。例如模型对一张图给出 99% 的置信度,实际正确率可能只有 87%,这在医疗影像、自动驾驶等安全性敏感的领域是致命的。使用 Label Smoothing 后,峰值置信度被压低,ECE 显著改善,模型不再“盲目自信”。

具体案例:某自动驾驶团队训练道路标志分类模型时,误检率居高不下。引入 ε=0.1 的 Label Smoothing 后,模型的校准误差从 0.12 降至 0.04,在“不确定就刹车”的决策逻辑下,误判率下降了 38%,因为模型能在真正不确定时给出更低置信度,触发安全兜底。

推荐系统的 CTR 预估

阶段:特征工程与模型优化

解决的问题:CTR 预估模型(如 DeepFM、DCN)输出的是点击概率,广告主按此出价和排期。如果概率校准差,模型可能对所有广告都给出高概率,导致预算分配失衡。LS 把二分类的标签从 0/1 软化,让预估点击率更贴近真实概率分布,从而让广告排序与计费更公平。

具体案例:某电商推荐团队发现,线上 A/B 测试中 CTR 预估概率普遍虚高 12%,广告主投诉“实际效果远不如预期”。他们在损失函数中引入 Label Smoothing 并对 ε 做了小范围网格搜索,最终线上 GMV 提升 5.3%,校准度指标 AUC 不变而 ECE 大幅下降。

人脸识别中的特征学习

阶段:损失函数设计与训练

解决的问题:在人脸识别(如 CosFace、ArcFace)中,类别数动辄上万,one-hot 目标让模型对每个身份都追求“满分”,导致特征空间极度分化、泛化差。LS 让每个身份的目标标签留出“余地”,配合 margin-based 损失,可以提升特征的内聚性和跨域泛化能力。

具体案例:某安防厂商训练千万级人脸识别模型时,在 ArcFace 损失中叠加 ε=0.3 的 Label Smoothing(因为类别数 K 很大,ε 需要相应调大),在 LFW 数据集上的准确率提升了 0.8%,同时在更难的 MegaFace 上提升了 1.4%,误识率显著下降。

Python 演示

python50 行
import torchimport torch.nn as nnimport torch.nn.functional as F  class LabelSmoothingLoss(nn.Module):    def __init__(self, K, epsilon=0.1, reduction='mean'):        super(LabelSmoothingLoss, self).__init__()        self.K = K        self.eps = epsilon        self.reduction = reduction     def forward(self, logits, targets):        log_probs = F.log_softmax(logits, dim=-1)        nll_loss = F.nll_loss(log_probs, targets, reduction='none')        uniform_loss = -log_probs.mean(dim=-1)        loss = (1 - self.eps) * nll_loss + self.eps * uniform_loss        if self.reduction == 'mean':            return loss.mean()        return loss.sum()  def main():    torch.manual_seed(0)    K = 5    model = nn.Linear(8, K)    data = torch.randn(64, 8)    targets = torch.randint(0, K, (64,))     smooth_loss = LabelSmoothingLoss(K, epsilon=0.1)    optimizer = torch.optim.SGD(model.parameters(), lr=0.2)     for epoch in range(60):        optimizer.zero_grad()        logits = model(data)        loss = smooth_loss(logits, targets)        loss.backward()        optimizer.step()        with torch.no_grad():            acc = (logits.argmax(-1) == targets).float().mean().item()            conf = F.softmax(logits, dim=-1).max(-1).values.mean().item()        if epoch % 20 == 0:            print(f'epoch {epoch:02d} loss={loss.item():.4f} '                  f'acc={acc:.3f} conf={conf:.3f}')     print('Done. 若 conf 略低于 acc,说明模型不再过度自信。')  if __name__ == '__main__':    main()
目的:实现一个完整的 Label Smoothing 损失类,并在一个 5 分类小模型上做 60 轮训练,观察“准确率 acc”与“平均置信度 conf”的差距。
  1. log_probs = F.log_softmax(logits, dim=-1)用 log_softmax 一步完成软化和取对数,数值更稳定。
  2. nll_loss = F.nll_loss(log_probs, targets, reduction='none')计算标准交叉熵部分(只关注正确类),不立即求均值。
  3. uniform_loss = -log_probs.mean(dim=-1)计算均匀分布项:对所有类别的 log 概率取平均再取负。
  4. loss = (1 - self.eps) * nll_loss + self.eps * uniform_loss按 ε 加权组合两项,这就是平滑损失的完整形式。
  5. if self.reduction == 'mean': return loss.mean()默认对所有样本求均值,匹配大多数训练框架的期望。
  6. optimizer = torch.optim.SGD(model.parameters(), lr=0.2)用 SGD 做基准优化,方便观察损失是否正常下降。
  7. conf = F.softmax(logits, dim=-1).max(-1).values.mean().item()计算平均峰值置信度,用来和准确率对比评估校准度。

常见误区

误区加入 Label Smoothing 后,训练集上的准确率确实下降了,于是我觉得这个技巧是负优化,果断删掉。

正解训练准确率下降恰恰是 LS 起作用的表现——它主动“不让学生考满分”,以换取更好的泛化。真正该看的是验证集准确率和模型校准度(ECE)。大量实验表明,LS 在 ImageNet 上能稳定提升测试准确率 0.5~1%,同时大幅改善校准度。用训练集准评估正则化方法,就像用月考成绩评价一个爱出“超纲题”的老师,方向就错了。

为何常见:人们习惯用“是否过拟合”来快速判断训练效果,训练准确率是最直观的数字,容易忽略正则化方法的真实目标是泛化能力。

误区既然 0.1 有效,那 0.3、0.5 效果应该更好,于是我直接把 ε 调到 0.5。

正解ε 过大会让正确类的目标概率大幅降低,比如 K=10、ε=0.5 时正确类标签只有 0.55,模型会被逼着对每个类别都“雨露均沾”,造成欠拟合,验证集准确率明显下滑。ε 应当根据任务调参:小数据集 0.05~0.1,大规模分类可上探 0.15~0.3,但超过 0.5 基本只会带来负面效果。温和老师也有底线,水掺多了学生就学不到东西了。

为何常见:正则化强度与效果在直觉上常被当作线性关系,但实际往往存在一个“甜蜜点”,超过后收益递减甚至反转。

误区知识蒸馏用 soft label,Label Smoothing 也用软标签,两者都是软化,叠加肯定 1+1>2。

正解蒸馏时教师模型的软输出已经包含了类别间的相似度信息,这是学生模型最宝贵的“知识”。再叠加 LS,相当于把教师传递的丰富信息又均匀稀释了一遍,学生会损失类间差异性信息,蒸馏效果往往不升反降。正确姿势是:蒸馏学生模型时用硬标签 + 教师软标签的加权 KL,而不额外加 LS;LS 更适合直接用硬标签训练的场景。

为何常见:软标签这个概念被过度泛化了,大家以为“软”就是好,忽略了信息的层次与纯度。

误区用了 Label Smoothing 之后,Dropout、Weight Decay 这些正则化都不需要了。

正解LS 只作用于标签分布,它解决的是“过度自信”和“校准度差”的问题;Dropout 和 Weight Decay 作用于网络结构或参数空间,解决的是“参数过拟合”的问题。两者作用层面不同,不能互相替代。实践中 LS 和 Weight Decay 是可以共存的,甚至能产生协同效应。老师管住学生的“态度”,教练管住“训练量”,缺一不可。

为何常见:正则化方法种类繁多,初学者容易把它们都归为“防过拟合”一类,忽视了各自的作用机制。

误区我认为正确类的目标标签应该是 1-ε,剩下的 ε 分给其他 K-1 个类,所以错误类是 ε/(K-1)。

正解正确的分配方式是:错误类每个分到 ε/K,正确类分到 1-ε+ε/K。因为 ε 的总量要在所有 K 个类别上均分,正确类自己也参与分配,所以正确类是 1-ε+ε/K 而不是 1-ε。如果按错误类 ε/(K-1) 分配,所有标签之和就不是 1,破坏概率分布的归一性。这一步差之毫厘,谬以千里。

为何常见:直觉上“正确类先剔除 ε,剩下的分给别人”很自然,但忽略了正确类也是 K 个类别之一。

面试题

Q1. Label Smoothing 中,设类别数 K=10、ε=0.1,正确类别的新标签值是多少?

单选题 · easy

  • A.0.90
  • B.0.91← 正确答案
  • C.0.09
  • D.0.10

答案:B。正确类标签为 1-ε+ε/K = 1-0.1+0.1/10 = 0.91。0.90 是忘记加上正确类自己分到的 ε/K 的常见错误;0.09 和 0.10 分别是错误类单类分到的值和 ε 的值,均不是正确类的目标标签。

Q2. Label Smoothing 中,超参 ε 的常用默认值是多少?

单选题 · easy

  • A.0.01
  • B.0.05
  • C.0.10← 正确答案
  • D.0.50

答案:C。工程实践证明 ε=0.1 是大多数任务上的“甜蜜点”,既能有效抑制过度自信,又不会导致欠拟合。0.01 太小几乎不起作用,0.05 偏保守,0.50 已属于过度平滑,会让正确类目标概率被压得过低。

Q3. 下列哪些是 Label Smoothing 带来的好处?

多选题 · easy

  • A.提升模型校准度← 正确答案
  • B.缓解过度自信← 正确答案
  • C.减少模型参数量
  • D.加快单步训练速度

答案:AB。LS 通过软化标签降低峰值置信度,使模型的置信度与实际准确率更接近,从而提升校准度并缓解过度自信。它不改变网络结构,因此不会减少参数量;也不会减少计算量,单步训练速度不会因此加快。

Q4. 标准交叉熵损失容易让模型过度自信的根本原因是什么?

单选题 · mid

  • A.目标分布是极端的 one-hot← 正确答案
  • B.学习率设定过高
  • C.模型参数量过大
  • D.数据增强过于激进

答案:A。one-hot 目标只有 0 和 1,模型被逼着把正确类的概率推向 1,天然倾向产出极端置信度。学习率和参数量是工程因素,数据增强与过度自信无直接关系。正是针对 one-hot 的极端性,LS 才将 1 降为 1-ε+ε/K。

Q5. 从 KL(q∥p) 推导 Label Smoothing 时,哪一项可以当作常数忽略?

单选题 · mid

  • A.交叉熵项 −Σq·log p
  • B.标签熵项 Σq·log q← 正确答案
  • C.均匀分布熵 ε·log K
  • D.对数损失项 −log p_c

答案:B。KL(q∥p)=Σq·log q − Σq·log p,第一项只包含目标分布 q、不含模型参数 p,因此是常数,优化时可忽略。保留的交叉熵项正是需要最小化的部分;均匀分布熵和 −log p_c 均不是从 KL 展开中独立出现的常数项。

Q6. 在知识蒸馏场景中叠加 Label Smoothing,通常会产生什么效果?

单选题 · mid

  • A.提升蒸馏效果
  • B.稀释教师信息← 正确答案
  • C.完全等价于温度缩放
  • D.只影响训练速度

答案:B。教师模型的软输出已经含有丰富的类间相似度信息,LS 再对标签做均匀化会把这些信息稀释,导致学生学到的知识变模糊。两者虽然都“软化”,但作用层面不同,叠加通常有害而非有益。

Q7. 平滑损失 L=(1−ε)·H(y,p)+ε·H(u,p) 中,u 代表什么分布?

单选题 · mid

  • A.均匀分布← 正确答案
  • B.高斯分布
  • C.伯努利分布
  • D.模型的预测分布

答案:A。u 是每个类别概率均为 1/K 的均匀分布。LS 的本质是把 one-hot 目标 y 与均匀分布 u 按 1−ε 和 ε 做加权混合,得到的软目标 q=(1−ε)y+εu,因此损失自然是 H(y,p) 与 H(u,p) 的加权组合。

Q8. 设 ε=0.2、K=5,模型对正确类能给出的最大“有效置信度”约是多少?

单选题 · hard

  • A.0.80
  • B.0.84← 正确答案
  • C.0.90
  • D.0.96

答案:B。有效置信度上限为 1−ε+ε/K = 1−0.2+0.2/5 = 0.84。0.80 是忽略了 ε/K 的常见错误;0.90 是混淆了类别数成 2 的结果;0.96 则把正确类当成了 K−1 类中多分的一份,均不正确。

Q9. 下列哪些场景不建议直接使用 Label Smoothing?

多选题 · mid

  • A.已用教师软标签的蒸馏← 正确答案
  • B.标签噪声严重且偏斜← 正确答案
  • C.大规模图像分类
  • D.小数据集上的小模型

答案:AB。蒸馏时教师软输出已含丰富信息,加 LS 会稀释知识;标签噪声偏斜时,LS 假设噪声均匀分布,会放大错误信号。大规模图像分类和小数据小模型通常都能从 LS 的正则化效果中获益,属于推荐场景。

Q10. 关于 ECE(期望校准误差),下列说法正确的有哪些?

多选题 · extreme

  • A.ECE 越低说明预测越校准← 正确答案
  • B.ECE 计算需按置信度分桶← 正确答案
  • C.ECE 与准确率完全正相关
  • D.ECE 能精确定位每个错误样本

答案:AB。ECE 通过按置信度分桶、比较桶内准确率与平均置信度来量化校准误差,值越小越好,因此 A、B 正确。ECE 是统计层面的校准度量,不直接等于或正相关于准确率,也不能定位单个错误样本,故 C、D 错误。