交叉熵:从gzip压缩到“压缩即智能“

交叉熵:从gzip压缩到"压缩即智能"

小可(眼睛瞪大):仅用gzip压缩,就能发现不同语言之间的关系?这太不可思议了吧!

博博(自信地微笑):没错!把文档A压缩后附加B的小段,看压缩效果就能判断相似度。这是25年前就有人做到的事情------不需要任何语言学知识,纯粹靠信息论的力量。


这篇论文展示了一个令人震惊的事实:我们只需要使用非常通用的文件压缩技术,就能在不同语言之间发现结构关系。给定一堆来自不同语言的文本文档,你的任务是自动根据语言对它们进行分类和聚类------甚至更进一步,找出哪些语言关系最密切,并重新发现它们之间的共享谱系树。

而这一切,只需要你编写一个处理每个文本的函数。没有现成的语言学知识可用。不需要知道什么是"日耳曼语族",不需要知道"印欧语系"这个概念,甚至不需要知道这些文本使用的是拉丁字母还是西里尔字母。算法完全从零开始,只依靠数据本身携带的信息。

当时要记住,这已经是将近四分之一世纪前的事了。那时候还完全没有现代语言模型可用。没有Transformer架构,没有BERT,没有GPT。令人惊讶的是,作者展示了只需使用gzip压缩------就是你每天在电脑上用的那个压缩工具------就能做到这一切。

这背后的原理是什么?为什么一个简单的压缩算法能够"理解"语言之间的亲缘关系?答案就在于信息论中最深刻的概念之一:交叉熵。让我们从这个看似简单的实验开始,一步步深入理解交叉熵的本质。


核心思路:联合压缩的力量

小可(若有所思):那具体要怎么做呢?在没有语言学知识的情况下?

博博(耐心解释):你的任务是自动根据语言对文本文档进行分类和聚类。这听起来是个典型的NLP任务,对吧?但作者的解法完全不同。

小可(感慨):这已经是四分之一世纪前的事了,那时候可没有大模型!

博博(点头):正因如此,这个思路才显得格外巧妙和启发人心。它不依赖任何复杂的神经网络或预训练语言模型,只用了最基础的信息论工具。


gzip压缩的工作原理

让我们先理解gzip是怎么工作的。gzip是一种广泛使用的通用文件压缩算法,它基于两个核心技术的组合:LZ77算法和霍夫曼编码。

LZ77算法的核心思想是:如果一段文本中之前出现过某个字符串,那么当它再次出现时,可以用一个"向后引用"来替代它。比如,在文本"the cat sat on the mat"中,第二次出现的"the"可以用"回到前面9个字符,复制3个字符"来代替。这样就用更少的信息表达了相同的内容。LZ77实际上是在寻找文本中的重复模式------它本质上是一种字典压缩方法,只不过字典是动态构建的,基于已经处理过的文本。

LZ77使用一个"滑动窗口"来跟踪已经处理过的文本。窗口的大小决定了它能记住多远之前的内容------gzip的默认窗口大小是32KB。这意味着如果两个相同的字符串之间的距离超过32KB,LZ77就无法发现它们的重复性。这个限制也解释了为什么gzip对短文本的压缩效果通常不如对长文本好:短文本中可发现的重复模式更少。

霍夫曼编码则是在LZ77的基础上进一步优化。LZ77产生的输出仍然是一系列符号(字面字符和引用),这些符号的出现频率不同。霍夫曼编码为出现频率高的符号分配较短的二进制编码,为出现频率低的符号分配较长的编码。这样,整个输出的平均比特数就进一步降低了。

霍夫曼编码的构建过程非常优雅:首先统计所有符号的出现频率,然后将频率最低的两个符号合并为一个新节点,重复这个过程直到所有符号合并为一棵二叉树。从根节点到每个叶子节点的路径就是该符号的编码------左分支为0,右分支为1。这样构建出来的编码天然就是前缀码。

gzip的压缩流程可以总结为以下步骤:

  1. 读取输入数据到滑动窗口
  2. LZ77扫描窗口,寻找最长匹配,输出(距离, 长度)对或字面字符
  3. 对LZ77的输出进行霍夫曼编码
  4. 添加必要的头部和校验信息
  5. 输出压缩后的字节流

这个流程中,LZ77负责"发现"模式,霍夫曼编码负责"编码"模式。两者结合,使得gzip能够在不需要任何领域知识的情况下,对任意类型的文件进行有效压缩。

关键在于:gzip的压缩效果取决于文本中的重复模式。如果两段文本具有相似的语言模式(比如都使用英语),那么将它们放在一起压缩时,gzip可以利用第一段文本中学到的模式来更有效地压缩第二段文本。


小可(眼睛一亮):让我想想,把A和B一起压缩,然后比较大小?

博博(赞许):对!比较压缩(A+B)与仅压缩(A)的差异。这就是整个方法的核心。


差异的含义

小可(好奇地歪头):这个差异告诉了我们什么呢?

博博(认真地):它告诉你:当压缩器主要针对A优化时,B的文本能被压缩得多好。

这个差异可以这样理解:当你先用文档A的内容"训练"压缩器(即让压缩器针对A的重复模式进行优化),然后再用这个压缩器去压缩B的一小段。如果B与A使用相同的语言模式,那么压缩器对A学到的模式同样适用于B,因此B的压缩效果会比较好------差异就小。反之,如果B与A使用完全不同的语言,压缩器学到的模式对B几乎没用,差异就大。

让我们用具体数字来理解。假设A是一篇英文文档(10000字节),B是一篇法文文档(5000字节):

  • 单独压缩A:S(A) = 4000字节
  • 单独压缩B:S(B) = 2500字节
  • 联合压缩A+B:S(A+B) = 6200字节
  • 差异:Δ = S(A+B) - S(A) = 6200 - 4000 = 2200字节

也就是说,当压缩器已经"学会"了英文的模式后,再压缩法文文本只需要额外2200字节(而不是单独压缩法文需要的2500字节)。这300字节的节省,就是英文和法文之间的共同模式带来的好处。

如果B是一篇中文文档呢?由于中文使用完全不同的字符集和语法结构,压缩器从英文中学到的模式几乎对中文没有用:

  • 联合压缩A(英文)+B(中文):S(A+B) ≈ 4000 + 3000 = 7000字节
  • 差异:Δ = 7000 - 4000 = 3000字节

差异更大,说明两种语言的关系更远。这就是整个方法的核心直觉。

让我们再看一个更精细的例子。假设我们有三篇文档:

  • A:英文《哈利·波特》第一章节选
  • B1:英文《指环王》第一章节选
  • B2:法文《小王子》第一章节选
  • B3:中文《西游记》第一章节选

分别计算差异:

  • Δ(A, B1) = S(A+B1) - S(A) ≈ 2100字节(同为英文,共享词汇和语法模式)
  • Δ(A, B2) = S(A+B2) - S(A) ≈ 2600字节(同属印欧语系,有部分共同词源)
  • Δ(A, B3) = S(A+B3) - S(A) ≈ 3200字节(完全不同语系,字符集和语法截然不同)

这个例子清楚地展示了距离度量如何反映语言之间的亲缘关系。英文-英文差异最小,英文-法文居中,英文-中文差异最大。


小可(恍然大悟):所以B与A越相似,差异就越小?

博博(微笑):完全正确!当差异更大时说明B与A的语言模式差距很大。


定义距离度量

小可(兴奋):作者用它定义了一个特殊的度量标准?

博博(讲解):是的,仅基于共同压缩效果来衡量两个文档之间的距离。

作者将这个思路形式化为一个距离度量。具体来说,给定两个文档A和B,定义它们之间的距离为:

d(A,B)=S(A,B)−S(A)d(A,B) = S(A,B) - S(A)d(A,B)=S(A,B)−S(A)

其中 S(A,B)S(A,B)S(A,B) 表示将A和B拼接后一起压缩得到的文件大小,S(A)S(A)S(A) 表示仅压缩A得到的文件大小。

这个度量有一个重要的不对称性:d(A,B)d(A,B)d(A,B) 不一定等于 d(B,A)d(B,A)d(B,A)。因为压缩器先"学习"A的模式再压缩B,和先学习B的模式再压缩A,效果是不同的。为了得到一个对称的距离度量,作者定义了一个归一化版本:

NCD(A,B)=S(A,B)−min⁡(S(A),S(B))max⁡(S(A),S(B))NCD(A,B) = \frac{S(A,B) - \min(S(A), S(B))}{\max(S(A), S(B))}NCD(A,B)=max(S(A),S(B))S(A,B)−min(S(A),S(B))

