3. Logits蒸馏(上)

各位同学,今天我们正式进入知识蒸馏的核心地带——Logits蒸馏。这一章,我会带着大家把Hinton老爷子那篇经典论文掰开揉碎了讲。说实话,我当年第一次读这篇论文的时候,也被那些公式和温度参数搞得有点懵。但后来在项目中反复调参、踩坑,才真正理解了里面的门道。

3.1 Hinton原始论文的核心思想

2015年,Hinton团队发表了《Distilling the Knowledge in a Neural Network》。这篇论文的核心观点其实很简单:大模型(教师网络)学到的知识,不仅体现在最终的分类结果上,更体现在它对于各类别的“软性”概率分布上。

举个例子,你训练一个图像分类模型,识别猫、狗、汽车。对于一张猫的图片,硬标签是[1, 0, 0]。但教师网络输出的软标签可能是[0.85, 0.12, 0.03]。这个0.12和0.03包含了重要信息——猫和狗有点像,但和汽车完全不像。这种“类间相似度”就是教师网络要传递的“暗知识”。

核心洞察:知识蒸馏的本质不是让学生模仿教师的输出,而是让学生学会教师对世界的“模糊认知”。这种模糊性恰恰是泛化能力的来源。

3.2 温度参数T的作用与物理意义

温度参数T,是Logits蒸馏中最关键、也最容易让人困惑的超参数。我们先看公式:

Softmax(q_i / T) = exp(q_i / T) / Σ_j exp(q_j / T)

其中q_i是logits(模型最后一层的输出,未经过softmax)。当T=1时,就是标准的softmax。当T增大时,概率分布会变得更“平滑”;当T趋近于0时,分布会变得更“尖锐”。

物理意义是什么?我个人理解,T控制着教师网络“知识传递的粒度”。

  • T较小(如1): 概率分布尖锐,只保留最大类别的信息,其他类别的细微差异被压制。这就像老师只告诉学生“正确答案是A”,不解释为什么B和C不对。
  • T较大(如5-20): 概率分布平滑,所有类别的相对关系都被保留。这就像老师详细解释了“A是对的,B有点接近但错了,C完全不对”。

我的经验:在项目中,我通常从T=4开始尝试。如果学生网络太小(比如MobileNet),T可以设大一些(8-12),让软标签携带更多信息。如果学生网络本身就不小(比如ResNet-18),T=3-5就够用了。

我曾经在一个OCR识别项目中,把T设成了20,结果学生网络完全学偏了——它学会了“模糊”,但学不会“准确”。后来我把T降到5,效果立刻好了很多。嗯,这里要注意:T不是越大越好。

3.3 软标签与硬标签的加权融合

知识蒸馏的损失函数由两部分组成:

  1. 硬标签损失: 学生网络输出与真实标签的交叉熵(标准监督学习)
  2. 软标签损失: 学生网络输出(用高温T软化后)与教师网络输出(也用相同T软化后)的KL散度

这两部分通过一个权重系数α来平衡:

L_total = α * L_hard + (1 - α) * L_soft * T²

注意那个T²!这是Hinton论文里的一个细节。为什么要乘T²?因为当T增大时,软标签损失的梯度会按比例缩小,乘T²是为了让梯度尺度与T无关。我刚开始做蒸馏时忽略了这一点,结果调T完全没效果——后来才发现是梯度尺度出了问题。

参数 作用 常见取值范围 我的建议
α 控制硬标签损失的权重 0.1 - 0.9 先从0.7开始,观察学生收敛情况再调整
T 控制软标签的平滑程度 1 - 20 小模型用大T,大模型用小T
T² 梯度尺度补偿 必须乘 千万别漏掉,否则调T无效

3.4 KD Loss的数学公式推导

我们一步步推导KD Loss。假设:

  • 教师网络logits:v = [v₁, v₂, ..., vₙ]
  • 学生网络logits:z = [z₁, z₂, ..., zₙ]
  • 真实标签:y(one-hot向量)
  • 温度参数:T

第一步:软化概率分布

p_i^T = exp(v_i / T) / Σ_j exp(v_j / T)   # 教师软标签
q_i^T = exp(z_i / T) / Σ_j exp(z_j / T)   # 学生软标签

第二步:计算软标签损失(KL散度)

L_soft = KL(p^T || q^T) = Σ_i p_i^T * log(p_i^T / q_i^T)

第三步:计算硬标签损失(交叉熵)

L_hard = CE(y, softmax(z)) = -Σ_i y_i * log(softmax(z_i))

第四步:组合总损失

L_total = α * L_hard + (1 - α) * T² * L_soft

避坑指南:我曾经在实现时把L_soft和L_hard的梯度尺度搞反了——L_soft的梯度比L_hard大了两个数量级,导致学生网络完全忽略真实标签,只去模仿教师。后来我加了一个梯度裁剪,并仔细检查了T²的乘除位置,才解决问题。

3.5 知识蒸馏核心流程

下面这张图展示了Logits蒸馏的完整流程,我建议你仔细看看:

Logits蒸馏核心流程 教师网络(大模型) 学生网络(小模型) 教师Logits (v) 学生Logits (z) 温度 T Softmax(q/T) 教师软标签 (p^T) 学生软标签 (q^T) KL散度:L_soft = KL(p^T || q^T) 交叉熵:L_hard = CE(y, softmax(z)) L_total = α·L_hard + (1-α)·T²·L_soft 反向传播更新学生网络参数 真实标签 y

3.6 实践中的关键参数调优

最后,我分享几个在实际项目中总结的经验:

  • 教师网络要足够强:如果教师网络本身准确率就不高,蒸馏出来的学生也不会好。我见过有人用一个80%准确率的教师去教学生,结果学生自己训练反而更好。
  • 温度T和权重α要联合调优:这两个参数是耦合的。我习惯的做法是:固定T=4,先调α;找到合适的α后,再微调T。
  • 软标签损失的计算精度:KL散度计算时,注意数值稳定性。p^T和q^T可能非常小(接近0),log之后会变成负无穷。我通常会在log里面加一个很小的epsilon(如1e-8)。

一个实用技巧:在训练初期,可以先用较大的α(0.7-0.9)让学生网络快速学习正确的分类边界;训练后期,逐渐减小α(0.3-0.5),让学生更多地模仿教师的软标签,学习类间关系。这种“退火策略”我在多个项目中使用过,效果比固定α要好。