训练一个分类模型,你八成写过这一行(或它背后的数学):
loss = nn.CrossEntropyLoss()(logits, labels)
但你有没有停下来想过一个问题:模型把一个样本"猜错"了,我们到底该怎么罚它? 是罚"猜错的程度"(比如预测 0.01,离正确答案 1 差了 0.99)?还是罚别的什么东西?
直觉上,罚"差值"最自然——均方误差(MSE)就是这么干的。可深度学习分类,几乎清一色用交叉熵,而不是 MSE。为什么?这个问题要回答清楚,得先绕一段路,从 1948 年香农的信息论说起。这条路不长,但每一步都挺有意思。
第一步:什么是"信息量"——越不可能的事,越值钱
先想一个直觉问题:下面两句话,哪句"信息量"更大?
- 甲:“太阳明天照常升起。”
- 乙:“明天要下金子雨。”
显然是乙。因为甲几乎必然发生,你听到它等于没听到;乙几乎不可能发生,一旦发生,带来的信息冲击巨大。
香农把这个直觉量化成了一个公式:一个概率为 p 的事件,它携带的信息量是 −log p。
事件概率 p 越大 → 信息量 −log p 越小(越"废话")
事件概率 p 越小 → 信息量 −log p 越大(越"劲爆")
用 log 而不是别的函数,有个漂亮的理由:两个独立事件一起发生,总信息量应该等于各自信息量之和,而 log 恰好把乘法变加法——−log(p₁p₂) = −log p₁ − log p₂。这个性质,让"信息"的定义自洽了。
第二步:什么是"熵"——一个系统的平均"不确定性"
单个事件有信息量,那一整个概率分布呢?答案是取平均:把所有可能结果的信息量,按它们各自的概率加权求和。这个平均值,就是熵(entropy):
H
(
p
)
=
−
∑
i
p
(
i
)
log
p
(
i
)
H(p) = -\\sum_i p(i)\\,\\log p(i)
H(p)=−i∑p(i)logp(i)
熵衡量的是一个分布的平均不确定性。抛一枚公平硬币,正反各 50%,熵最大(最不可预测);如果硬币作弊、99% 出正面,熵就很小(基本能猜中)。熵越大,系统越"乱"、越难猜。
到这里,我们还只是"描述"一个分布。但机器学习要的是"比较"两个分布——真实分布 p 和模型预测的分布 q,到底差多远? 接下来才是重头戏。
第三步:KL 散度——用"错误的描述"去描述"真实",要付出多少代价
假设真实分布是 p(比如一张猫图,真实标签是"猫=1,狗=0,鸟=0"),而模型预测的分布是 q(比如"猫=0.7,狗=0.2,鸟=0.1")。我们想知道 q 离 p 有多远。
一个巧妙的问法:如果我们"错把 q 当成真实分布",然后用 q 的编码方案去描述真实发生的事件,平均要多花多少"比特"? 这个"多花的代价",就是 KL 散度(相对熵):
D
K
L
(
p
∥
q
)
=
∑
i
p
(
i
)
log
p
(
i
)
q
(
i
)
D_{KL}(p \\parallel q) = \\sum_i p(i)\\,\\log\\frac{p(i)}{q(i)}
DKL(p∥q)=i∑p(i)logq(i)p(i)
KL 散度有个好性质:永远非负,且只有当 p = q 时等于 0。两个分布越像,KL 散度越小。它完美刻画了"q 和 p 的差距"。
但直接用 KL 散度当损失函数有个小麻烦。把它拆开:
D
K
L
(
p
∥
q
)
=
∑
i
p
(
i
)
log
p
(
i
)
⏟
−
H
(
p
)
+
(
−
∑
i
p
(
i
)
log
q
(
i
)
)
⏟
H
(
p
,
q
)
D_{KL}(p \\parallel q) = \\underbrace{\\sum_i p(i)\\log p(i)}_{-H(p)} \\;+\\; \\underbrace{\\left(-\\sum_i p(i)\\log q(i)\\right)}_{H(p,\\,q)}
DKL(p∥q)=−H(p)
i∑p(i)logp(i)+H(p,q)
(−i∑p(i)logq(i))
第一项是真实分布 p 的熵 H§ 的相反数。关键点来了:在训练过程中,真实分布 p 是固定不变的(标签就长那样),所以 H§ 是个常数,不参与梯度更新。真正会随模型变化、需要我们去最小化的,只有第二项:
H
(
p
,
q
)
=
−
∑
i
p
(
i
)
log
q
(
i
)
H(p,\\,q) = -\\sum_i p(i)\\,\\log q(i)
H(p,q)=−i∑p(i)logq(i)
这一项,就是交叉熵(cross entropy)。 所以"最小化 KL 散度"和"最小化交叉熵",在训练时是完全等价的——它们只差一个常数 H§。这就是为什么损失函数用交叉熵:它省掉了那个我们根本不需要知道的常数项,却完整保留了"让 q 逼近 p"的全部信息。
一个具体数字,感受交叉熵的"惩罚力度"
回到那只猫。真实分布 p = [猫1, 狗0, 鸟0](one-hot),模型预测 q = [0.7, 0.2, 0.1]。交叉熵只对真实类别"猫"那一项非零:
损失 = -1 × log(0.7) = 0.357
如果模型更有信心、猜得更准,q = [0.95, …],损失 = -log(0.95) = 0.051,小了。
反过来,如果模型自信地猜错——把一只猫,用 99% 的置信度猜成"狗"(q 里猫那项只有 0.01):
损失 = -log(0.01) = 4.6
看见没?-log(0.01) = 4.6,而"差值"只有 0.99。 交叉熵用对数,把"自信地犯错"惩罚到了一个夸张的程度——你越笃定地错,罚得越狠。这正是我们想要的:模型最该被重罚的,不是"犹豫着错",而是"斩钉截铁地错"。
那为什么不用 MSE?
这可能是交叉熵最"硬核"、也最常被问的一点。答案藏在梯度里。
当交叉熵搭配 softmax 输出时,损失对 logits 的梯度会化简成极漂亮的形式:
∂
L
∂
z
=
y
^
−
y
\\frac{\\partial L}{\\partial z} = \\hat{y} – y
∂z∂L=y^−y
——梯度 = 预测值 − 真实值。误差越大,梯度越大,学习信号清晰稳定,不存在"学不动"的问题。
而 MSE 配合 sigmoid/softmax 时,当预测严重错误、落在激活函数的饱和区,梯度会趋近于 0——错得越离谱,反而越学不动(这就是著名的"梯度消失")。模型在它最该拼命改正的时候,却失去了学习的动力。
所以"分类用交叉熵而不是 MSE",不是玄学,是梯度性质决定的:交叉熵保证"错得越狠,改得越猛",MSE 却会在错误最大的地方"熄火"。
从 1948 年,到今天的 loss 曲线
把这条链捋一遍,你会发现它美得惊人:
信息量(−log p,越不可能越值钱)
↓ 取平均
熵(一个分布的平均不确定性)
↓ 换用错误分布 q 去描述真实 p
KL 散度(多花的比特代价)
↓ 拆掉那个常数项 H(p)
交叉熵(= KL 散度 + 常数,可直接当损失)
↓ 配上 softmax
梯度 = 预测 − 真实(学习信号清晰稳定)
香农在 1948 年提出信息论时,肯定想不到他这套"度量信息"的数学,会在七十年后成为每天跑在几百万块 GPU 上的损失函数。最优雅的理论,往往最后成为最实用的工具。
下次你在训练日志里盯着 loss 往下降,不妨多想一层:你的模型不是在"减少错误",而是在一步步地,让它的预测分布 q,去逼近那个真实分布 p——用最少的比特,去描述这个世界的真相。
想补齐信息熵、概率分布、矩阵运算这些机器学习所需的数学底子,推荐 B站【408实验室】的《机器学习数学基础》。