这个归一化压缩距离(Normalized Compression Distance)取值范围大致在0, 1之间。0表示两个文档完全相同(联合压缩没有额外开销),1表示两个文档完全没有共同模式。

为什么需要归一化?

原始距离 d(A,B)=S(A,B)−S(A)d(A,B) = S(A,B) - S(A)d(A,B)=S(A,B)−S(A) 有一个问题:它对文档的绝对大小很敏感。一个大文档和一个小文档的压缩差异,天然就会比两个小文档之间的差异大。归一化通过除以较大的文件大小,消除了这种尺度效应,使得不同大小的文档之间可以公平比较。

NCD的数学性质

虽然NCD不是一个严格的数学度量(它不一定满足三角不等式),但它在实践中表现良好。研究表明,当使用足够好的压缩器时,NCD近似满足度量的三个基本性质:

  1. 非负性 :NCD(A,B)≥0NCD(A,B) \geq 0NCD(A,B)≥0
  2. 对称性 :NCD(A,B)≈NCD(B,A)NCD(A,B) \approx NCD(B,A)NCD(A,B)≈NCD(B,A)(归一化后近似对称)
  3. 自反性 :NCD(A,A)≈0NCD(A,A) \approx 0NCD(A,A)≈0

这个度量的巧妙之处在于它完全是无监督的------不需要任何语言学的先验知识,不需要标注数据,甚至不需要知道这些文本使用的是什么语言。它只依赖于一个基本假设:相似的数据具有相似的可压缩性。


重建语言谱系树

小可(惊叹):居然能重建语言的谱系树?这太神奇了!

博博(自豪):从瑞典语到弗里斯兰语,各种语言的亲缘关系一目了然。

当作者将这个距离度量应用到大量不同语言的文本上时,令人震惊的结果出现了:通过简单的层次聚类算法,他们成功重建了印欧语系的语言谱系树!

具体来说,作者收集了《圣经》的新约部分在多种语言中的翻译版本,然后计算了每对语言之间的NCD值,得到一个距离矩阵。对这个矩阵应用标准的层次聚类算法,就得到了一棵树。

日耳曼语族(英语、德语、瑞典语、荷兰语等)被正确聚类在一起,罗曼语族(法语、西班牙语、意大利语、葡萄牙语等)也被正确归类。斯拉夫语族、凯尔特语族等也各自形成了正确的分支。这些结果与语言学家通过历史比较方法建立的谱系树高度一致。

这意味着什么?意味着信息的压缩模式本身就编码了语言的深层结构关系。即使不使用任何语言学知识,仅通过分析文本的压缩特性,就能"重新发现"语言的演化历史。

这个实验之所以如此令人震撼,是因为它展示了信息论与语言学之间深刻的联系。语言的演化过程本质上是一个信息传递的过程------从祖先到后代,语言的特征被传递、变异和选择。而这些信息传递的痕迹,恰好就编码在文本的可压缩性中。


更广泛的应用

小可(好奇):这个技巧只能用于语言分类吗?

博博(摇头):不止!同样的技巧可以用于其他自然语言任务,意义广泛。

作者指出,这种基于压缩的距离度量可以推广到更广泛的自然语言处理任务中。任何需要衡量文本之间相似性或差异性的场景,都可以考虑使用这种方法:

  • 文本分类:将未知文档与已知类别的文档进行比较,看它与哪类文档的NCD最小
  • 作者识别:比较不同文档之间的压缩距离,识别同一作者的作品
  • 文本相似度:作为传统TF-IDF或词嵌入方法的补充
  • 基因组分析:将DNA序列视为文本,用同样的方法比较不同物种的基因组
  • 音乐分类:将MIDI文件视为符号序列,按风格或时期自动分组

本质上,任何可以用通用压缩器处理的离散序列数据,都可以用NCD来衡量它们之间的信息距离。


小可(激动):我喜欢这篇论文的地方在于,它是纯粹的信息论例子!

博博(赞同):对看似属于机器学习和AI的任务,产生巨大的帮助。

这篇论文的真正价值在于它展示了一个深刻的道理:信息论的基础概念不仅仅是一个数学理论,它在实际问题中可以产生惊人的效果。不需要复杂的深度学习模型,不需要大规模的训练数据,只需要理解信息压缩的本质,就能解决看起来非常困难的问题。

这个例子也引出了一个更深层次的问题:为什么压缩能够揭示语言的结构?答案就在于香农信息论的核心思想------压缩的本质就是发现数据中的规律。一个高效的压缩器必须理解数据的统计结构,而这种理解本身就是一种"智能"的体现。


交叉熵登场

小可(好奇):这个例子背后的概念是什么?

博博(认真地):它叫交叉熵(Cross-Entropy),在信息论中地位重要。

虽然gzip压缩的方法不能完美等同于交叉熵------gzip不是完美的压缩器,远未达到香农极限------但它的核心思想与交叉熵的概念高度相关。交叉熵是信息论中衡量两个概率分布之间差异的核心工具,也是现代机器学习中最重要的概念之一。

让我们更精确地理解这个联系。gzip压缩的大小 S(A)S(A)S(A) 大致正比于文档A的Kolmogorov复杂度------即产生A的最短程序长度。虽然Kolmogorov复杂度是不可计算的,但gzip给出了它的一个实际近似。而Kolmogorov复杂度与信息论中的熵有着深刻的联系:对于从某个概率分布中采样的数据序列,其Kolmogorov复杂度近似等于序列长度乘以该分布的熵。

因此,S(A+B)−S(A)S(A+B) - S(A)S(A+B)−S(A) 这个差异,实际上就是在近似地衡量:用A的统计模式(编码方案)去编码B时,额外需要多少信息量。这正是交叉熵的核心含义。

有趣的是,交叉熵在信息论中有着重要的地位。而更有趣的是,它与某种深度学习模型的核心部分存在着某种深层次的联系。这种联系将在我们深入探讨交叉的本质后变得越来越清晰。


小可(好奇):交叉熵和深度学习有什么关系?

博博(神秘):它是92/93模型不可或缺的核心部分,存在某种深层次联系。

---核心目标是回归基础知识。在前半部分,我们将在压缩的背景下建立交叉熵的基本概念,并通过可视化手段帮助你建立直觉。在后半部分,我们将看到交叉熵如何以一种完全不同的方式出现在一个似乎与压缩无关的领域中------语言模型的训练。

而最终,这两条看似不同的路径将汇聚到一个深刻的洞见上。


小可(惊讶):预训练不再以预测下一个词为核心,而是以压缩为核心?

博博(肯定):是的,这种视角转换让概念更容易理解。

这是一个关键的视角转换。传统上,我们理解语言模型预训练的方式是"预测下一个词"------给定一段文本的前面部分,模型需要预测下一个最可能出现的词。但如果我们从信息论的角度来看,这个过程本质上就是在做压缩:模型学习文本的统计模式,然后用这些模式来更高效地"编码"文本。

"压缩即智能"------这个观点正在深刻地改变我们对语言模型的理解。


信息论基础回顾

小可(思考):我们把信息视为符号序列,类似文本中的字符?

博博(讲解):对,每个符号从某个分布中采样,这些概率揭示了压缩的基本限制。

在信息论中,我们将信息视为符号序列。这些符号可以是文本中的字符、单词、或者是任何离散的单位。每个符号从一个概率分布中采样得到,而这些概率揭示了压缩的基本限制。

克劳德·香农在他的1948年开创性论文《通信的数学理论》中证明了一个深刻的定理:对于一个概率分布,存在一个最优的编码方案,使得每条信息的平均编码长度趋近于该分布的熵。而熵,正是这个分布中固有的信息量。

香农的工作建立了现代信息论的基础。他定义了信息量、熵、信道容量等核心概念,并证明了数据压缩和通信的理论极限。这些概念不仅对通信工程至关重要,也深刻地影响了计算机科学、统计学、物理学乃至生物学。

自然语言的情况极其复杂。英语中每个字母的出现概率不同,字母之间的相关性也很强(比如'q'后面几乎总是跟着'u')。这些概率分布很难精确描述。但我们之前讨论中使用的一个简化例子,能帮助我们理解交叉熵的核心概念。


机器人游走示例

小可(好奇):用机器人游走的例子来理解?

博博(生动描述):向上50%、向下25%、左右各12.5%,每个方向概率不同。

让我们回到之前讨论过的机器人游走例子。想象一个机器人在一个网格上移动,每次移动的指令是一个符号,可能是向上、向下、向左或向右。

这些符号从某个概率分布中采样:向上发送的概率是50%,向下发送的概率是25%,向左和向右各占12.5%。

