知识蒸馏的核心是让学生模型学习教师模型经温度缩放后的logits分布,而非简单复制模型或特征;需自定义混合损失函数,同步计算带温度补偿的kl散度与硬标签交叉熵,并在自定义训练循环中同批数据联合推理。

知识蒸馏的核心不是模型复制,而是让小模型学“ logits 分布”
知识蒸馏在 TensorFlow 2.x 中不依赖特殊 API,关键在于修改损失函数:用教师模型的软标签(经温度缩放的 softmax 输出)指导学生模型。硬标签(真实类别)只起辅助作用。直接复用 model.fit() 会失败——因为默认只算交叉熵,没接入教师输出。
常见错误是把教师模型当固定特征提取器,只蒸馏中间层;这其实是特征迁移,不是标准知识蒸馏。真正的蒸馏必须对齐 logits 层输出,并引入温度 T 控制分布平滑度。
- 教师模型需预先训练好,且推理时保持
training=False - 学生模型输入与教师完全一致(同尺寸、同归一化)
- 温度
T通常设为 3–20;T=1等价于普通交叉熵,失去蒸馏意义 - 软损失权重常设为 0.7~0.9,硬损失补足剩余部分
自定义蒸馏损失函数必须同时处理软/硬目标
TensorFlow 2.x 推荐用函数式写法实现混合损失,避免 Keras 内置损失无法接入教师 logits 的问题。不能只写 tf.keras.losses.categorical_crossentropy,要手动计算带温度的 KL 散度。
注意:KL 散度要求输入是概率分布(和为 1),所以必须先对教师和学生 logits 做 softmax,且学生侧要除以温度再 softmax,教师侧也需同样温度缩放——否则分布不对齐,梯度爆炸很常见。
def distillation_loss(y_true, y_pred, y_teacher, T=4, alpha=0.8):
# 学生软目标:logits / T → softmax
soft_pred = tf.nn.softmax(y_pred / T, axis=-1)
# 教师软目标:同温度缩放
soft_teacher = tf.nn.softmax(y_teacher / T, axis=-1)
# KL 散度(batch-wise,非 sample-wise)
kl_loss = tf.keras.losses.KLDivergence()(
soft_teacher, soft_pred
) * (T ** 2) # 温度补偿项,不可省
# 硬标签交叉熵
ce_loss = tf.keras.losses.sparse_categorical_crossentropy(
y_true, y_pred, from_logits=True
)
return alpha * kl_loss + (1 - alpha) * ce_loss
这里 T ** 2 是标准补偿因子,省略会导致 KL 损失过小,蒸馏失效;from_logits=True 保证硬损失仍作用于原始 logits,而非 softmax 后结果。
训练循环中必须同步获取教师 logits,不能用 predict()
在 model.fit() 中无法自然注入教师输出,必须改用自定义训练循环(tf.GradientTape)。用 model.predict() 预先缓存教师输出看似省事,但会切断梯度、丢失 batch 内随机增强一致性(如 RandAugment),导致学生学到噪声模式。
正确做法是在每个 step 内,同一 batch 数据同时过教师和学生模型,确保图像增强、dropout 状态完全同步。教师模型必须设为 training=False,否则其 dropout 或 BN 层会干扰软标签稳定性。
- 教师模型调用前加
teacher_model(x_batch, training=False) - 学生模型保持
training=True(正常训练) - 务必禁用教师模型的可训练变量更新:
teacher_model.trainable = False - 若用
tf.data.Dataset,别在 map 中调用教师模型——它不支持图模式
学生模型收敛慢、验证准确率卡住?检查温度和 alpha 是否动态调整
固定 T 和 alpha 往往不是最优。初期学生 logits 差距大,高温度(如 T=8)让分布更平滑,利于学习全局结构;后期应逐步降温(如线性衰减到 T=2),聚焦细节区分。同样,alpha 可从 0.9 逐渐降到 0.5,让学生后期更关注真实标签。
另一个易忽略点:教师模型若用 BN 层,其统计量(moving_mean/moving_variance)必须在蒸馏前用足够多数据校准(teacher_model.trainable = False 后跑一个 epoch 的 inference)。否则软标签方差过大,学生震荡严重。
最后,学生模型结构不宜过浅——比如用 3 层 CNN 蒸馏 ResNet-50,即使 loss 下降,top-1 准确率也很难突破教师的 85%;建议学生至少保留教师 50% 参数量或等效深度。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











