前置知识: AI工程

信息论

00:00
3 min Intermediate

熵、交叉熵、KL 散度、互信息、困惑度、标签平滑

信息论

信息论回答一个根本问题:一个事件包含多少”惊讶”?答案决定了我们如何压缩数据、训练模型和衡量不确定性。

类型: 构建 语言: Python 前置条件: 阶段 1,第 06 课(概率与分布) 预计时间: ~90 分钟

学习目标

  • 从零计算熵、交叉熵和 KL 散度,解释它们在 AI 中的含义
  • 使用互信息衡量两个变量之间的依赖关系
  • 计算困惑度并解释它作为语言模型评估指标的意义
  • 实现标签平滑并解释它为什么提升泛化能力

问题所在

交叉熵损失是分类和语言模型的标准损失函数。KL 散度是 VAE 和知识蒸馏的核心。困惑度是语言模型的评估指标。如果你不理解信息论,你就无法理解这些方法为什么有效、何时使用它们,或如何调试它们。

核心概念

信息量

一个事件的信息量与它的概率成反比。越罕见的事件,信息量越大。

I(x) = -log2(P(x))
def information(p):
    """事件的信息量"""
    return -np.log2(p)

print(f"P=0.5: {information(0.5):.2f} bits")   # 1.00
print(f"P=0.25: {information(0.25):.2f} bits")  # 2.00
print(f"P=0.125: {information(0.125):.2f} bits") # 3.00

概率减半,信息量加 1 bit。

熵是信息量的期望值。它衡量随机变量的平均不确定性。

H(X) = -sum(P(x) * log2(P(x)))
def entropy(probs):
    """计算熵"""
    return -sum(p * np.log2(p) for p in probs if p > 0)

# 公平硬币
print(f"公平硬币: {entropy([0.5, 0.5]):.2f} bits")  # 1.00

# 不公平硬币
print(f"偏硬币: {entropy([0.9, 0.1]):.2f} bits")    # 0.47

# 确定性事件
print(f"确定性: {entropy([1.0, 0.0]):.2f} bits")    # 0.00

熵越高,不确定性越大。均匀分布的熵最大。

交叉熵

交叉熵衡量使用分布 Q 编码来自分布 P 的数据所需的平均比特数。

H(P, Q) = -sum(P(x) * log2(Q(x)))
def cross_entropy(p_true, p_pred):
    """交叉熵"""
    return -sum(p * np.log2(q) for p, q in zip(p_true, p_pred) if p > 0)

p = [1, 0, 0]  # 真实分布
q_good = [0.9, 0.05, 0.05]  # 好的预测
q_bad = [0.3, 0.4, 0.3]     # 差的预测

print(f"好预测: {cross_entropy(p, q_good):.4f} bits")  # 0.152
print(f"差预测: {cross_entropy(p, q_bad):.4f} bits")    # 1.737

当 Q = P 时,交叉熵等于熵。Q 越偏离 P,交叉熵越大。

KL 散度

KL 散度衡量两个分布之间的”距离”。它是交叉熵与熵之差。

KL(P || Q) = H(P, Q) - H(P) = sum(P(x) * log(P(x)/Q(x)))
def kl_divergence(p, q):
    """KL 散度"""
    return sum(pi * np.log2(pi / qi) for pi, qi in zip(p, q) if pi > 0 and qi > 0)

print(f"KL(好预测): {kl_divergence(p, q_good):.4f}")  # 0.152
print(f"KL(差预测): {kl_divergence(p, q_bad):.4f}")    # 1.737

关键性质:

  • 非负:KL(P||Q) >= 0,等号当且仅当 P = Q
  • 不对称:KL(P||Q) != KL(Q||P),不是真正的距离

互信息

互信息衡量两个变量之间的依赖关系。

I(X; Y) = H(X) - H(X|Y) = sum P(x,y) * log(P(x,y) / (P(x)*P(y)))

互信息 = X 的不确定性 - 给定 Y 后 X 的不确定性。如果 I(X;Y) = 0,X 和 Y 独立。

困惑度

困惑语言模型的标准评估指标。它是交叉熵的指数。

Perplexity = 2^H(P, Q)
def perplexity(p_true, p_pred):
    """困惑度"""
    ce = -sum(p * np.log2(q) for p, q in zip(p_true, p_pred) if p > 0)
    return 2 ** ce

# 好的模型:困惑度低
print(f"好模型困惑度: {perplexity(p, q_good):.2f}")  # 1.11
# 差的模型:困惑度高
print(f"差模型困惑度: {perplexity(p, q_bad):.2f}")    # 3.31

困惑 = “模型在每个位置平均不确定的词数”。困惑 10 意味着模型在每个位置平均在 10 个词之间犹豫。

标签平滑

标签平滑将硬标签([1, 0, 0])变为软标签([0.9, 0.05, 0.05]),防止模型过自信。

def label_smoothing(labels, num_classes, epsilon=0.1):
    """标签平滑"""
    smoothed = np.ones(num_classes) * epsilon / (num_classes - 1)
    smoothed[labels] = 1 - epsilon
    return smoothed

# 原始标签:类别 0
print(f"原始: {[1, 0, 0]}")
print(f"平滑: {label_smoothing(0, 3, 0.1)}")  # [0.9, 0.05, 0.05]

实际应用

概念AI 中的位置
交叉熵分类损失,语言模型训练
KL 散度VAE,知识蒸馏,策略
决策树分裂标准信息增益
困惑语言模型评估
信息特征选择,表示学习
标签平滑正则化,提升泛化

练习

  1. 计算公平骰和偏骰(P(6)=0.5)的熵,比较差异
  2. 两个正态分布计算 KL 散度验证解析公式
  3. 实现困惑计算,用不同质量的”模型”预测同一文本
  4. 分类任务中比较使用硬标签标签平滑的训练效果

知识检测

学习进度

-- 已学文档
--% 知识覆盖率

学习推荐

专注模式