这个分布可以写成:

P(↑)=12,P(↓)=14,P(←)=18,P(→)=18P(\uparrow) = \frac{1}{2}, P(\downarrow) = \frac{1}{4}, P(\leftarrow) = \frac{1}{8}, P(\rightarrow) = \frac{1}{8}P(↑)=21,P(↓)=41,P(←)=81,P(→)=81

为什么航天机构会这样设定概率?也许是因为任务目标要求机器人更多地向某个方向移动,所以向上的概率被设得最高。无论如何,关键是这个分布是不均匀的------不同的方向有不同的概率。


最优编码方案

小可(计算中):概率高的符号用更少的比特?

博博(确认):向上1比特,向下2比特,左右各3比特,这就是最优编码。

对于这个分布,最优的编码方案是:

方向 概率 编码 比特数 −log⁡2p-\log_2 p−log2p
向上 50% 0 1 1.0
向下 25% 10 2 2.0
向左 12.5% 110 3 3.0
向右 12.5% 111 3 3.0

概率越高的符号分配的比特数越少,这样在平均意义上编码效率最高。这个编码方案是霍夫曼编码的一个经典例子------它是一棵二叉树,左分支为0,右分支为1,叶子节点对应各个符号。

霍夫曼编码的一个重要性质是它是前缀码 :没有任何符号的编码是另一个符号编码的前缀。这保证了解码的唯一性------给定一个比特串,我们可以从左到右唯一地确定每个符号的边界。比如比特串010110可以唯一地解码为↑, ↓, ←

这个编码方案的平均比特数是:

0.5×1+0.25×2+0.125×3+0.125×3=1.75 比特/符号0.5 \times 1 + 0.25 \times 2 + 0.125 \times 3 + 0.125 \times 3 = 1.75 \text{ 比特/符号}0.5×1+0.25×2+0.125×3+0.125×3=1.75 比特/符号

注意,这个值正好等于该分布的熵:

H(P)=−12log⁡212−14log⁡214−18log⁡218−18log⁡218=0.5+0.5+0.375+0.375=1.75H(P) = -\frac{1}{2}\log_2\frac{1}{2} - \frac{1}{4}\log_2\frac{1}{4} - \frac{1}{8}\log_2\frac{1}{8} - \frac{1}{8}\log_2\frac{1}{8} = 0.5 + 0.5 + 0.375 + 0.375 = 1.75H(P)=−21log221−41log241−81log281−81log281=0.5+0.5+0.375+0.375=1.75

这不是巧合------对于这个特定的分布,霍夫曼编码恰好达到了理论最优。


小可(疑惑):比特数和概率之间有什么关系?

博博(推导):信息量 = -log₂§,概率的以二为底负对数。

信息量的公式是:

I(x)=−log⁡2(p(x))I(x) = -\log_2(p(x))I(x)=−log2(p(x))

这个负对数表达式有非常直观的含义。log⁡2\log_2log2 本质上在问:你需要把东西切成一半多少次才能得到特定的数量?当概率 p(x)p(x)p(x) 越小时,−log⁡2(p(x))-\log_2(p(x))−log2(p(x)) 就越大,意味着该事件包含的信息量越多------这很合理,因为越不可能发生的事情发生时带给我们的"惊喜"越大。

让我们看看几个具体的例子:

  • 如果一个事件确定发生(p=1p=1p=1),它的信息量是 −log⁡2(1)=0-\log_2(1) = 0−log2(1)=0。这很合理------确定的事情不发生任何"惊喜",所以不包含任何新信息。
  • 如果抛一枚公平硬币,正面出现的概率是 p=0.5p=0.5p=0.5,信息量是 −log⁡2(0.5)=1-\log_2(0.5) = 1−log2(0.5)=1 比特。这正是我们直觉上理解的"一比特信息"------一个二元选择。
  • 如果一个事件有8种等可能的结果(p=1/8p=1/8p=1/8),信息量是 −log⁡2(1/8)=3-\log_2(1/8) = 3−log2(1/8)=3 比特。这对应于三个二元选择(23=82^3=823=8)。
  • 如果一个事件非常罕见(p=1/1000000p=1/1000000p=1/1000000),信息量是 −log⁡2(1/1000000)≈19.93-\log_2(1/1000000) \approx 19.93−log2(1/1000000)≈19.93 比特。罕见事件发生时确实会带来巨大的"惊喜"。

当然,通常这些数字并不那么整洁。因此信息价值通常不是一个整数,而是一个实数。这意味着我们不能像上面的例子那样简单地将每个符号关联到特定长度的比特串------至少不能精确做到。但平均意义上,最优编码的平均比特数确实趋近于熵。

信息量的可加性也是一个重要性质:如果两个事件是独立的,那么它们同时发生的信息量等于各自信息量之和:

I(x,y)=−log⁡2(p(x)p(y))=−log⁡2p(x)−log⁡2p(y)=I(x)+I(y)I(x,y) = -\log_2(p(x)p(y)) = -\log_2 p(x) - \log_2 p(y) = I(x) + I(y)I(x,y)=−log2(p(x)p(y))=−log2p(x)−log2p(y)=I(x)+I(y)

这个性质保证了信息量的定义在数学上是一致的。


小可(思考):一条完整信息需要多少比特?

博博(总结):所有符号信息量之和,这就是信息内容的完整度。

要编码一条完整的信息------即一个符号序列------我们需要的比特数是所有符号信息量之和:

总比特数=∑iI(xi)=∑i−log⁡2(p(xi))\text{总比特数} = \sum_i I(x_i) = \sum_i -\log_2(p(x_i))总比特数=i∑I(xi)=i∑−log2(p(xi))

这个信息内容的完整度决定了最优编码所需的比特数。当概率分布是 ppp 时,一条信息(符号序列)的期望比特数就是该分布的熵:

H(p)=Ep−log⁡2p(x)=∑xp(x)⋅(−log⁡2p(x))H(p) = \mathbb{E}_p-\\log_2 p(x) = \sum_x p(x) \cdot (-\log_2 p(x))H(p)=Ep−log2p(x)=x∑p(x)⋅(−log2p(x))

熵有几个重要的性质:

  1. 非负性 :H(p)≥0H(p) \geq 0H(p)≥0,因为每个 −log⁡2p(x)≥0-\log_2 p(x) \geq 0−log2p(x)≥0
  2. 最大值 :对于有 nnn 个可能取值的离散分布,熵的最大值是 log⁡2n\log_2 nlog2n,在均匀分布时达到
  3. 最小值:熵的最小值是 0,在确定性分布(某个事件概率为1)时达到
  4. 可加性:对于独立分布,联合熵等于边际熵之和

熵是信息论中最核心的概念。它衡量了分布的不确定性------熵越高,分布越"混乱",需要越多的比特来编码。反之,熵越低,分布越"有序",编码效率越高。


交叉熵的概念

小可(担忧):如果航天机构调整了计划,概率分布变了怎么办?

博博(解释):向上/向下各1/8,向左1/4,向右1/2------编码方案不再最优。

现在进入第二部分。想象一下,航天机构决定更改计划------通过旋转调整方向以鼓励整体向右的移动。新的分布是:向上和向下各有1/8的概率,向左有1/4的概率,而向右则有1/2的概率。

Q(↑)=18,Q(↓)=18,Q(←)=14,Q(→)=12Q(\uparrow) = \frac{1}{8}, Q(\downarrow) = \frac{1}{8}, Q(\leftarrow) = \frac{1}{4}, Q(\rightarrow) = \frac{1}{2}Q(↑)=81,Q(↓)=81,Q(←)=41,Q(→)=21

但问题在于:我们仍然使用为旧分布 PPP 优化的编码方案。这显然不再是最优的了。

让我们看看具体发生了什么。旧的编码方案是:

  • 向上:0(1比特)
  • 向下:10(2比特)
  • 向左:110(3比特)
  • 向右:111(3比特)

这个方案是为旧分布 PPP 设计的------向上概率最高所以用最短码,向右概率最低所以用最长码。但现在实际情况变了------向右变成了最高概率的事件,却仍然用3比特编码!而向上变成了低概率事件,却享受着1比特的优待。这显然是低效的。

如果我们要为新分布 QQQ 设计最优编码,应该是:

  • 向右:0(1比特)--- 概率最高
  • 向左:10(2比特)
  • 向上:110(3比特)
  • 向下:111(3比特)

但我们没有这样做------我们仍然用旧的编码。这就导致了效率的损失。


小可(计算):旧的编码方案在新分布下效率有多低?

博博(计算):计算加权和:1/8×1 + 1/8×2 + 1/4×3 + 1/2×3 = 2.625比特。

