从第一性原理理解交叉熵 | AI生成和翻译
问题: 使用数学从基本原理解释交叉熵。
回答:
交叉熵:完整数学推导
1. 从信息论开始
对于一个概率为 p 的事件,其惊异度(自信息)为:
I(x) = −log p(x)
单位取决于对数的底数:以2为底是比特,以e为底是纳特。PyTorch 使用 ln(纳特)。
为什么是负对数? 三个公理决定了这种形式:
- 必然事件
p=1→ 零惊异度:−log(1) = 0✓ - 不可能事件
p→0→ 无限惊异度:−log(0) = ∞✓ - 独立事件的概率相乘,惊异度相加:
−log(p·q) = −log p − log q✓
2. 香农熵 H(p)
在真实分布下的期望惊异度:
H(p) = 𝔼_{x∼p}[−log p(x)] = −Σₓ p(x) log p(x)
这是当你知道真实分布时所能达到的最小平均编码长度。它是一个下界——你无法做得更好。
3. 交叉熵 H(p, q)
现在假设你不知道 p。你假设分布为 q 来设计编码,但现实是从 p 中采样:
H(p, q) = 𝔼_{x∼p}[−log q(x)] = −Σₓ p(x) log q(x)
分解一下:
| 项 | 含义 |
|---|---|
−log q(x) |
你分配给事件 x 的编码长度(错误的假设) |
p(x) |
真实权重——x 实际发生的频率 |
Σₓ p(x) · [−log q(x)] |
现实条件下的期望代价 |
4. KL 分解(最重要的恒等式)
H(p, q) = H(p) + D_KL(p ∥ q)
证明:
D_KL(p ∥ q) = Σₓ p(x) log [p(x) / q(x)]
= Σₓ p(x) [log p(x) − log q(x)]
= Σₓ p(x) log p(x) − Σₓ p(x) log q(x)
= −H(p) + H(p, q)
→ H(p, q) = H(p) + D_KL(p ∥ q) □
由于 D_KL ≥ 0 始终成立(吉布斯不等式),可得:
H(p, q) ≥ H(p)
当且仅当 p = q 时取等号。这就是最小化交叉熵有效的原因——训练期间 H(p) 是常数(标签固定),因此:
argmin_q H(p, q) = argmin_q D_KL(p ∥ q)
5. One-Hot 坍缩(语言建模案例)
在语言模型训练中,p 在词表上是 one-hot 的:p(y=k) = 1,其余全部 = 0。
对所有类别的求和坍缩为单个项:
H(p, q) = −Σₓ p(x) log q(x)
= −[0·log q(x₁) + ··· + 1·log q(y_true) + ··· + 0·log q(xₙ)]
= −log q(y_true)
这就是整个损失——仅仅是模型分配给正确 token 的负对数概率。每个其他类别都贡献为零,因为 p(x≠y_true) = 0。
6. Softmax + Log-Sum-Exp 链
你的模型输出 logits z ∈ ℝᶜ。Softmax 给出:
q(y=k) = exp(zₖ) / Σⱼ exp(zⱼ)
将 one-hot 目标类别 c 代入交叉熵:
L = −log q(y=c)
= −log [ exp(zc) / Σⱼ exp(zⱼ) ]
= −zc + log Σⱼ exp(zⱼ)
= −zc + LogSumExp(z)
这就是 F.cross_entropy 直接计算的内容——无需中间的 softmax。梯度很简洁:
∂L/∂zₖ = q(y=k) − 𝟙[k=c]
= 预测概率减去 one-hot 真值。对于正确类别 k=c:
∂L/∂zc = q(y=c) − 1
当模型置信度不足时为负 → 梯度推动 zc 上升。对于错误类别:
∂L/∂zₖ = q(y=k) (k ≠ c)
为正 → 梯度推动 zₖ 下降。梯度就是预测与真值之间的残差。非常优美。
7. 完整图示
现实(真实标签 p)
│
│ 以概率 p(x) 采样 x
▼
模型分配的代价:−log q(x) ← 仅取决于 q
│
│ 按 p(x) 加权,求和
▼
H(p,q) = H(p) ──────────────────┐
+ D_KL(p‖q) ◄────┘ ← 这就是训练最小化的对象
↑
└── 仅当 q = p 时为零(完美模型)
一句话直觉
交叉熵是模型因错误估计分布而平均浪费的纳特数——熵是不可逾越的下限,KL 散度是可修复的差距。