人工智能之数学基础 信息论:第二章 核心度量

人工智能之数学基础 信息论

第二章 核心度量


文章目录

  • [人工智能之数学基础 信息论](#人工智能之数学基础 信息论)
  • 前言
  • 一、核心概念回顾:香农熵
  • 二、交叉熵(Cross-Entropy)
    • [1. 定义](#1. 定义)
    • [2. 在分类任务中的形式](#2. 在分类任务中的形式)
  • [三、KL 散度(相对熵)](#三、KL 散度(相对熵))
    • [1. 定义](#1. 定义)
    • [2. KL 散度 vs 交叉熵](#2. KL 散度 vs 交叉熵)
  • 四、为什么分类任务用交叉熵作损失函数?
    • [1. 理论优势](#1. 理论优势)
    • [2. 与 MSE 对比(为何不用均方误差?)](#2. 与 MSE 对比(为何不用均方误差?))
  • [五、Python 代码实现](#五、Python 代码实现)
    • [1. 导入库](#1. 导入库)
    • [2. 从零实现交叉熵与 KL 散度](#2. 从零实现交叉熵与 KL 散度)
    • [3. 分类任务中的交叉熵(one-hot 形式)](#3. 分类任务中的交叉熵(one-hot 形式))
    • [4. 与 PyTorch / TensorFlow 对比](#4. 与 PyTorch / TensorFlow 对比)
    • [5. 可视化:交叉熵 vs 预测概率](#5. 可视化:交叉熵 vs 预测概率)
    • [6. KL 散度实验:逼近真实分布](#6. KL 散度实验:逼近真实分布)
    • [7. 多分类交叉熵的向量化实现(批量处理)](#7. 多分类交叉熵的向量化实现(批量处理))
  • 六、高级话题:交叉熵与最大似然估计(MLE)
  • 七、总结
  • 后续
  • 资料关注

前言

交叉熵(Cross-Entropy)和 KL 散度(Kullback-Leibler Divergence)是现代机器学习,尤其是深度学习分类任务的理论基石 。它们不仅定义了损失函数的形式,还揭示了模型学习的本质:让预测分布逼近真实分布

本文将系统讲解:

  • 交叉熵的定义与直觉
  • KL 散度(相对熵)的数学本质
  • 两者之间的深刻联系
  • 为什么分类任务使用交叉熵作为损失函数?
  • 配套 Python 代码实现(从零构建 + PyTorch/TensorFlow 对比 + 可视化)

一、核心概念回顾:香农熵

在深入交叉熵前,先回顾香农熵(Shannon Entropy)

H ( P ) = − ∑ x P ( x ) log ⁡ P ( x ) H(P) = -\sum_{x} P(x) \log P(x) H(P)=−x∑P(x)logP(x)

  • 表示真实分布 P 的不确定性(平均信息量)
  • 单位:比特(以 2 为底)或纳特(以 ( e ) 为底)

✅ 例:公平硬币 P(H)=P(T)=0.5 H§ = 1 比特


二、交叉熵(Cross-Entropy)

1. 定义

给定真实分布 P 模型预测分布 Q ,交叉熵定义为:

H ( P , Q ) = − ∑ x P ( x ) log ⁡ Q ( x ) H(P, Q) = -\sum_{x} P(x) \log Q(x) H(P,Q)=−x∑P(x)logQ(x)

  • 直觉:用基于 Q 的编码方案去编码来自 P 的数据,所需的平均比特数
  • Q = P ,则 H(P, Q) = H§ (最优编码)
  • Q \\ne P ,则 H(P, Q) \> H§

📌 关键点 :交叉熵衡量的是用错误模型 Q 描述真实世界 P 的代价


2. 在分类任务中的形式

多分类任务中:

  • 真实标签 y 是 one-hot 向量(如 [ 0 , 0 , 1 , 0 ] [0, 0, 1, 0] [0,0,1,0])
  • 模型输出 \\hat{y} 是概率分布(如 softmax 输出 [ 0.1 , 0.2 , 0.6 , 0.1 ] [0.1, 0.2, 0.6, 0.1] [0.1,0.2,0.6,0.1])

此时,交叉熵简化为:

H ( P , Q ) = − log ⁡ Q ( y true ) H(P, Q) = -\log Q(y_{\text{true}}) H(P,Q)=−logQ(ytrue)

即:只关注真实类别的预测概率

✅ 例:真实类别是第 3 类(索引 2), \\hat{y}_2 = 0.6 → 损失 = -\\log(0.6) \\approx 0.51


三、KL 散度(相对熵)

1. 定义

KL 散度衡量两个分布 P Q 非对称差异

D KL ( P ∥ Q ) = ∑ x P ( x ) log ⁡ P ( x ) Q ( x ) = E x ∼ P [ log ⁡ P ( x ) Q ( x ) ] D_{\text{KL}}(P \parallel Q) = \sum_{x} P(x) \log \frac{P(x)}{Q(x)} = \mathbb{E}_{x \sim P} \left[ \log \frac{P(x)}{Q(x)} \right] DKL(P∥Q)=x∑P(x)logQ(x)P(x)=Ex∼P[logQ(x)P(x)]

  • 性质
    • D_{\\text{KL}}(P \\parallel Q) \\geq 0
    • D_{\\text{KL}}(P \\parallel Q) = 0 \\iff P = Q
    • 非对称 D_{\\text{KL}}(P \\parallel Q) \\ne D_{\\text{KL}}(Q \\parallel P)
    • 不是距离(不满足三角不等式)

💡 直觉:KL 散度是"用 Q 近似 P 所损失的信息量"


2. KL 散度 vs 交叉熵

展开 KL 散度:

D KL ( P ∥ Q ) = ∑ x P ( x ) log ⁡ P ( x ) − ∑ x P ( x ) log ⁡ Q ( x ) = − H ( P ) + H ( P , Q ) \begin{aligned} D_{\text{KL}}(P \parallel Q) &= \sum_x P(x) \log P(x) - \sum_x P(x) \log Q(x) \\ &= -H(P) + H(P, Q) \end{aligned} DKL(P∥Q)=x∑P(x)logP(x)−x∑P(x)logQ(x)=−H(P)+H(P,Q)

因此:

H ( P , Q ) = H ( P ) + D KL ( P ∥ Q ) \boxed{H(P, Q) = H(P) + D_{\text{KL}}(P \parallel Q)} H(P,Q)=H(P)+DKL(P∥Q)

🌟 核心结论

  • 最小化交叉熵 ⇨ 最小化 KL 散度(因为 是常数!)
  • 模型训练的目标:让 Q \\to P ,即使 D_{\\text{KL}}(P \\parallel Q) \\to 0

四、为什么分类任务用交叉熵作损失函数?

1. 理论优势

  • 梯度良好 \\frac{\\partial}{\\partial z_i} (-\\log \\hat{y}_j) 在 softmax 下有简洁形式
  • 概率解释清晰:最大化真实类别的对数似然(MLE)
  • 与信息论一致:最小化预测与真实的分布差异

2. 与 MSE 对比(为何不用均方误差?)

指标 交叉熵 均方误差(MSE)
适用任务 分类(概率输出) 回归(连续值)
梯度饱和 无(尤其配合 softmax) 有(sigmoid + MSE 梯度消失)
优化目标 最大似然估计 最小平方误差
概率一致性

🔥 经典结论:分类任务应使用交叉熵,而非 MSE


五、Python 代码实现

1. 导入库

python 复制代码
import numpy as np
import torch
import tensorflow as tf
import matplotlib.pyplot as plt
import seaborn as sns

plt.rcParams['font.sans-serif'] = ['SimHei']
sns.set(style="whitegrid")

2. 从零实现交叉熵与 KL 散度

python 复制代码
def cross_entropy(p, q, eps=1e-15):
    """
    计算离散分布 p 和 q 的交叉熵 H(p, q)
    p, q: 一维 numpy 数组,表示概率分布(需归一化)
    """
    q = np.clip(q, eps, 1 - eps)  # 防止 log(0)
    return -np.sum(p * np.log(q))

def kl_divergence(p, q, eps=1e-15):
    """计算 KL(P || Q)"""
    q = np.clip(q, eps, 1 - eps)
    p = np.clip(p, eps, 1 - eps)
    return np.sum(p * np.log(p / q))

def entropy(p, eps=1e-15):
    """计算香农熵 H(p)"""
    p = np.clip(p, eps, 1 - eps)
    return -np.sum(p * np.log(p))

3. 分类任务中的交叉熵(one-hot 形式)

python 复制代码
def categorical_cross_entropy_onehot(y_true, y_pred, eps=1e-15):
    """
    y_true: one-hot 标签,shape=(n_classes,)
    y_pred: 预测概率,shape=(n_classes,)
    """
    y_pred = np.clip(y_pred, eps, 1 - eps)
    return -np.sum(y_true * np.log(y_pred))

# 示例
y_true = np.array([0, 0, 1, 0])      # 真实类别:第3类
y_pred_good = np.array([0.1, 0.1, 0.7, 0.1])   # 预测较好
y_pred_bad = np.array([0.4, 0.3, 0.1, 0.2])    # 预测较差

loss_good = categorical_cross_entropy_onehot(y_true, y_pred_good)
loss_bad = categorical_cross_entropy_onehot(y_true, y_pred_bad)

print(f"好预测的损失: {loss_good:.4f}")   # ≈ 0.3567
print(f"差预测的损失: {loss_bad:.4f}")   # ≈ 2.3026

4. 与 PyTorch / TensorFlow 对比

python 复制代码
# PyTorch
y_true_idx = torch.tensor([2])  # 真实类别索引
y_pred_logits = torch.tensor([[np.log(0.1), np.log(0.1), np.log(0.7), np.log(0.1)]])
loss_torch = torch.nn.CrossEntropyLoss()(y_pred_logits, y_true_idx)
print(f"PyTorch 损失: {loss_torch.item():.4f}")

# TensorFlow / Keras
y_true_tf = tf.constant([[0, 0, 1, 0]], dtype=tf.float32)
y_pred_tf = tf.constant([[0.1, 0.1, 0.7, 0.1]], dtype=tf.float32)
loss_tf = tf.keras.losses.categorical_crossentropy(y_true_tf, y_pred_tf)
print(f"TensorFlow 损失: {loss_tf.numpy()[0]:.4f}")

# 验证一致性
assert abs(loss_good - loss_torch.item()) < 1e-5
assert abs(loss_good - loss_tf.numpy()[0]) < 1e-5
print("✅ 自实现与主流框架一致")

⚠️ 注意:PyTorch 的 CrossEntropyLoss 接收 logits(未 softmax) ,内部自动加 softmax;而我们的实现接收 概率


5. 可视化:交叉熵 vs 预测概率

python 复制代码
p_true = 1.0  # 真实概率(one-hot)
q_pred = np.linspace(0.01, 1.0, 100)
ce_loss = [-np.log(q) for q in q_pred]

plt.figure(figsize=(8, 5))
plt.plot(q_pred, ce_loss, 'b-', linewidth=2)
plt.axvline(1.0, color='r', linestyle='--', label='完美预测 (q=1)')
plt.title('交叉熵损失 vs 预测概率(真实类别概率=1)')
plt.xlabel('模型预测概率 $\\hat{y}_{true}$')
plt.ylabel('交叉熵损失 $-\\log(\\hat{y}_{true})$')
plt.legend()
plt.grid(True)
plt.show()

📈 观察:当 \\hat{y}*{\\text{true}} \\to 0 ,损失 → ∞;当 \\hat{y}*{\\text{true}} = 1 ,损失 = 0


6. KL 散度实验:逼近真实分布

python 复制代码
# 真实分布 P:偏置硬币
p = np.array([0.9, 0.1])

# 一系列模型分布 Q
q_vals = np.linspace(0.1, 0.99, 50)
kl_vals = []
ce_vals = []

for q in q_vals:
    q_dist = np.array([q, 1 - q])
    kl_vals.append(kl_divergence(p, q_dist))
    ce_vals.append(cross_entropy(p, q_dist))

# 绘图
plt.figure(figsize=(10, 4))
plt.subplot(1, 2, 1)
plt.plot(q_vals, kl_vals, 'r-', label='$D_{KL}(P \\parallel Q)$')
plt.axvline(0.9, color='k', linestyle='--', label='P=Q')
plt.title('KL 散度'); plt.xlabel('Q(正面)'); plt.legend()

plt.subplot(1, 2, 2)
plt.plot(q_vals, ce_vals, 'b-', label='$H(P, Q)$')
plt.axvline(0.9, color='k', linestyle='--')
plt.title('交叉熵'); plt.xlabel('Q(正面)'); plt.legend()

plt.tight_layout()
plt.show()

# 验证:H(P, Q) = H(P) + D_KL(P||Q)
h_p = entropy(p)
print(f"H(P) = {h_p:.4f}")
print(f"在 Q=P 时: H(P,Q) - D_KL = {ce_vals[np.argmin(np.abs(q_vals - 0.9))]:.4f} - {min(kl_vals):.4f} ≈ {h_p:.4f}")

7. 多分类交叉熵的向量化实现(批量处理)

python 复制代码
def batch_categorical_cross_entropy(y_true, y_pred, eps=1e-15):
    """
    y_true: shape=(N, C), one-hot
    y_pred: shape=(N, C), 概率分布
    返回: 平均损失
    """
    y_pred = np.clip(y_pred, eps, 1 - eps)
    losses = -np.sum(y_true * np.log(y_pred), axis=1)
    return np.mean(losses)

# 测试批量
N, C = 32, 10
y_true_batch = np.eye(C)[np.random.choice(C, N)]  # 随机 one-hot 标签
y_pred_batch = np.random.dirichlet([1]*C, size=N)  # 随机概率 simplex

loss_batch = batch_categorical_cross_entropy(y_true_batch, y_pred_batch)
print(f"批量交叉熵损失: {loss_batch:.4f}")

六、高级话题:交叉熵与最大似然估计(MLE)

定理:最小化交叉熵 ⇨ 最大化对数似然

设数据集 {(x_i, y_i)}_{i=1}\^N ,模型输出 P(y \\mid x; \\theta)

  • 对数似然
    L ( θ ) = ∑ i = 1 N log ⁡ P ( y i ∣ x i ; θ ) \mathcal{L}(\theta) = \sum_{i=1}^N \log P(y_i \mid x_i; \theta) L(θ)=i=1∑NlogP(yi∣xi;θ)
  • 平均交叉熵损失
    J ( θ ) = − 1 N ∑ i = 1 N log ⁡ P ( y i ∣ x i ; θ ) = − 1 N L ( θ ) \mathcal{J}(\theta) = -\frac{1}{N} \sum_{i=1}^N \log P(y_i \mid x_i; \theta) = -\frac{1}{N} \mathcal{L}(\theta) J(θ)=−N1i=1∑NlogP(yi∣xi;θ)=−N1L(θ)

✅ 因此:最小化交叉熵 = 最大化似然 → 模型学习真实条件分布


七、总结

概念 公式 在 ML 中的角色
交叉熵 H(P, Q) -\\sum P \\log Q 分类任务的标准损失函数
KL 散度 D_{\\text{KL}}(P \\parallel Q) \\sum P \\log(P/Q) 衡量预测分布与真实分布的差异
关系 H(P, Q) = H§ + D_{\\text{KL}}(P \\parallel Q) 优化交叉熵 ⇨ 逼近距离最小化
分类损失 -\\log Q(y_{\\text{true}}) 只惩罚真实类别的预测置信度

💡 关键洞见

  • 交叉熵是 KL 散度的"可优化部分"(因 ( H§ ) 与模型无关);
  • 深度学习分类器本质上是在拟合条件概率分布
  • 不要对分类任务使用 MSE------它缺乏概率解释且梯度不佳;
  • 低交叉熵 ≠ 高准确率(可能过拟合或校准差),但它是优化的正确方向。

后续

python过渡项目部分代码已经上传至gitee,后续会逐步更新。

资料关注

公众号:咚咚王

gitee:https://gitee.com/wy18585051844/ai_learning

《Python编程:从入门到实践》

《利用Python进行数据分析》

《算法导论中文第三版》

《概率论与数理统计(第四版) (盛骤) 》

《程序员的数学》

《线性代数应该这样学第3版》

《微积分和数学分析引论》

《(西瓜书)周志华-机器学习》

《TensorFlow机器学习实战指南》

《Sklearn与TensorFlow机器学习实用指南》

《模式识别(第四版)》

《深度学习 deep learning》伊恩·古德费洛著 花书

《Python深度学习第二版(中文版)【纯文本】 (登封大数据 (Francois Choliet)) (Z-Library)》

《深入浅出神经网络与深度学习+(迈克尔·尼尔森(Michael+Nielsen)》

《自然语言处理综论 第2版》

《Natural-Language-Processing-with-PyTorch》

《计算机视觉-算法与应用(中文版)》

《Learning OpenCV 4》

《AIGC:智能创作时代》杜雨+&+张孜铭

《AIGC原理与实践:零基础学大语言模型、扩散模型和多模态模型》

《从零构建大语言模型(中文版)》

《实战AI大模型》

《AI 3.0》

相关推荐
Trent19852 小时前
影楼精修-眼镜祛反光算法详解
图像处理·人工智能·算法·计算机视觉·aigc
吾在学习路2 小时前
【CVPR 2018最佳论文】Squeeze-and-Excitation Networks
人工智能·深度学习·神经网络·机器学习
小黄人软件2 小时前
豆包AI手机是未来所有带屏设备的方向,包括POS机。豆包AI手机需要很强的本地算力吗?不需要。
人工智能·智能手机
Salt_07282 小时前
DAY 47 Tensorboard的使用介绍
人工智能·python·深度学习·机器学习
木卫二号Coding2 小时前
第七十篇-ComfyUI+V100-32G+运行SD3.5-文生图
人工智能
Salt_07283 小时前
DAY 40 早停策略和模型权重的保存
人工智能·python·算法·机器学习
码农小白猿3 小时前
IACheck优化电梯定期检验报告:自动化术语审核提升合规性与效率
大数据·运维·人工智能·ai·自动化·iacheck
点云SLAM3 小时前
Absence 英文单词学习
人工智能·英文单词学习·雅思备考·absence·缺席 / 不在场·缺乏 / 缺失