让我们仔细计算一下。在旧编码方案下,新分布 QQQ 中每个符号的平均编码长度是:

  • 向上(新概率1/8,旧编码1比特)→ 贡献 1/8×1=0.1251/8 \times 1 = 0.1251/8×1=0.125
  • 向下(新概率1/8,旧编码2比特)→ 贡献 1/8×2=0.251/8 \times 2 = 0.251/8×2=0.25
  • 向左(新概率1/4,旧编码3比特)→ 贡献 1/4×3=0.751/4 \times 3 = 0.751/4×3=0.75
  • 向右(新概率1/2,旧编码3比特)→ 贡献 1/2×3=1.51/2 \times 3 = 1.51/2×3=1.5

总平均比特数 = 0.125+0.25+0.75+1.5=2.6250.125 + 0.25 + 0.75 + 1.5 = 2.6250.125+0.25+0.75+1.5=2.625 比特/符号。

而新分布 QQQ 的熵(最优编码的理论下限)是:

H(Q)=−18log⁡218−18log⁡218−14log⁡214−12log⁡212H(Q) = -\frac{1}{8}\log_2\frac{1}{8} - \frac{1}{8}\log_2\frac{1}{8} - \frac{1}{4}\log_2\frac{1}{4} - \frac{1}{2}\log_2\frac{1}{2}H(Q)=−81log281−81log281−41log241−21log221

=38+38+24+12=0.375+0.375+0.5+0.5=1.75 比特= \frac{3}{8} + \frac{3}{8} + \frac{2}{4} + \frac{1}{2} = 0.375 + 0.375 + 0.5 + 0.5 = 1.75 \text{ 比特}=83+83+42+21=0.375+0.375+0.5+0.5=1.75 比特

所以实际用了2.625比特,而理论最优是1.75比特------每符号浪费了0.875比特。

这0.875比特的浪费,就是用错误的编码方案编码正确数据的代价。在信息论中,这个代价有一个专门的名称:KL散度。


小可(恍然大悟):2.625比特------这就是交叉熵!

博博(点头):它反映了两个分布之间的信息差异程度。

这正是交叉熵的概念。当我们用为分布 qqq 优化的编码方案去编码来自分布 ppp 的符号时,平均每个符号所需的比特数就是 ppp 相对于 qqq 的交叉熵。

更精确地说:在我们的例子中,ppp 是实际的数据分布(新分布 QQQ),qqq 是编码方案基于的分布(旧分布 PPP)。交叉熵 H(p,q)H(p,q)H(p,q) 就是用 qqq 的编码去编码 ppp 的数据时的平均比特数。

注意这里的顺序很重要:H(p,q)H(p,q)H(p,q) 中,ppp 是实际数据的分布(权重),qqq 是编码方案基于的分布(编码长度由 qqq 决定)。


交叉熵的含义

小可(思考):交叉究竟在问什么问题?

博博(精准描述):如果你在某一上下文中优化了压缩方案,它在另一个上下文中表现如何?

交叉熵的核心问题可以这样表述:如果你针对某个分布 qqq 优化了压缩方案,那么当实际的符号分布是 ppp 时,这个压缩方案的表现如何?

这就是交叉熵度量的东西------它告诉我们,一个为某个上下文优化的编码方案在另一个上下文中的效率损失。

我们可以从几个角度来理解交叉熵:

  1. 压缩视角 :用为 qqq 设计的压缩器压缩 ppp 的数据,平均需要多少比特?
  2. 预测视角 :如果你的预测模型输出的分布是 qqq,而真实数据的分布是 ppp,你的预测有多"意外"?
  3. 编码视角 :如果你用基于 qqq 的编码表去传输 ppp 的数据,传输效率如何?

这三个视角本质上是等价的,都指向同一个数学量:交叉熵 H(p,q)H(p,q)H(p,q)。


交叉熵公式

小可(期待):公式是什么样的?

博博 (清晰):H(p,q)=∑pi⋅(−log⁡2qi)H(p,q) = \sum p_i \cdot (-\log_2 q_i)H(p,q)=∑pi⋅(−log2qi),用p的权重乘以q编码下的信息量。

交叉熵的一般公式是:

H(p,q)=∑xp(x)⋅(−log⁡2q(x))H(p, q) = \sum_x p(x) \cdot (-\log_2 q(x))H(p,q)=x∑p(x)⋅(−log2q(x))

其中:

  • p(x)p(x)p(x) 是真实分布中符号 xxx 出现的概率(权重)
  • q(x)q(x)q(x) 是编码方案基于的分布中符号 xxx 的概率(决定了编码长度)
  • −log⁡2q(x)-\log_2 q(x)−log2q(x) 是在 qqq 的编码方案下,符号 xxx 的信息量(比特数)

这个公式的含义是:对于每个可能的符号,计算它在 qqq 的编码方案下的比特数,然后用 ppp 中的实际概率对它加权求和。这就是实际的平均比特数。

交叉熵有一个非常重要的分解:

H(p,q)=H(p)+DKL(p∣∣q)H(p, q) = H(p) + D_{KL}(p || q)H(p,q)=H(p)+DKL(p∣∣q)

其中:

  • H(p)H(p)H(p) 是 ppp 的熵------理论最优编码的平均比特数
  • DKL(p∣∣q)=∑xp(x)log⁡2p(x)q(x)D_{KL}(p || q) = \sum_x p(x) \log_2 \frac{p(x)}{q(x)}DKL(p∣∣q)=∑xp(x)log2q(x)p(x) 是KL散度------用 qqq 代替 ppp 的额外代价

这个分解告诉我们:交叉熵 = 理论最优 + 效率损失。当 p=qp = qp=q 时,KL散度为零,交叉熵等于熵------编码方案完美匹配。当 p≠qp \neq qp=q 时,KL散度为正,交叉熵大于熵------有额外的浪费。


可视化理解

小可(对比):熵和交叉熵在图上有什么区别?

博博(图示):熵是柱宽=p、柱高=-log₂§;交叉熵是柱宽=p、柱高=-log₂(q)。

让我们用柱状图来直观理解熵和交叉熵的关系。

  • 熵 H(p)H(p)H(p) :每个柱的宽度是 p(x)p(x)p(x),高度是 −log⁡2p(x)-\log_2 p(x)−log2p(x)。面积总和就是熵。
  • 交叉熵 H(p,q)H(p, q)H(p,q) :每个柱的宽度仍然是 p(x)p(x)p(x)(因为符号的实际出现频率不变),但高度变成了 −log⁡2q(x)-\log_2 q(x)−log2q(x)(因为编码方案变了)。

两者之间的差值就是KL散度:

DKL(p∣∣q)=H(p,q)−H(p)=∑xp(x)log⁡2p(x)q(x)D_{KL}(p || q) = H(p, q) - H(p) = \sum_x p(x) \log_2 \frac{p(x)}{q(x)}DKL(p∣∣q)=H(p,q)−H(p)=x∑p(x)log2q(x)p(x)

KL散度有几个重要性质:

  1. 非负性 :DKL(p∣∣q)≥0D_{KL}(p || q) \geq 0DKL(p∣∣q)≥0,这被称为Gibbs不等式
  2. 不对称性 :DKL(p∣∣q)≠DKL(q∣∣p)D_{KL}(p || q) \neq D_{KL}(q || p)DKL(p∣∣q)=DKL(q∣∣p),所以KL散度不是真正的"距离"
  3. 零值条件 :DKL(p∣∣q)=0D_{KL}(p || q) = 0DKL(p∣∣q)=0 当且仅当 p=qp = qp=q

KL散度衡量了由于使用错误的编码方案而浪费的比特数。当 p=qp = qp=q 时,KL散度为零,交叉等于熵------编码方案完美匹配实际分布。


二元分布示例

小可(想简化):用两个事件的分布来理解?

博博(举例):Q均匀分布50-50,P偏向90-10,直观展示差异。

引入新公式时,用简单的例子来建立直觉很有帮助。因此让我们考虑只有两个可能事件的分布。

假设 QQQ 是均匀分布,给每个事件分配50%的概率。而 PPP 偏向其中一个事件,给第一个事件分配90%的概率,第二个事件10%。

QQQ 的熵是 1 比特(因为两个事件等概率,每个事件的 −log⁡2(0.5)=1-\log_2(0.5) = 1−log2(0.5)=1,加权后还是1)。

PPP 的熵是 −0.9log⁡20.9−0.1log⁡20.1≈0.469-0.9 \log_2 0.9 - 0.1 \log_2 0.1 \approx 0.469−0.9log20.9−0.1log20.1≈0.469 比特。

