AI 工程基础体系 · 第 38/100 篇。内容覆盖机器学习、深度学习与生成式 AI;模型、数据、评测、权限和成本会作为同一生产系统处理。
AI 信息论基础:熵、交叉熵、KL 散度、互信息与编码直觉
信息论研究的是“不确定性如何被表示、传输和消除”。在机器学习中,它并不是一组只用于考试的公式:
- 熵描述数据或随机变量本身有多不确定;
- 交叉熵描述用概率模型 表示真实分布 时,平均需要付出多少信息代价;
- KL 散度描述模型分布与真实分布之间的额外代价;
- 互信息描述一个变量知道另一个变量后,不确定性减少了多少;
- 编码直觉把这些量连接到压缩、预测、分类损失、语言模型困惑度和生成式 AI 的 token 概率。
理解这些概念前,需要先固定概率分布、对数和期望的含义。
1. 概率分布与信息量
设离散随机变量 的取值集合为 ,概率分布为
满足:
如果 的某个结果概率很高,它并不令人意外;如果结果概率很低,它包含的信息通常更多。因此单个结果的信息量定义为:
这里的对数底数决定单位:
- :单位是 bit;
- :单位是 nat;
- :单位是 hartley,机器学习中较少使用。
概率越小, 越大。例如使用 bit:
确定会发生的事件不提供新信息;而
表示这个结果需要约 10 bit 来描述。
信息量具有可加性。若两个事件独立,则:
这也是对数在信息论中自然出现的原因。
2. 熵:随机变量平均有多少不确定性
2.1 离散熵的定义
离散随机变量 的熵定义为信息量的期望:
熵不是某一次观测的信息量,而是长期重复观测时的平均信息量。
例如,公平硬币:
使用 bit:
这表示每次投掷平均需要 1 bit 描述结果。
对于必然为正面的硬币:
有:
其中约定 ,因为:
确定结果没有不确定性,也不需要额外编码。
2.2 熵的范围与最大值
如果 有 个可能取值,则:
当且仅当所有结果等概率时取得最大值:
可以用 KL 散度证明这一点。设均匀分布为 ,则:
展开:
由于 KL 散度非负:
等号成立的条件是 。
这说明“类别越多”不自动意味着“熵越高”。类别数量只给出上界,真正的熵还取决于概率是否均匀。
2.3 一个完整算例:偏置硬币
设硬币正面概率为 ,反面概率为 。使用 bit:
虽然每次仍有两个可能结果,但由于正面高度可预测,平均信息量只有约 bit,而不是公平硬币的 1 bit。
注意:单次出现反面时的信息量为:
这大于正面出现时的:
熵是平均值,不能与某个具体样本的信息量混淆。
3. 条件熵:知道部分信息后还剩多少不确定性
对两个离散随机变量 ,条件熵定义为:
它表示已经知道 后, 平均还剩多少不确定性。
联合熵为:
利用联合概率分解:
可得链式法则:
因此:
在经典离散概率中,知道更多变量不会增加剩余不确定性:
但这句话只适用于条件熵的正确概率定义。工程中如果用有限样本估计熵,采样噪声可能导致估计值违反直觉,例如估计出的条件熵略高于边际熵。
4. 交叉熵:用 描述来自 的数据
4.1 定义
设真实分布为 ,模型使用分布 。交叉熵定义为:
关键区别是:
- 熵 使用真实概率 编码真实分布;
- 交叉熵 使用模型概率 编码来自真实分布 的样本。
如果模型给真实事件很低的概率, 会很大,损失也会很大。
4.2 交叉熵与分类损失
在 分类问题中,真实标签是 ,模型输出概率为:
如果标签使用 one-hot 向量 ,即正确类别 的概率为 1,其余为 0,则单个样本的交叉熵为:
因此常见的分类交叉熵损失,本质上就是正确类别负对数概率。
例如三分类样本的真实类别为第 2 类:
模型预测:
则:
如果模型预测为:
虽然最大概率类别可能是第 3 类,且分类结果错误,但更重要的是正确类别概率只有 ,损失为:
交叉熵因此不仅关注“猜对或猜错”,还惩罚错误的置信度。一个极度自信但错误的模型,损失会非常大。
4.3 从 logits 推导 softmax 交叉熵
神经网络通常输出 logits:
而不是直接输出概率。softmax 定义为:
真实类别为 时:
这就是常说的 log-sum-exp 形式。
对某个 logit 求导:
其中 在 时为 1,否则为 0。于是:
- 正确类别的梯度为 ,会推动 增大;
- 错误类别的梯度为 ,会推动其 logit 减小。
这解释了交叉熵为什么适合训练分类模型。
实际实现通常应直接使用框架提供的“带 logits 的交叉熵”接口,而不是先手动 softmax 再取 log。原因是:
可能溢出,而 log-sum-exp 可以通过减去最大 logit 稳定计算:
4.4 数据集交叉熵
对 个样本,经验交叉熵通常为:
这也是平均负对数似然。最小化它等价于最大化训练数据的平均对数似然:
这只是训练目标的等价变形,并不表示模型已经学到了真实世界分布。训练集偏差、标签噪声、分布偏移和数据泄漏仍然会影响结果。
5. KL 散度:模型相对真实分布多付出的代价
5.1 定义与交叉熵分解
KL 散度定义为:
将对数拆开:
因此:
这个等式是机器学习中最重要的关系之一:
- 是数据本身不可避免的平均信息量;
- 是模型不准确造成的额外代价;
- 交叉熵是二者之和。
由于 Gibbs 不等式:
所以:
当且仅当 时取等号。
5.2 支持集条件与无限损失
如果存在某个事件 ,满足:
则:
交叉熵同样为无穷大,因为真实会发生的事件被模型赋予了零概率。
这在生成式 AI 中尤其重要。一个语言模型如果对真实数据中会出现的 token 给出严格零概率,那么理论上的负对数似然会无限大。实际 softmax 在有限 logits 下通常产生严格正概率,但:
- 词表裁剪;
- 硬过滤;
- 不正确的 token mask;
- 解码阶段禁止某些 token;
都可能让某些真实序列变得不可表示。
训练和评测时,不能把“生成阶段的硬约束”直接当成无条件概率模型,否则可能破坏似然计算。
5.3 KL 不是距离
KL 散度常被称为“分布距离”,但它不是严格的距离,因为通常:
例如:
使用 nat:
反向计算:
方向不能省略。
更直接的反例是:
则:
但:
因为反向 KL 会访问 支持的第二个事件,而 对该事件赋予了零概率。
5.4 为什么不同方向会产生不同模型行为
最小化:
时,期望是在真实分布 下计算的。真实分布支持的区域都必须被 覆盖,否则会产生很大甚至无限的惩罚。这通常被描述为偏向“覆盖多个模式”。
最小化:
时,期望是在模型分布 下计算的。模型可以把概率集中到某个高密度模式,避开真实分布低概率区域,因此常表现出“偏向单个模式”的行为。
但“mode-cover”和“mode-seeking”是常见优化直觉,不是对所有参数化模型和优化过程的绝对定理。模型容量、目标函数、近似误差和优化算法都会影响最终行为。
5.5 机器学习中的 KL 用法
知识蒸馏中,教师模型给出软分布 ,学生模型输出 ,可以最小化:
这会让学生不仅学习硬标签,还学习教师对“其他类别”的相对判断。
变分自编码器中,常见目标包含:
它约束编码器产生的潜变量分布不要偏离先验过远。这里的方向是模型设计的一部分,不能随意交换。
分布漂移检测中,可以比较时间窗口或人群切片的离散分布。但直接使用 KL 前必须处理零计数、平滑和样本量问题,否则一个未观测类别就可能导致无穷大或极不稳定的结果。
6. 互信息:一个变量能减少另一个变量多少不确定性
6.1 定义
随机变量 的互信息定义为:
利用链式法则,也可以写成:
还可以写成联合分布与独立分布之间的 KL 散度:
展开:
因此:
且当且仅当:
也就是 独立时,互信息为 0。
互信息是对称的:
这与 KL 散度的非对称性不同。
6.2 完整算例:完全相关与独立变量
设 都是公平二值变量。
情形一:
联合分布只有两个可能结果:
由于知道 后就完全知道 :
而 bit,因此:
这表示 完整解释了 的不确定性。
情形二: 独立
四种组合概率均为 。知道 不会改变 的分布:
所以:
6.3 互信息不等于相关系数
线性相关系数只刻画特定的线性关系,而互信息刻画一般依赖关系。
一个重要例子是 XOR:
对单独的 或 ,都有:
因为只知道其中一个输入, 仍然等可能为 0 或 1。
但联合知道 后, 完全确定:
因此“每个特征单独与标签互信息低”并不意味着“这些特征组合后没有预测能力”。这也是单变量特征筛选可能漏掉交互特征的原因。
6.4 互信息与特征、表示和生成模型
在特征选择中,可以估计:
筛选与标签相关的特征。但高互信息不等于因果关系,也不等于部署后稳定。一个特征可能通过时间泄漏、用户 ID 或权限范围外的数据获得很高互信息,却无法在真实预测时使用。
在表示学习中,常见目标是让表示 保留任务相关信息:
同时限制不希望保留的信息,例如敏感属性 :
不过这些量通常难以直接准确估计,实际方法依赖变分上界、对比学习目标或分类器近似。近似目标下降,不自动证明真实互信息已经按同样幅度下降。
在生成模型中,条件生成分布为:
条件 是否有用,可以从不确定性减少来理解:
如果条件信息与目标无关,理想模型不会因为它而显著降低预测熵;如果条件包含关键信息,条件分布会比无条件分布更集中。
7. 编码直觉:为什么这些公式等于“平均描述长度”
7.1 前缀编码与 Kraft 不等式
考虑二进制前缀码。前缀码要求一个码字不能是另一个码字的前缀,这样接收方才能无歧义地解码。
若每个事件 的码长为 ,Kraft 不等式要求:
对于概率 ,理想码长是:
但它不一定是整数。实际可以取:
其期望码长满足:
其中 表示使用 bit 的熵。
含义是:已知真实分布后,长期平均编码长度可以接近熵,但单个码字必须是整数长度,通常会产生少量舍入开销。
严格地说,经典结论通常针对无失真前缀编码和足够长的独立同分布序列;单个样本、有限块长和具体编码器可能有额外开销。
7.2 用错误分布编码:交叉熵是平均码长
假设数据真实来自 ,但编码器按 设计理想码长:
那么真实平均码长为:
结合分解式:
因此,错误模型造成的额外平均码长就是:
这不是比喻,而是概率建模与通用编码之间的数学对应。
7.3 自回归语言模型与 token 编码
对 token 序列 ,链式法则给出:
取负对数:
所以语言模型的 token 级交叉熵,就是序列总负对数似然,也可以理解为在已知前文时逐 token 编码的总平均代价。
如果平均每个 token 的交叉熵是 nat,则困惑度定义为:
如果交叉熵用 bit,则:
困惑度不是“模型知道的词汇数量”,而是指数化的平均 token 预测不确定性。不同 tokenizer、文本切分、数据领域和评测集合之间的困惑度通常不能直接横向比较。
8. 交叉熵、准确率与校准的差异
准确率只观察:
而交叉熵观察正确类别的完整概率 。
考虑两个预测:
如果第一类是真实标签,二者准确率都为 1,但损失分别为:
和:
第二个模型不仅预测正确,而且更确信;在大量样本上,交叉熵会奖励这种概率质量。
反过来,如果第二个预测在真实标签为第二类时出错,其损失为:
这说明交叉熵对过度自信的错误非常敏感。
校准描述预测概率是否具有频率意义。例如,模型对许多样本都预测“置信度约 0.8”,如果这些样本实际约 80% 正确,则模型较校准。交叉熵通常能反映概率质量,但单独一个交叉熵数值不能完整诊断校准,仍需结合可靠性图、分桶统计或 Brier score 等指标。
9. 标签平滑、软标签与交叉熵
硬标签的真实分布为 one-hot:
标签平滑会改为:
此时损失为:
它不再要求模型把全部概率集中到一个类别,通常可以降低过度自信。
但标签平滑不是无条件改进:
- 如果标签本来非常准确,过度平滑可能限制可达到的概率质量;
- 如果类别极不平衡,均匀分配平滑质量可能不符合真实先验;
- 训练目标改变后,训练交叉熵与原始 one-hot 评测损失不再完全对应。
软标签还可以来自教师模型、人类分布式标注或多答案数据。此时交叉熵更接近拟合一个条件分布,而不是拟合唯一“正确类别”。
10. 生成式 AI 中的条件概率、采样与信息量
10.1 训练损失与生成结果不是同一件事
语言模型训练通常最小化:
这要求模型为真实训练 token 分配高概率。
生成时却通常从模型分布采样,或使用贪心、beam search、top-、top- 等解码策略。解码会改变实际输出分布,因此:
- 训练交叉熵评估的是模型对参考序列的概率;
- 生成质量还受搜索策略、重复惩罚、停止条件和安全过滤影响;
- 低困惑度不保证事实正确、风格合适或满足权限约束。
如果生成系统在运行时截断候选 token,它实际采样的分布可能是重归一化后的分布,而不是原始模型分布。分析成本、质量和安全行为时,需要区分模型分布与解码后分布。
10.2 温度如何改变熵
给定 logits ,温度 的分布为:
- :分布更平,熵通常增加;
- :分布更尖,熵通常降低;
- :趋向于最大 logit 的贪心选择;
- :趋向于均匀分布。
“熵通常增加或降低”需要限定为改变温度的典型 softmax 情况;如果叠加候选截断、过滤或特殊约束,最终分布还取决于这些操作。
11. 一个可运行的 NumPy 示例
下面代码实现离散熵、交叉熵、KL 散度和互信息,并验证关键等式。前置条件是 Python 3 和 NumPy。
import numpy as np
def normalize(p):
p = np.asarray(p, dtype=float)
if np.any(p < 0):
raise ValueError("probabilities must be non-negative")
total = p.sum()
if total <= 0:
raise ValueError("probabilities must have positive sum")
return p / total
def entropy(p, base=np.e):
p = normalize(p)
positive = p > 0
value = -np.sum(p[positive] * np.log(p[positive]))
return value / np.log(base)
def cross_entropy(p, q, base=np.e):
p = normalize(p)
q = normalize(q)
if np.any((p > 0) & (q <= 0)):
return np.inf
positive = p > 0
value = -np.sum(p[positive] * np.log(q[positive]))
return value / np.log(base)
def kl_divergence(p, q, base=np.e):
return cross_entropy(p, q, base) - entropy(p, base)
def mutual_information(joint, base=np.e):
joint = np.asarray(joint, dtype=float)
if np.any(joint < 0) or joint.sum() <= 0:
raise ValueError("joint distribution must be non-negative and non-empty")
joint = joint / joint.sum()
px = joint.sum(axis=1, keepdims=True)
py = joint.sum(axis=0, keepdims=True)
product = px @ py
positive = joint > 0
value = np.sum(joint[positive] * np.log(
joint[positive] / product[positive]
))
return value / np.log(base)
p = np.array([0.9, 0.1])
q = np.array([0.5, 0.5])
print("H(p) =", entropy(p, base=2), "bits")
print("H(p, q) =", cross_entropy(p, q, base=2), "bits")
print("KL(p || q) =", kl_divergence(p, q, base=2), "bits")
print("check =", entropy(p, base=2) + kl_divergence(p, q, base=2))
joint = np.array([
[0.5, 0.0],
[0.0, 0.5],
])
print("I(X;Y) =", mutual_information(joint, base=2), "bits")
对于前面的偏置硬币和均匀模型,输出应接近:
H(p) = 0.4689955935892812 bits
H(p, q) = 1.0 bits
KL(p || q) = 0.5310044064107188 bits
check = 1.0
I(X;Y) = 1.0 bits
这里的 check 验证:
joint 矩阵中只有 和 有概率,表示 ,所以互信息为 1 bit。
代码中对 p=0 的项进行了跳过,这是数学约定 的实现。对于 q=0 且 p>0 的情况,函数返回无穷大,而不是静默加一个很小的数;生产代码若使用平滑,应明确记录平滑策略,因为它会改变被评估的分布。
12. 连续变量:微分熵不能简单照搬离散熵
对于连续随机变量,概率质量函数被概率密度 替代。微分熵定义为:
它与离散熵有相似形式,但性质不同:
- 微分熵可以为负;
- 它依赖坐标单位;
- 对连续变量做可逆变换时不保持不变;
- 它不直接等于有限比特的无损编码长度。
例如把长度单位从米改成毫米,密度会发生缩放,微分熵也会随之变化。因此不能把连续变量的微分熵直接解释为“这个物理量需要多少 bit”。
连续分布之间的 KL 散度仍然定义为:
它具有非负性,并且在适当条件下具有坐标变换不变性。连续变量互信息也仍可写作:
这也是为什么在表示学习和变分推断中,KL 与互信息通常比单独的微分熵更稳健、更有解释力。
13. 估计这些量时最容易出错的地方
13.1 对数底数不一致
用 得到 nat,用 得到 bit:
如果训练损失用 nat,却拿它直接和 bit 形式的熵比较,数值会相差约 或其倒数。比较论文、模型或服务指标时必须注明单位。
13.2 平均方式不一致
token 级交叉熵可能按:
- 所有有效 token 平均;
- 每条序列先平均,再对序列平均;
- 包含或排除 padding;
- 按字符、词、token 统计。
这些定义不相同。尤其在序列长度差异很大时,“每条序列等权”和“每个 token 等权”会产生不同结果。
13.3 用 argmax 概率代替完整分布
互信息、KL 和交叉熵都依赖完整概率分布。把模型输出只保留最大类别,会丢失不确定性结构。
例如:
argmax 结果相同,但熵、交叉熵和校准行为完全不同。
13.4 有限样本互信息估计偏差
如果 的类别很多而样本很少,联合频数表会非常稀疏。直接用经验频率计算互信息可能:
- 高估或低估真实依赖;
- 对偶然共现非常敏感;
- 产生大量零概率;
- 在切分数据后不稳定。
连续高维变量的互信息估计更困难,常见方法包括离散化、核密度、近邻估计和神经估计器,但每种方法都有偏差、方差或优化稳定性问题。互信息估计值下降时,必须同时检查样本量、估计器和随机种子,不能只看一个数字。
13.5 训练集交叉熵低不等于泛化好
训练交叉熵下降表示模型提高了对训练样本的概率分配,但可能发生:
- 记忆训练样本;
- 标签泄漏;
- 训练和验证分布不同;
- 评测文本出现在预训练数据中;
- 数据切分跨越同一用户、同一文档或同一时间实体。
生产评测应明确数据来源、时间切分、用户隔离、权限边界和去重策略。否则一个很低的交叉熵可能只是数据泄漏的结果。
14. 从信息量到生产系统:模型、数据、评测、权限与成本
信息论指标不能脱离生产系统解释。
14.1 数据权限会改变可用分布
如果某类数据只有特定用户或租户有权访问,那么训练和评测时使用这类数据不仅是数据问题,也是权限问题。即使它显著降低预测熵或提高互信息,也不能据此绕过访问控制。
对于检索增强生成系统,实际条件分布更接近:
而不是:
把无权访问的上下文加入训练、日志或离线评测,可能让交叉熵变低,却使线上系统违反权限约束。
14.2 token 熵不等于 token 成本
语言模型的 token 数量直接影响推理成本、延迟和上下文占用;token 熵描述的是预测不确定性。两者相关但不等价:
- 长文本可能每个 token 都很容易预测,但成本仍然高;
- 短文本可能存在高不确定性,但 token 成本不一定高;
- 采样策略改变输出长度和重复率,也会改变成本;
- 缓存、批处理、模型大小和服务商计费规则会进一步影响总成本。
因此生产监控至少要区分:
不能用困惑度或熵单独替代成本指标。
14.3 不确定性不能直接当成风险概率
高熵表示模型分布更分散,低熵表示模型更集中,但低熵不代表答案真实。模型可能对错误事实非常自信。
风险评估需要结合:
- 事实核验;
- 任务特定准确率;
- 置信度校准;
- 拒答和升级策略;
- 权限与审计;
- 对抗和分布外测试。
信息论指标描述概率结构,不自动提供因果、事实性或合规保证。
15. 一张关系图
flowchart LR
P["真实分布 p"] --> H["熵 H(p)<br/>真实不确定性的平均信息量"]
P --> CE["交叉熵 H(p,q)<br/>用 q 编码来自 p 的数据"]
Q["模型分布 q"] --> CE
CE --> Decomp["H(p,q) = H(p) + KL(p || q)"]
P --> KL["KL 散度<br/>模型造成的额外编码代价"]
Q --> KL
X["变量 X"] --> MI["互信息 I(X;Y)<br/>知道一个变量后减少的不确定性"]
Y["变量 Y"] --> MI
MI --> MI2["I(X;Y)=KL(p(x,y) || p(x)p(y))"]
CE --> CLS["分类交叉熵<br/>-log q(y|x)"]
CE --> LM["语言模型 NLL<br/>sum_t -log q(x_t|x_<t)"]
LM --> PPL["困惑度<br/>exp(平均 NLL)"]
图中的核心路径是:
- 真实分布自身有熵;
- 模型用 预测真实样本时产生交叉熵;
- 交叉熵比真实熵多出的部分是 KL 散度;
- 互信息则把“联合分布是否偏离独立分布”表示成 KL 散度;
- 分类和语言建模损失都是交叉熵在不同输出结构下的具体形式。
16. 最容易混淆的结论
熵不是准确率。
熵描述整个概率分布的不确定性;准确率只看最大概率类别是否正确。
交叉熵不是熵。
只有当 时,交叉熵才等于真实熵。一般情况下:
KL 散度不是对称距离。
写出 时,必须说明谁是真实分布、谁是近似分布。
互信息为零表示独立,而不是“没有线性相关”。
它检测的是一般统计依赖;零互信息比零相关更强。
低损失不保证可靠。
损失可能因数据泄漏、权限越界、评测分布过窄或模型过度自信而虚假变好。
困惑度依赖 tokenizer 和评测协议。
不同 token 粒度、文本过滤和平均方式下,数值不能直接比较。
把这些概念统一起来,可以得到一个简洁框架:
这组关系构成了从概率预测、分类训练、语言模型评测,到压缩、表示学习和生成式 AI 的共同数学基础。
系列导航与关联阅读
- 系列入口:AI 工程完整学习路线:从机器学习与 Transformer 到 RAG、Agent 和生产治理
- 上一篇:AI 优化基础:凸性、梯度下降、约束、鞍点与收敛判断
- 下一篇:AI 数值计算:浮点误差、稳定性、向量化、条件数与精度选择
官方资料
本文依据研究论文、标准组织与主流框架官方文档重新梳理;正文、示例与工程清单由 WR BLOG 编写。

评论
0 条讨论