Visual Information Theory
Chris Olah 的信息论可视化
一句话定义:信息论是研究信息量化、存储和传输的数学分支。由香农 (Claude Shannon) 在 1948 年创立。在 AI 中,它是理解 Cross-Entropy Loss 和 KL 散度 的关键。
调整真实分布 P 和预测分布 Q,观察熵、交叉熵和 KL 散度如何变化。
熵就像是一本杂志的”惊讶总量”。如果每篇文章都是”太阳升起”,熵很低(无聊)。如果有各种稀奇古怪的新闻,熵很高(精彩)。
在分类任务中,模型输出的是概率分布 ,而真实标签是one-hot 分布 。
我们需要一种方式来衡量”模型预测”和”真实答案”有多接近。
Cross-Entropy Loss 正是用信息论的方式来做这件事:
这比简单的 MSE 更适合分类问题,因为它能惩罚”自信但错误”的预测。
一个事件发生的信息量,与其概率成反比:
随机变量的平均信息量:
用分布 编码来自分布 的数据时的平均码长:
两个分布的”差异”:
import torchimport torch.nn.functional as F
# 真实标签 (one-hot): 类别 2y_true = torch.tensor([0, 0, 1, 0], dtype=torch.float32)
# 模型预测 (softmax 后的概率)y_pred = torch.tensor([0.1, 0.2, 0.6, 0.1])
# ===== 手动计算交叉熵 =====# H(p, q) = -Σ p(x) * log(q(x))cross_entropy_manual = -torch.sum(y_true * torch.log(y_pred + 1e-9))print(f"手动计算 Cross-Entropy: {cross_entropy_manual.item():.4f}")# 输出: 0.5108
# ===== PyTorch 内置 (推荐) =====# 注意: F.cross_entropy 接受 logits (未经 softmax)logits = torch.log(y_pred) # 转回 logits (近似)target = torch.tensor(2) # 类别索引loss = F.cross_entropy(logits.unsqueeze(0), target.unsqueeze(0))print(f"PyTorch Cross-Entropy: {loss.item():.4f}")
# ===== KL 散度 =====p = y_true / y_true.sum() # 确保是概率分布q = y_predkl_div = F.kl_div(torch.log(q), p, reduction='sum')print(f"KL 散度: {kl_div.item():.4f}")import numpy as np
def entropy(p): """计算熵 H(p)""" p = np.array(p) p = p[p > 0] # 忽略 0 概率 return -np.sum(p * np.log2(p))
def cross_entropy(p, q): """计算交叉熵 H(p, q)""" p, q = np.array(p), np.array(q) q = np.clip(q, 1e-10, 1) # 避免 log(0) return -np.sum(p * np.log2(q))
def kl_divergence(p, q): """计算 KL 散度 D_KL(p || q)""" return cross_entropy(p, q) - entropy(p)
# 示例p_true = [0, 0, 1, 0] # 真实分布 (one-hot)q_pred = [0.1, 0.2, 0.6, 0.1] # 模型预测
print(f"熵 H(p): {entropy(p_true):.4f}") # 0 (确定性分布)print(f"交叉熵 H(p,q): {cross_entropy(p_true, q_pred):.4f}")print(f"KL 散度: {kl_divergence(p_true, q_pred):.4f}")