如果用 QQQ 的编码(每个符号1比特)去编码 PPP 分布的符号,交叉熵是 0.9×1+0.1×1=10.9 \times 1 + 0.1 \times 1 = 10.9×1+0.1×1=1 比特------没有损失,因为均匀编码对所有符号都一样。

但如果反过来------用 PPP 的编码(为第一个符号约0.152比特,第二个约3.322比特)去编码 QQQ 分布的符号呢?交叉熵是 0.5×0.152+0.5×3.322≈1.7370.5 \times 0.152 + 0.5 \times 3.322 \approx 1.7370.5×0.152+0.5×3.322≈1.737 比特。

这个例子说明了交叉熵的不对称性:H(P,Q)≠H(Q,P)H(P,Q) \neq H(Q,P)H(P,Q)=H(Q,P)。用均匀分布的编码去编码偏斜分布的数据,效率还行;但用偏斜分布的编码去编码均匀分布的数据,效率很差------因为偏斜编码为低概率事件分配了很长的码字,而均匀分布中这些"长码字事件"出现的频率并不低。


交叉熵的最小值

小可(疑惑):交叉熵什么时候取最小值?

博博(揭示):当p和q完全相同时!最小值就是p的熵。

这是交叉熵的一个关键性质:如果你将 ppp 视为固定,qqq 视为变量,那么当 qqq 等于 ppp 时,交叉熵取得最小可能值。更具体地说,这个最小值就是 ppp 的熵 H(p)H(p)H(p)。

这个性质非常合理。交叉熵的问题是在问:用为 qqq 优化的编码去编码来自 ppp 的符号,效率如何?当 qqq 与 ppp 完全匹配时,编码方案完美适配实际分布,效率自然达到最佳。

我们可以把这个性质可视化。如果固定 ppp,将交叉熵 H(p,q)H(p, q)H(p,q) 作为 qqq 的函数绘制出来,我们会看到一条曲线,在 q=pq = pq=p 处达到最小值。这条最小值轨迹实际上就是 ppp 的熵。

这个性质的证明依赖于Gibbs不等式,它本质上是一个关于对数函数凹凸性的结果。利用 ln⁡x≤x−1\ln x \leq x - 1lnx≤x−1(对所有 x>0x > 0x>0),可以证明:

DKL(p∣∣q)=∑xp(x)ln⁡p(x)q(x)≥∑xp(x)(1−q(x)p(x))=∑x(p(x)−q(x))=0D_{KL}(p || q) = \sum_x p(x) \ln \frac{p(x)}{q(x)} \geq \sum_x p(x) \left(1 - \frac{q(x)}{p(x)}\right) = \sum_x (p(x) - q(x)) = 0DKL(p∣∣q)=x∑p(x)lnq(x)p(x)≥x∑p(x)(1−p(x)q(x))=x∑(p(x)−q(x))=0

等号成立当且仅当 p(x)=q(x)p(x) = q(x)p(x)=q(x) 对所有 xxx。


语言模型中的交叉

现在让我们进入后半部分------交叉熵如何在语言模型训练中出现。这看起来是一个完全不同的领域,似乎与压缩无关。但背后有着深刻的数学联系。

小可(关键问题):交叉怎么成为语言模型的损失函数?

博博(讲解):模型对每个标记赋予概率,损失 = -log(q(正确标记)),对所有标记平均。

语言模型的基本工作原理是:将文本视为由一系列标记(token)组成的序列,然后根据这些标记生成所有可能标记的概率分布,从而预测接下来可能出现的内容。

要训练一个语言模型,你需要一个损失函数------用来衡量模型的预测是否准确。在语言模型的背景下,这个损失函数就是交叉。

具体来说:

  1. 从互联网上抽取大量文本样本作为训练数据
  2. 对于每个标记位置,模型生成所有可能下一个标记的概率分布 qqq
  3. 计算模型给真实下一个标记赋予的概率 q(xtrue)q(x_{\text{true}})q(xtrue)
  4. 损失值 = −log⁡q(xtrue)-\log q(x_{\text{true}})−logq(xtrue)(通常用自然对数而非以二为底的对数)
  5. 对所有标记平均这个值

这就是交叉熵在语言模型训练中的具体实现。模型对正确下一个词赋予的概率越高,−log⁡q(x)-\log q(x)−logq(x) 就越小,损失就越低。一个训练好的模型会对正确内容感到"不意外",因此损失低;一个随机或训练不好的模型会感到困惑,总是赋予低概率,损失就高。

在数学上,这等价于最小化模型分布 qqq 和数据分布 ppp 之间的交叉熵。因为对于每个标记位置,真实数据的分布 ppp 是一个 one-hot 分布(只有正确的标记概率为1,其余为0),所以:

H(p,q)=−∑xp(x)log⁡q(x)=−log⁡q(xtrue)H(p, q) = -\sum_x p(x) \log q(x) = -\log q(x_{\text{true}})H(p,q)=−x∑p(x)logq(x)=−logq(xtrue)

这正是语言模型使用的交叉熵损失。


为什么是对数函数?

你可能会问:为什么偏偏是对数函数?很多函数都有类似的递减形状------在概率低时惩罚大,在概率高时惩罚小。什么让对数函数如此特殊?

答案在于一个深刻的数学论证:如果你要求损失函数满足某些自然的性质------特别是,要求当模型的预测分布与数据的真实分布完全一致时,总平均损失达到最小------那么损失函数必须是一个对数函数。没有其他选择。

这可以通过拉格朗日乘数法来证明:在所有满足 ∑q(x)=1\sum q(x) = 1∑q(x)=1 的分布中,使总平均损失最小化的条件最终归结为 f′(q)=常数/qf'(q) = \text{常数}/qf′(q)=常数/q,而对数函数是唯一满足这个性质的函数。

这就是为什么交叉熵不仅仅是一个"不错的选择"------它是必然的选择

perplexity(困惑度)

在语言模型领域,交叉熵通常被转换为一个更直观的指标:困惑度(perplexity)。困惑度定义为:

Perplexity=2H(p,q)\text{Perplexity} = 2^{H(p,q)}Perplexity=2H(p,q)

(如果用自然对数,则是 eH(p,q)e^{H(p,q)}eH(p,q))

困惑度可以理解为:模型在预测下一个标记时,平均有多少个"等效的"候选标记。如果困惑度是100,意味着模型在每一步平均在100个候选中做选择。困惑度越低,模型越好。

现代大型语言模型的困惑度通常在个位数到几十之间,这意味着它们对语言的预测能力已经非常强。


知识蒸馏

小可(好奇):小模型如何模仿大模型?

博博(解释):用交叉熵比较小模型分布和大模型分布,而不仅仅是看正确下一个词。

知识蒸馏是交叉的一个重要应用。在这个场景中,你希望用一个更小、更高效的模型来模仿一个大模型的性能------这样在推理时运行起来会更加节省资源和时间。

训练方法是:

  1. 浏览一堆数据
  2. 对于每个标记位置,获取大模型的完整概率分布(而不仅仅是最高概率的那个标记)
  3. 用交叉熵比较小模型的分布和大模型的分布

这与标准预训练的区别在于:标准预训练只关心正确下一个词的损失,而知识蒸馏用大模型的完整分布作为"软目标",对小模型的整个分布进行约束。

这就像学习国际象棋------与其只看别人下棋时走了哪一步,不如了解所有可能的走法及其优劣。知识蒸馏大大减少了训练所需的数据量,因为你从一个例子中就能获得丰富的信息(大模型的完整分布),而不仅仅是单一的标注。

在实际应用中,知识蒸馏通常还会引入一个"温度"参数 TTT,将概率分布"软化":

qT(x)=exp⁡(zx/T)∑jexp⁡(zj/T)q_T(x) = \frac{\exp(z_x / T)}{\sum_j \exp(z_j / T)}qT(x)=∑jexp(zj/T)exp(zx/T)

其中 zxz_xzx 是模型对标记 xxx 的 logits(未归一化的分数)。当 T>1T > 1T>1 时,分布变得更加均匀,保留了更多关于"哪些标记比较相似"的信息。这使得小模型能够从大模型中学到更丰富的知识。


回到起点:压缩即智能

现在让我们后退一步,回顾整个旅程。

前半部分在压缩的背景下,交叉熵的出现非常自然------只需问:为分布 qqq 优化的编码方案,在分布 ppp 的上下文中表现如何?答案就是交叉熵。

后半部分从完全不同的数学领域(约束优化)导出了交叉熵公式------它作为损失函数出现在语言模型训练中,感觉与压缩无关。

