一个分类器看到一张图说「这是猫」,它真正在做的是输出一组概率:
softmax([z猫,z狗,z鸟,z鱼])=[0.87, 0.10, 0.02, 0.01]
LLM 生成下一个 token 也一样——给词表里每个 token 都打一个概率,再从里面采样。所有现代 ML 模型的输出本质都是一个分布,不是「答案本身」。
要训练这种模型,就必须能回答:
- 怎么衡量「这个分布有多不确定」? → 熵
- 怎么衡量「模型预测的分布和真实分布有多接近」? → 交叉熵 / KL 散度
这两个量是分类、生成、强化学习几乎所有损失函数的底料。这篇就把它们画清楚。
把一个离散概率分布画成柱状图——每个柱子的高度就是那个事件发生的概率。这些柱子加起来必须等于 1。
骰子是均匀分布(6 个等高柱子)。一个有偏好的预测(比如「这张图大概率是猫」)是尖的(一根柱子很高,其他很矮)。
数学上,期望就是「按概率加权的平均」:
E[X]=i∑pi⋅xi
可以理解为柱状图的重心——如果柱子是质量,期望就是平衡点。方差就是「柱子离重心有多远」的平均平方距离,衡量分布的铺开程度。
但仅仅「铺开程度」还不够。我们需要一个更基本的量,直接衡量「这个分布到底有多不确定」——这就是熵。
一个事件的「意外感」(self-information) 就是:
I(x)=−log2p(x)
概率越小,意外越大。 「明天太阳升起」 p≈1, I=0 bit, 一点不意外;「今天 GPT-7 发布」 p=1/1000, I≈10 bit, 信息量大。底数取 2 让单位就是熟悉的 bit。
把意外按概率加权平均,就是分布的熵:
H(P)=−i∑pilog2pi=EP[I(X)]
直觉一句话:熵 = 平均每次抽样,你需要花多少 bit 才能描述结果。
- 均匀分布 → 完全猜不准 → 熵最大(N 个等概率事件,熵 = log2N)。
- 一点冲突都没有(某事件概率 1) → 闭着眼都能猜中 → 熵 = 0。
拖滑块感受:
熵 H(P)
2.10 bit
最大值 = log₂6 ≈ 2.58 bit(完全均匀时)
几乎能猜中 → 熵很低
熵 = 平均要花多少 bit 才能描述一次抽样。 分布越「平」,熵越大;越「尖」,熵越小。
熵是信息论的「主角色」。它不是抽象的——Shannon 在 1948 年证明,H(P) 就是用最优编码压缩这个分布的样本所需的平均比特数。换句话说,熵给出了「这个分布最少需要多少存储空间」的下界。
现在场景换一下:
真实分布是 P,但我们手上只有一个估计的分布 Q(模型的预测)。如果用为 Q 设计的编码去压缩 P 的样本,平均每次要花多少 bit?
答案就是交叉熵:
H(P,Q)=−i∑pilog2qi
- 如果 Q=P,H(P,Q)=H(P)——最优情况,等于真分布的熵。
- 如果 Q=P,H(P,Q)>H(P)——你用了错的编码,被惩罚了多余的 bit。
- H(P,Q) 永远 ≥ H(P)(这就是著名的 Gibbs 不等式)。
这就是为什么 ML 里分类的损失函数就是交叉熵:
L=−i∑pilogqi
真实标签是 one-hot,比如「猫」对应 P=[1,0,0,0]。这时:
L=−logq猫
「最小化交叉熵」就翻译成了一句话:让模型预测真实类别的概率尽量大。LLM 训练里的 next-token loss 也是同一个公式,只是「类别」从「猫狗鸟鱼」换成了「词表里的几万个 token」。
试试调一下模型分布 Q,看 cross-entropy 怎么变:
训练分类器 = 调 Q 让 H(P, Q) 尽量小。 最小值就是 H(P)——此时 Q = P,KL = 0。
把交叉熵和真分布的熵相减,得到一个非常有用的量:
DKL(P∥Q)=H(P,Q)−H(P)=i∑pilog2qipi
这就是 KL 散度(Kullback–Leibler divergence)。
直觉上:
KL 是「用 Q 而不是 P 来描述 P 时,多浪费了几个 bit」。
它有三个值得记住的性质:
- DKL≥0,等于 0 当且仅当 P=Q。所以可以当「距离」用。
- 不对称: DKL(P∥Q)=DKL(Q∥P)。所以不是真正的距离——选哪个方向有讲究。
- 训练分类器最小化交叉熵 = 最小化 KL 散度——因为 H(P) 在数据集固定时是常数。
第二条的不对称很微妙:DKL(P∥Q) 强迫 Q 覆盖 P 的所有支持区域(否则 logp/q→∞);而 DKL(Q∥P) 反过来,允许 Q 只「贴」到 P 的某个模态上。前者叫 mode-covering, 后者叫 mode-seeking——这在 VAE、扩散模型、GAN 里是核心的设计差异。