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 软标签与硬标签的加权融合
知识蒸馏的损失函数由两部分组成:
- 硬标签损失: 学生网络输出与真实标签的交叉熵(标准监督学习)
- 软标签损失: 学生网络输出(用高温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蒸馏的完整流程,我建议你仔细看看:
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),让学生更多地模仿教师的软标签,学习类间关系。这种“退火策略”我在多个项目中使用过,效果比固定α要好。