但这两种出现方式之间有着比表面看起来更紧密的联系。

小可(领悟):所以训练好语言模型 = 成为最佳压缩器?

博博(总结):对!最小化交叉熵就是逼近语言的熵------压缩即智能。


深层联系

当我们将语言模型训练理解为交叉熵最小化时,我们实际上是在做一件事:让模型学会预测文本中每个标记的概率分布。而根据信息论,一个能准确预测符号分布的系统,本质上就是一个高效的压缩器------因为它知道如何用最短的编码来表示信息。

反过来说,一个高效的压缩器必须对数据的统计模式有深刻的理解,这本身就是一种"智能"的体现。这就是"压缩即智能"(Compression is Intelligence)这一观点的核心。

在语言模型的情况下:

  • 模型学习语言的统计模式
  • 这些模式使模型能够预测下一个标记
  • 预测越准确,模型的交叉熵损失越低
  • 交叉熵越低,模型对文本的压缩效率越高
  • 因此,一个优秀的语言模型就是一个优秀的文本压缩器

一旦你理解了这个联系,整个景观就完全不同了。你不再将语言模型视为单纯的"预测机器",而是将其视为一个"压缩引擎"------它通过压缩来理解语言,通过理解来智能地处理文本。

最小描述长度原则

这个联系还可以从另一个角度理解:最小描述长度(MDL)原则。MDL原则说:对于一组数据,最好的模型是那个能让"模型描述长度 + 数据在模型下的编码长度"最小化的模型。

在语言模型中:

  • 模型描述长度 ≈ 模型的参数量(参数量越大,模型越复杂)
  • 数据编码长度 ≈ 交叉熵损失 × 数据量

因此,训练语言模型就是在寻找一个平衡点:模型不能太简单(否则交叉熵高),也不能太复杂(否则模型描述长度大)。最优的模型是在这两个方面达到最佳平衡的模型。

泛化与压缩

有趣的是,这个压缩视角还解释了为什么语言模型能够泛化。一个真正"理解"了语言规律的模型,不仅能够复现训练数据,还能够压缩未见过的数据------因为它学到了数据中的普遍模式,而不是简单地记忆。

如果一个模型只是死记硬背训练数据,它在训练集上的交叉熵会很低,但在新数据上会很高。而一个真正学会了语言规律的模型,在新数据上的交叉也会比较低------因为它学到的模式具有普遍性。

这就是为什么交叉熵不仅是训练的目标,也是评估模型泛化能力的指标。



KL散度详解:理解交叉熵的关键

KL散度(Kullback-Leibler divergence)是信息论中最重要的概念之一,它衡量了两个概率分布之间的差异。理解KL散度,是深入理解交叉熵的关键。

KL散度的定义

DKL(p∣∣q)=∑xp(x)log⁡2p(x)q(x)D_{KL}(p || q) = \sum_x p(x) \log_2 \frac{p(x)}{q(x)}DKL(p∣∣q)=x∑p(x)log2q(x)p(x)

这个公式可以理解为:对于每个可能的符号x,计算p(x)和q(x)之间比值的对数,然后用p(x)加权求和。

从交叉熵的分解来看:DKL(p∣∣q)=H(p,q)−H(p)D_{KL}(p || q) = H(p, q) - H(p)DKL(p∣∣q)=H(p,q)−H(p)。KL散度就是交叉熵超出熵的那部分------用错误编码方案编码数据的额外代价。

直观理解

回到我们的机器人游走例子:

  • 实际分布Q:向右50%,向左25%,向上12.5%,向下12.5%
  • 假设分布P:向上50%,向下25%,向左12.5%,向右12.5%

用P的编码来编码Q的数据时,KL散度DKL(Q∣∣P)=0.875D_{KL}(Q || P) = 0.875DKL(Q∣∣P)=0.875比特。这意味着:

  • 向右(实际概率1/2,却用了3比特编码)→ 浪费极大!最高频事件用了最长码
  • 向上(实际概率1/8,却只用了1比特编码)→ 看似赚了,但发生频率太低
  • 净效果:每符号浪费0.875比特
KL散度的四大关键性质

1. 非负性(Gibbs不等式) :DKL(p∣∣q)≥0D_{KL}(p || q) \geq 0DKL(p∣∣q)≥0,等号当且仅当p=qp = qp=q

证明利用了ln⁡x≤x−1\ln x \leq x - 1lnx≤x−1这个基本不等式:

DKL(p∣∣q)=−∑xp(x)ln⁡q(x)p(x)≥−∑xp(x)(q(x)p(x)−1)=0D_{KL}(p || q) = -\sum_x p(x) \ln \frac{q(x)}{p(x)} \geq -\sum_x p(x) \left(\frac{q(x)}{p(x)} - 1\right) = 0DKL(p∣∣q)=−x∑p(x)lnp(x)q(x)≥−x∑p(x)(p(x)q(x)−1)=0

这意味着:用任何非最优编码方案,都会导致比特浪费。你不可能比理论最优做得更好。

2. 不对称性 :DKL(p∣∣q)≠DKL(q∣∣p)D_{KL}(p || q) \neq D_{KL}(q || p)DKL(p∣∣q)=DKL(q∣∣p)

  • DKL(p∣∣q)D_{KL}(p || q)DKL(p∣∣q)用p加权,衡量在p的视角下用q编码的损失
  • DKL(q∣∣p)D_{KL}(q || p)DKL(q∣∣p)用q加权,衡量在q的视角下用p编码的损失
  • 这两个值通常不同。在我们的例子中,DKL(Q∣∣P)=0.875D_{KL}(Q || P) = 0.875DKL(Q∣∣P)=0.875,而DKL(P∣∣Q)D_{KL}(P || Q)DKL(P∣∣Q)会是一个完全不同的值

3. 无穷大条件 :如果q(x)=0q(x) = 0q(x)=0但p(x)>0p(x) > 0p(x)>0,则DKL(p∣∣q)=∞D_{KL}(p || q) = \inftyDKL(p∣∣q)=∞

这意味着:如果你的编码方案完全没有考虑某个实际会发生的事件,那么平均编码长度就是无穷大。在机器学习中,这通常通过在q(x)上加一个小的平滑项(如10−710^{-7}10−7)来避免。

4. 链式法则 :对于联合分布,

DKL(p(x,y)∣∣q(x,y))=DKL(p(x)∣∣q(x))+Ep(x)DKL(p(y∣x)∣∣q(y∣x))D_{KL}(p(x,y) || q(x,y)) = D_{KL}(p(x) || q(x)) + E_{p(x)}D_{KL}(p(y\|x) \|\| q(y\|x))DKL(p(x,y)∣∣q(x,y))=DKL(p(x)∣∣q(x))+Ep(x)DKL(p(y∣x)∣∣q(y∣x))

这意味着联合分布的KL散度可以分解为边际分布的KL散度加上条件分布的KL散度的期望。这个性质在变分推断中非常重要。

KL散度在机器学习中的广泛应用

KL散度在机器学习中无处不在:

  • 变分推断 :用易处理的分布q近似难以计算的后验分布p,目标是最小化DKL(q∣∣p)D_{KL}(q || p)DKL(q∣∣p)
  • 变分自编码器(VAE) :ELBO目标中包含DKL(q(z∣x)∣∣p(z))D_{KL}(q(z|x) || p(z))DKL(q(z∣x)∣∣p(z))项,强制隐变量分布接近先验
  • 策略优化:强化学习中的TRPO/PPO算法用KL散度约束策略更新幅度,防止更新过大
  • 模型正则化:在分类模型中加入KL散度惩罚,防止模型过度自信
  • 信息瓶颈 :用DKLD_{KL}DKL控制表示的信息量,在压缩和预测之间找到最优平衡

理解KL散度的非负性和不对称性,是理解这些应用的基础。


信息几何视角:分布空间中的距离

KL散度虽然不是严格意义上的距离(因为它不对称,不满足三角不等式),但它在概率分布空间中定义了一种几何结构,被称为信息几何

Fisher信息度量

在信息几何中,概率分布空间被赋予了一种自然的度量------Fisher信息度量。这个度量描述了当分布参数发生微小变化时,分布本身变化的速率。

对于一个参数化分布pθ(x)p_\theta(x)pθ(x),Fisher信息矩阵定义为:

I(θ)=Epθ(∂∂θln⁡pθ(x))2I(\theta) = E_{p_\theta}\left\\left(\\frac{\\partial}{\\partial \\theta} \\ln p_\\theta(x)\\right)\^2\\rightI(θ)=Epθ(∂θ∂lnpθ(x))2

