信息论:熵、交叉熵、KL 散度的直觉
损失函数为什么长 -log P 这样?这一篇从信息论角度回答。理解了,你看到任何损失函数都不再陌生。
L1-04 我们看到 ML 的损失函数 。为什么是 log?为什么是负号?
答案藏在 1948 年 Shannon 的一篇论文里——信息论。这一篇我们打开它的核心,理解为什么所有 ML 损失都长这样。
第一站:信息的”量”怎么衡量
凭直觉,信息量取决于”惊讶程度”:
- “明天太阳会升起” — 没什么信息(几乎确定)
- “明天会下雨” — 有点信息(不太确定)
- “你今晚中彩票头奖” — 信息巨大(极不可能)
事件越罕见,它发生时携带的信息越大。
Shannon 用数学表达这个直觉。一个概率为 的事件,发生时携带的”信息量”是:
注意:
- (确定的事),,(没信息)
- (极罕见),,(信息巨大)
- 负号:让 总是正数
底数通常取 2(单位叫”比特”)或 (单位叫”奈特”)。ML 里用 (自然对数)。
第二站:熵 = 平均信息量
如果一个变量 服从某个分布,它的”熵”是它每次取值的平均信息量:
直觉:
- 确定的分布(一个值概率为 1,其它为 0):熵 = 0(每次结果都没意外)
- 均匀分布:熵最大(每次结果都最让人意外)
举例:抛一枚公平硬币():
抛一枚作弊硬币( 正面):
作弊硬币熵小 — 因为几乎不让人惊讶。
熵是”不确定性”的数学度量。分布越均匀、越不可预测,熵越大。
第三站:交叉熵
到现在为止讲的都是真实分布 的事。但 ML 还有一个”预测分布” ——模型给出的概率分布。
交叉熵就是衡量”用 q 去近似 p”的代价:
注意符号顺序:左边是真实,右边是预测。它是不对称的!
直觉:
- 如果 (预测完美), —— 等于 p 的熵,是最小可能值
- 偏离 越远, 越大
这就是 ML 训练的损失:
真实标签 是 one-hot:[0, 0, 1, 0, …](第 3 类对)。 模型预测 是概率分布:[0.1, 0.05, 0.7, 0.15, …]。
交叉熵 = ≈ 0.357
训练让 越来越靠近 ,交叉熵越来越小。
第四站:KL 散度
KL 散度衡量两个分布的”距离”:
性质:
- (自己和自己没差异)
- 总是
- 不对称!
它和交叉熵的关系:
翻译:交叉熵 = 真实分布的熵 + 真实和预测之间的 KL 散度。
训练时 是常数(标签固定),所以最小化交叉熵 = 最小化 KL 散度。两个说法在 ML 里是等价的。
第五站:所有损失函数都是它
回过头看 ML 各种损失:
1. 多分类交叉熵(图像分类、文本分类)
直接是交叉熵。
2. 二分类交叉熵
是上面的特例(只有 2 个类别)。
3. LLM 训练(语言模型)
模型预测下一个词,真实 token 是 one-hot,所以又是交叉熵。
4. VAE 重建损失
显式用 KL 散度做正则化。
5. 强化学习 PPO
也用 KL 散度做”新旧策略不要差太远”的约束。
6. 知识蒸馏
让学生模型的输出分布逼近老师模型。
你看到的 ML 损失函数,几乎全部都是某种形式的交叉熵或 KL 散度。所有”让模型预测靠近真实”的训练,本质都在做”让两个概率分布更近”。
第六站:MSE 也是交叉熵?
很多人以为均方误差(MSE)和交叉熵不搭。其实它也是交叉熵的特例。
如果你假设真实数据 服从高斯分布 :
取负对数:
这就是 MSE!只是去掉常数和缩放。
结论:MSE = 假设噪声是高斯分布时的最大似然估计。
它不是”另一种”损失,它和交叉熵是同一个东西的不同视角。
第七站:用 Python 看看
import numpy as np
# 真实分布(one-hot)和模型预测
y_true = np.array([0, 0, 1, 0, 0]) # 第 3 类
y_pred = np.array([0.1, 0.05, 0.7, 0.1, 0.05])
# 交叉熵
ce = -np.sum(y_true * np.log(y_pred + 1e-9))
print(f"交叉熵: {ce:.4f}") # 0.3567
# KL 散度(注意:one-hot 时严格地讲不能算,因为 log 0 = -inf)
# 用一个平滑的 y_true
y_true_smooth = np.array([0.01, 0.01, 0.96, 0.01, 0.01])
kl = np.sum(y_true_smooth * np.log(y_true_smooth / y_pred))
print(f"KL 散度: {kl:.4f}")
# 一个分布的熵
p = np.array([0.5, 0.3, 0.2])
h = -np.sum(p * np.log(p))
print(f"熵: {h:.4f}") # ≈ 1.0297
# 均匀分布熵最大
uniform = np.array([1/3, 1/3, 1/3])
h_max = -np.sum(uniform * np.log(uniform))
print(f"均匀分布熵: {h_max:.4f}") # ≈ 1.0986
一句话总结
熵 = 不确定性。交叉熵 = “用预测替代真实”的成本。KL 散度 = “两个分布之间的距离”。
几乎所有 ML 损失都是它们的某种形式。理解了这一篇,你看到任何新的”奇怪损失函数”,都能秒翻译成”这是在让某个分布靠近另一个分布”。
- ✓ 线性代数(L1-02)
- ✓ 导数与梯度(L1-03)
- ✓ 概率与最大似然(L1-04)
- ✓ 信息论(本篇)
- 下一篇:链式法则与反向传播 —— 把所有数学武器组合起来训练真神经网络
读到这里说明你认真在学 🎯
订阅每周精选 —— 下一篇新文章 / 新可视化第一时间送到邮箱。
讨论区
· 用 GitHub 账号登录评论src/components/Comments.astro 顶部填入
仓库 ID 和分类 ID(见组件注释里的配置步骤)。