我最早接触交叉熵的时候,心里只有一个想法:这公式也太丑了。一堆 log 和概率乘在一起,怎么就变成了“损失”?后来我才明白,它背后藏着一个扳道工的故事——而且这个故事,香农在 1948 年就写好了。

损失函数,说白了就是模型的自我纠错机制。模型输出一个预测,真实答案摆在另一边,损失函数负责给这次预测打个分:你猜得越离谱,分数越低(或者说,损失越高)。模型的目标就是拼命把这个分数压到最小。但这里有一个关键:这个打分必须是可以求导的,因为模型要靠梯度下降一点一点挪动参数,就像你闭着眼睛下山,全靠脚底下的坡度告诉你往哪走。如果损失函数不可微,坡度就没了,模型也就没法学习。
那为什么分类问题几乎都用交叉熵,而不是我们最熟悉的“算错了多少”或者“距离的平方”呢?
香农1948年就为你准备好了答案
交叉熵这个词,其实是从信息论里借来的。要理解它,得先回到信息熵。香农在他那篇著名的论文里定义了一个概念:熵,衡量的是一个事件的不确定性。比如一枚公平的硬币,正面反面概率各 0.5,它的熵是 1 比特——你每次都需要 1 比特的信息来描述抛掷结果。如果硬币是特制的,100% 正面,那熵就是 0,因为根本不需要信息,你早就知道结果了。
那交叉熵呢?它衡量的是:当你用一个错误的概率分布去编码真实分布的事件时,你得多花多少比特。比如真实硬币是公平的(50% 正面),但你误以为它 90% 正面、10% 反面。你按照自己以为的分布去设计一套编码(出现概率越高的结果用越短的码),结果拿到真实世界里去传输抛掷结果——你会发现,你平均每次要多花一些比特才能把信息传出去。这个“多花的比特数”,就是交叉熵比真实熵多出来的那一部分。
把这个直觉搬到分类任务上,一切都通了。模型输出一个概率分布(比如 softmax 之后的三个类别的概率),真实标签是一个 one-hot 分布(正确答案是 1,其他是 0)。交叉熵就是在算:如果按模型预测的概率分布去编码“正确答案”,要花多少额外比特。模型预测得越准,额外的比特越少;当模型预测和真实分布完全一致时,交叉熵就等于真实分布的熵——对于 one-hot,熵为 0,所以交叉熵也变成 0。
分类问题里,交叉熵是怎么“算账”的
我们看一个具体的例子。假设做一个三分类:猫、狗、鸟。一张猫的图片,真实标签是[1, 0, 0]。模型预测的概率分布是[0.7, 0.2, 0.1]。交叉熵的公式是:
- Σ y_i * log(p_i)
其中 y_i 是真实类别的 one-hot 值(只有猫那一项是 1),p_i 是模型预测的概率。所以计算就是:
- (1 * log(0.7) + 0 * log(0.2) + 0 * log(0.1)) = -log(0.7) ≈ 0.357
如果模型自信满满地猜错,比如输出[0.1, 0.8, 0.1](真实是猫,它猜狗),损失就是 -log(0.1) ≈ 2.3,一下子涨了 6 倍多。那个 log 在这里扮演了一个惩罚放大器的角色:当预测概率离 1 很远时,log 会给出一个巨大的惩罚,而且这个惩罚的增长是非线性的——越自信地错,惩罚越狠。这正好符合我们想要的学习信号:模型对错误答案越自信,就越需要被狠狠纠正。
为什么不是均方误差?
很多人(包括早年的我)会问:为什么不用更直观的均方误差(MSE)?比如直接算 (1 – 0.7)² + (0 – 0.2)² + (0 – 0.1)²?
答案藏在梯度里。我们用一个表格对比一下:
| 损失函数 | 公式(简化) | 梯度特性 | 适用场景 |
|---|---|---|---|
| 交叉熵 | -Σ y_i log(p_i) | 当 p_i 远小于 1 时,梯度大,学习快;越接近 1,梯度越小 | 分类 |
| 均方误差 | Σ (y_i – p_i)² | 当 p_i 接近 0 或 1 时,梯度很小,学习几乎停滞 | 回归(不适合分类) |
关键就在那个“梯度很小”上。MSE 搭配 softmax 输出时,如果模型预测某个类别的概率非常接近 0 或 1,它的梯度会变得极其微小,模型几乎不动了。这就好比你在山脚下时,MSE 告诉你“前面很平,不用走了”,但其实你离山顶还远着呢。交叉熵则没有这个毛病,它根据误差的大小给出成比例的梯度,该快的时候快,该慢的时候慢,学习效率高得多。
我亲手算了一遍交叉熵,才明白那个 log 是在惩罚过度自信
有一件事让我困惑了很久。如果模型预测的概率是 0.99,正确类别是 1,损失是 -log(0.99) ≈ 0.01,几乎可以忽略。但如果模型预测的概率是 0.01,正确类别是 1,损失高达 4.6。这个不对称性,在直觉上感觉很合理——错得离谱就该重罚。但直到我意识到“log 在 0 附近变化极快,在 1 附近变化极慢”这个数学特性时,我才真正理解这种设计的美妙:它不是在惩罚错误,它是在惩罚“不该有的自信”。模型如果你不确定,就给我输出一个不高不低的概率,这样即使错了,损失也不会太离谱;但如果你在错误答案上斩钉截铁,损失函数就会让你刻骨铭心。
常见误解
交叉熵损失能到 0,是不是说明模型已经完美了?
理论上,对于 one-hot 标签,如果模型输出概率分布恰好也是 one-hot 且正确,交叉熵确实是 0。但在实际中,softmax 输出永远不可能完全达到 0 或 1(只是无限接近),而且真实标签也可能不是绝对 one-hot(比如标签平滑),所以交叉熵永远不会真的到 0。不过,它逼着模型往那个方向努力。
交叉熵只适用于分类吗?
主要用于分类,但它的思想可以推广到任何需要衡量两个概率分布差异的场景,比如语言模型中的下一个词预测,用的也是交叉熵。
多分类和二分类的交叉熵公式一样吗?
本质一样。二分类交叉熵常写为 -[y log(p) + (1-y) log(1-p)],其实就是多分类公式在只有两个类别时的特例,用上 softmax 后等价。
边界与局限
交叉熵不是银弹。它对标签噪声非常敏感,因为如果训练数据里把“猫”标成了“狗”,模型会拼命去拟合这个错误,造成灾难性后果。另外,在类别极度不平衡的数据集上,交叉熵容易被多数类带偏,于是有了 Focal Loss 等改进版,它们通过降低易分类样本的权重,让模型更关注难例。不过,即便有这些局限,理解交叉熵的直觉,是理解整个现代深度学习优化过程的基石。下次你再看到那个带 log 的公式,不要只看到数学,要看到那个扳道工——它正根据你的预测和真实之间的“额外编码代价”,一遍遍扳动模型的参数轨道。
进阶阅读
- Shannon (1948) A Mathematical Theory of Communication — 信息论的开山之作
- Wikipedia: Cross entropy — 交叉熵的数学定义与性质
- Understanding binary cross-entropy / log loss: a visual explanation — 直观的可视化讲解
原创文章,作者:guanweilu,如若转载,请注明出处:https://guanweilu.cn/article/85.html