Fisher信息度量告诉我们:在参数空间的哪个方向上,分布变化最快。这个度量与KL散度有着深刻的联系------当两个分布非常接近时,KL散度近似等于Fisher信息度量下的平方距离的一半:

DKL(pθ∣∣pθ+δ)≈12δTI(θ)δD_{KL}(p_\theta || p_{\theta+\delta}) \approx \frac{1}{2} \delta^T I(\theta) \deltaDKL(pθ∣∣pθ+δ)≈21δTI(θ)δ

这个近似关系在自然梯度下降(Natural Gradient Descent)中有重要应用------它告诉我们,在参数空间中移动时,应该考虑分布空间的几何结构,而不仅仅是参数的欧氏距离。

信息几何的直观理解

想象概率分布空间是一个弯曲的曲面。KL散度告诉我们两个分布在曲面上的"信息距离"。当两个分布很近时,这个曲面看起来像一个平面,KL散度近似于欧氏距离。但当两个分布相距较远时,曲面的弯曲变得重要,KL散度的不对称性就显现出来了。

这种几何视角帮助我们理解为什么KL散度在机器学习中有如此广泛的应用------它本质上是在衡量模型预测分布与真实数据分布在信息空间中的距离。


语言模型困惑度(Perplexity)详解

在语言模型领域,交叉熵通常被转换为一个更直观的指标:困惑度(Perplexity)。困惑度定义为:

Perplexity=2H(p,q)\text{Perplexity} = 2^{H(p,q)}Perplexity=2H(p,q)

(如果用自然对数,则是eH(p,q)e^{H(p,q)}eH(p,q))

困惑度的直观含义

困惑度可以理解为:模型在预测下一个标记时,平均有多少个"等效的"候选标记。如果困惑度是100,意味着模型在每一步平均在100个候选中做选择。困惑度越低,模型越好。

让我们用几个例子来说明:

  • 完美模型 :如果模型总是100%确定下一个词,H(p,q)=0H(p,q) = 0H(p,q)=0,困惑度 = 1
  • 均匀随机模型 :如果词表大小是10000,模型对每个词赋均匀概率,H(p,q)=log⁡2(10000)≈13.29H(p,q) = \log_2(10000) \approx 13.29H(p,q)=log2(10000)≈13.29,困惑度 = 10000
  • 现代语言模型:大型语言模型的困惑度通常在个位数到几十之间,说明它们对语言的预测能力已经非常强
困惑度与词汇量的关系

困惑度的一个重要特性是:它已经隐含地考虑了词汇量的大小。一个困惑度为50的模型,无论词表大小是1000还是100000,其预测质量是可比的。这使得困惑度成为跨模型、跨数据集比较的标准指标。

困惑度的局限性

虽然困惑度是一个有用的指标,但它也有局限性:

  • 它只衡量模型对测试数据的拟合程度,不直接衡量生成质量
  • 一个困惑度低的模型不一定能生成连贯的文本
  • 不同数据集上的困惑度不可直接比较(因为数据分布不同)

尽管如此,困惑度仍然是语言模型研究和开发中最常用的评估指标之一。


知识蒸馏中的温度参数详解

在实际的知识蒸馏应用中,通常会引入一个温度参数 TTT,将概率分布"软化":

qT(x)=exp⁡(zx/T)∑jexp⁡(zj/T)q_T(x) = \frac{\exp(z_x / T)}{\sum_j \exp(z_j / T)}qT(x)=∑jexp(zj/T)exp(zx/T)

其中zxz_xzx是模型对标记x的logits(未归一化的分数)。

温度的作用

当T=1T = 1T=1时,这就是标准的softmax。当T>1T > 1T>1时,分布变得更加均匀------原本概率很小的事件会获得更大的概率,原本概率很大的事件会变得更小。这种"软化"保留了更多关于"哪些标记比较相似"的信息。

例如,假设一个模型对四个词的logits是10, 2, 1, 0

  • 当T=1时,softmax输出约为0.999, 0.0004, 0.0001, 0.00005------几乎全部概率集中在第一个词
  • 当T=5时,softmax输出约为0.37, 0.25, 0.20, 0.18------保留了更多关于相对排序的信息
为什么软化分布有用?

标准训练中,损失只关心正确标记的概率。但大模型的logits包含了丰富的信息------它不仅知道哪个词是对的,还知道哪些词"比较接近"。

比如,对于句子"I love to ___",大模型可能会输出:

  • eat: 高概率
  • drink: 中等概率(语义相关)
  • sleep: 低概率(不太相关)
  • fly: 极低概率(完全无关)

这些信息对于小模型学习语言的语义结构非常有用。通过温度软化,小模型可以从大模型的完整分布中学到这种语义层次,而不仅仅是"哪个词对"。

蒸馏损失的设计

完整的知识蒸馏损失通常包含两部分:

L=α⋅Lhard+(1−α)⋅T2⋅LsoftL = \alpha \cdot L_{hard} + (1-\alpha) \cdot T^2 \cdot L_{soft}L=α⋅Lhard+(1−α)⋅T2⋅Lsoft

  • LhardL_{hard}Lhard:标准交叉熵损失,基于真实标签
  • LsoftL_{soft}Lsoft:软化分布之间的交叉熵
  • α\alphaα:两部分损失的权重
  • T2T^2T2:缩放因子,补偿温度对梯度幅度的影响

T2T^2T2这个缩放因子很重要------因为温度增大会减小梯度的幅度,乘以T2T^2T2可以恢复梯度的正确尺度。


压缩即智能:更深层的哲学思考

"压缩即智能"这个观点不仅仅是一个技术观察,它还触及了智能本质的哲学问题。

为什么压缩等于理解?

当我们说"理解"一段文本时,我们指的是什么?通常意味着我们能够:

  • 预测接下来会发生什么
  • 用更简洁的方式重述内容
  • 发现内容中的模式和规律

注意这三件事都与压缩有关。能够预测接下来会发生什么,意味着你对数据的统计模式有准确的把握------这正是高效压缩所需要的。能够用更简洁的方式重述内容,意味着你找到了数据的简洁表示------这也是压缩的核心。

柯尔莫哥洛夫复杂度与智能

柯尔莫哥洛夫复杂度K(x)K(x)K(x)定义为产生x的最短程序的长度。虽然它是不可计算的,但它提供了一个理解"简单性"的数学框架。

一个真正"理解"了某个领域的智能体,应该能够用最简洁的方式描述该领域的知识。这就是最小描述长度(MDL)原则的核心思想:最好的模型是那个让"模型描述 + 数据编码"总长度最短的模型。

从压缩到泛化

压缩视角还解释了为什么语言模型能够泛化。一个真正"理解"了语言规律的模型,不仅能够复现训练数据,还能够压缩未见过的数据------因为它学到了数据中的普遍模式,而不是简单地记忆。

如果一个模型只是死记硬背训练数据,它在训练集上的交叉熵会很低,但在新数据上会很高。而一个真正学会了语言规律的模型,在新数据上的交叉熵也会比较低------因为它学到的模式具有普遍性。

这就是为什么交叉熵不仅是训练的目标,也是评估模型泛化能力的指标。好的压缩器 = 好的泛化器 = 好的语言模型。

香农的信息论遗产

克劳德·香农在1948年的论文中建立的信息论,为理解智能提供了一个全新的视角。在他之前,信息被认为是某种神秘的东西------与意义、意图和意识相关。香农的革命性贡献在于:他将信息定义为纯粹的统计量,与意义无关。

这个视角的转变使得我们可以用严格的数学工具来分析信息处理系统。而"压缩即智能"的观点,正是这一传统的延续------它告诉我们,智能的本质不在于理解"意义",而在于发现数据中的统计规律并用最简洁的方式编码它们。

从这个意义上说,语言模型的成功不仅仅是工程上的胜利,也是信息论思想的一次验证。25年前的gzip压缩实验和今天的大型语言模型,用完全不同的技术手段,指向了同一个深刻的真理:理解和压缩,本质上是一回事。


交叉熵优化的数学基础

为什么交叉熵作为损失函数如此有效?这背后有坚实的数学基础。

最大似然估计与交叉熵

从统计学的角度来看,最小化交叉熵等价于最大似然估计(MLE)。

给定数据x1,x2,...,xnx_1, x_2, ..., x_nx1,x2,...,xn和参数化模型qθ(x)q_\theta(x)qθ(x),最大似然估计的目标是:

max⁡θ∏i=1nqθ(xi)\max_\theta \prod_{i=1}^n q_\theta(x_i)θmaxi=1∏nqθ(xi)

取对数后:

