欢迎光临
我们一直在努力

模型“猜错“该罚多少?-log(0.01) 和 0.01,差了 460 倍——从信息熵到交叉熵的一课

训练一个分类模型,你八成写过这一行(或它背后的数学):

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)=ip(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(pq)=ip(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(pq)=H(p)

ip(i)logp(i)+H(p,q)

(ip(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)=ip(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

zL=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实验室】的《机器学习数学基础》。

赞(0)
未经允许不得转载:171主机测评 » 模型“猜错“该罚多少?-log(0.01) 和 0.01,差了 460 倍——从信息熵到交叉熵的一课
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址