max⁡θ∑i=1nlog⁡qθ(xi)=min⁡θ∑i=1n−log⁡qθ(xi)\max_\theta \sum_{i=1}^n \log q_\theta(x_i) = \min_\theta \sum_{i=1}^n -\log q_\theta(x_i)θmaxi=1∑nlogqθ(xi)=θmini=1∑n−logqθ(xi)

这正是交叉熵损失。因此,训练语言模型本质上就是在做最大似然估计------寻找最可能产生观察数据的参数。

交叉熵的梯度

交叉熵损失的一个关键优势是它的梯度形式非常简单。对于softmax输出qqq和one-hot标签ppp:

∂H(p,q)∂zi=qi−pi\frac{\partial H(p,q)}{\partial z_i} = q_i - p_i∂zi∂H(p,q)=qi−pi

也就是说,梯度就是预测分布与真实分布的差。这个简洁的形式使得交叉熵损失非常适合梯度下降优化。

交叉熵与逻辑回归

在二分类问题中,交叉熵损失与逻辑回归完全等价。对于一个样本xxx和标签y∈{0,1}y \in \{0, 1\}y∈{0,1}:

L=−ylog⁡q+(1−y)log⁡(1−q)L = -y \\log q + (1-y) \\log(1-q)L=−ylogq+(1−y)log(1−q)

其中q=σ(wTx)q = \sigma(w^T x)q=σ(wTx)是sigmoid函数的输出。这个损失函数是凸的,保证了优化过程能够找到全局最优解。

在多分类问题中,softmax + 交叉熵是逻辑回归的自然推广。虽然多分类情况下的损失函数不再是凸的(因为神经网络的参数空间非凸),但交叉熵本身的凸性保证了在固定特征表示下,最优的分类器可以通过交叉熵损失找到。


交叉熵在自然语言处理中的更多应用

交叉熵的应用远不止语言模型训练和知识蒸馏。在自然语言处理的众多任务中,交叉都扮演着核心角色。

机器翻译中的交叉熵

在神经机器翻译中,交叉熵损失用于训练编码器-解码器架构。对于源语言句子xxx和目标语言句子yyy,模型的条件概率为:

p(y∣x)=∏t=1Tp(yt∣y<t,x)p(y|x) = \prod_{t=1}^T p(y_t | y_{<t}, x)p(y∣x)=t=1∏Tp(yt∣y<t,x)

训练目标是最小化负对数似然,即交叉熵损失:

L=−∑t=1Tlog⁡p(yt∣y<t,x)L = -\sum_{t=1}^T \log p(y_t | y_{<t}, x)L=−t=1∑Tlogp(yt∣y<t,x)

这里的交叉熵有一个特殊的含义:它衡量了模型对翻译结果的不确定性。损失越低,模型对正确翻译的置信度越高。

命名实体识别中的交叉熵

在序列标注任务如命名实体识别(NER)中,交叉熵损失用于训练每个位置的分类器。对于长度为TTT的序列,损失为:

L=−∑t=1Tlog⁡p(labelt∣x,t)L = -\sum_{t=1}^T \log p(label_t | x, t)L=−t=1∑Tlogp(labelt∣x,t)

这里每个位置的交叉熵独立计算,然后求和。这种方法的优势在于:不同位置的错误可以被独立处理,模型可以专注于困难位置的预测。

文本生成的质量评估

交叉还可以用于评估文本生成模型的质量。除了困惑度,研究者还使用交叉熵的变体来衡量生成文本的多样性和质量:

  • 参考交叉熵:用参考文本的分布来评估生成文本
  • 自交叉熵:用模型自身分布来评估一致性
  • 人类对齐交叉熵:用人类偏好数据来微调交叉熵权重

这些变体帮助研究者更好地理解模型的行为,并指导模型改进。

对抗训练中的交叉熵

在对抗训练中,交叉损失被用来增强模型的鲁棒性。通过在输入中添加精心设计的扰动(对抗样本),并在训练中最小化对抗样本上的交叉损失,模型可以学会抵抗这些扰动。

对抗训练的损失函数通常为:

Ladv=L(x,y)+λL(xadv,y)L_{adv} = L(x, y) + \lambda L(x_{adv}, y)Ladv=L(x,y)+λL(xadv,y)

其中xadvx_{adv}xadv是通过对xxx添加扰动得到的对抗样本,λ\lambdaλ是权重系数。这种方法显著提高了模型在分布外数据和对抗攻击下的性能。

多模态学习中的交叉熵

交叉熵的概念也在多模态学习中找到了新的应用。在视觉-语言模型(如CLIP)中,交叉熵损失被用来对齐图像和文本的表示空间。具体来说,对于一批图像-文本对,模型计算所有图像和所有文本之间的相似度矩阵,然后用交叉熵损失来确保正确的图像-文本对的相似度最高。

这种对称的交叉熵设计(图像到文本和文本到图像各一次)使得模型能够学习到跨模态的共享表示,为后续的零样本分类、图像检索和文本生成等任务奠定了基础。

总结

让我们总结一下从gzip压缩到"压缩即智能"的完整旅程:

  1. gzip压缩发现语言关系:通过比较联合压缩和单独压缩的差异,可以在没有语言学知识的情况下重建语言谱系树。这展示了信息论的实际力量------不需要复杂模型,简单的压缩算法就能揭示深层结构。

  2. 距离度量的定义:NCD(归一化压缩距离)提供了一种完全无监督的相似度度量,适用于任何可以用压缩器处理的离散序列数据。

  3. 交叉熵的引入:这个差异的本质是交叉熵------衡量一个分布的编码在另一个分布下的效率。交叉 = 熵 + KL散度。

  4. 信息论基础 :从符号序列、概率分布到最优编码,信息论提供了理解信息的数学框架。信息量 I(x)=−log⁡2p(x)I(x) = -\log_2 p(x)I(x)=−log2p(x),熵 H(p)=E−log⁡2p(x)H(p) = \mathbb{E}-\\log_2 p(x)H(p)=E−log2p(x)

  5. 语言模型训练 :交叉熵作为损失函数,驱动语言模型学习预测下一个标记的概率分布。perplexity = 2H(p,q)2^{H(p,q)}2H(p,q) 是常用的评估指标。

  6. 知识蒸馏:交叉熵还可以用于比较小模型和大模型的分布,实现知识迁移,大幅减少训练所需的数据量。

  7. 压缩即智能:最小化交叉熵就是逼近语言的熵------好的语言模型就是好的压缩器。这个联系不仅帮助我们理解语言模型的工作原理,还启发了我们对"智能"本质的新思考。

这个旅程展示了一个深刻的洞见:信息论、机器学习和智能之间存在着本质的联系。理解这种联系,不仅能帮助我们更好地理解语言模型的工作原理,还能启发我们用新的视角来看待"智能"的本质。

从25年前的gzip压缩实验,到今天的大型语言模型,交叉熵这条线贯穿始终。它告诉我们:无论技术如何发展,信息论的基本原理始终是理解智能的核心钥匙。


感谢小可和博博的精彩对话!希望这篇漫画科普帮助你从直观到深入,全面理解交叉这个重要概念。记住:压缩即智能------当你的模型学会了压缩,它也就学会了理解。

🐾 下期再见!

相关推荐
Yngz_Miao6 个月前
【深度学习】交叉熵损失函数Cross-Entropy Loss
人工智能·深度学习·损失函数·交叉熵·ce
AIminminHu8 个月前
底层视觉及图像增强-项目实践理论补充(十六-0-(34):交叉熵损失函数与软件思维的联系):从奥运大屏到手机小屏,快来挖一挖里面都有什么
交叉熵·交叉熵损失
a man of sadness10 个月前
决策树算法基础:信息熵相关知识
决策树·机器学习·分类·信息熵·kl散度·交叉熵
码字的字节1 年前
深度学习损失函数的设计哲学:从交叉熵到Huber损失的深入探索
深度学习·交叉熵·huber
Jcldcdmf1 年前
激活层为softmax时,CrossEntropy损失函数对激活层输入Z的梯度
机器学习·损失函数·softmax·交叉熵
夜松云1 年前
从对数变换到深度框架:逻辑回归与交叉熵的数学原理及PyTorch实战
pytorch·算法·逻辑回归·梯度下降·交叉熵·对数变换·sigmoid函数
callinglove1 年前
交叉熵在机器学习中的应用解析
损失函数·交叉熵
xidianjiapei0011 年前
一文读懂深度学习中的损失函数quantifying loss —— 作用、分类和示例代码
人工智能·深度学习·分类·损失函数·交叉熵
余胜辉2 年前
【深度学习】交叉熵:从理论到实践
人工智能·深度学习·机器学习·损失函数·交叉熵