跳到主要内容

损失与逐词生成 — 「答得好」怎么变成一个数

这一章讲两件事: 第 01 章说训练是「把损失调到最小」,这一章给损失填内容—— 三种基本任务各用什么损失,以及为什么说损失是「替身」而非「本尊」; 然后讲序列数据(文字)怎么进这台机器——答案是「一次只猜下一个词」。 它在全书的位置:本章后半就是今天那些会写文章的模型的训练方式。

1. 顶层全景:损失是一台「打分器」

上一章的训练回路里,「损失」是唯一的裁判:模型算出答案,裁判看一眼真实答案, 打一个分,分越低越好。这一章要回答的问题是:这个裁判的评分规则怎么写?

原书按第 01 章的三类任务各给了一条标准答案1:

任务形状标准裁判一句话规则
回归(答案是连续量)均方误差(MSE,第 01 章已见)差多少,平方,求平均
密度建模(学数据本身)「真实数据被判了多大可能性」的分这个分越大越好;它的名字见第 2 节末
分类(有限类挑一个)见下面第 2 节,值得走一遍先打分、洗成可能性、再罚

2. 分类的标准裁判(本章主走查)

分类这一行值得拆开走,因为它拐了两个弯,每个弯都有名字。 先交代终点裁判名字里的一个字:(entropy)——它本来是信息论里 「不确定程度」的度量;本章只借这个裁判的打分行为,不涉及信息论本身的数学。

第一个弯:模型的输出不是「答案」,是一排打分。 分类模型对每个候选类输出一个数, 这个数叫 logit(把它理解成「未归一化的信心分」就行—— 数越大,模型越倾向这一类,但这排数本身不是概率——概率就是可能性大小—— 它们加起来不等于 1)2

第二个弯与终点裁判

第二个弯:把这排打分洗成概率。 洗法叫 softmax

它对每个打分取 e 的指数 (把它们全变成正数),再除以所有指数之和(让它们加起来等于 1)。 它还有一个更诚实的名字 softargmax——「软化版的取最大值」: 取最大值是「只认第一名」,softmax 是「按名次分配份额」3

然后裁判才出场,它叫交叉熵(cross-entropy)。

它的打分规则:对真实那一类的概率取负对数—— 「对数」就是『几次方』的逆运算,「概率」就是可能性大小。 真实类概率越接近 1,负对数越接近 0;概率越小,这个值涨得越快—— 它对「自信地答错」罚得极重4

拿一个具体的三分类走一遍(这些打分是为演示编的,不是真实模型输出):

输入一张图,模型给出 logits: 猫 2.0 狗 1.0 车 0.1
取指数(e 的幂): 7.39 2.72 1.11
总和: 11.22
softmax(各自除以总和): 0.66 0.24 0.10 ← 现在是一组概率
真实答案是「猫」: 交叉熵 = −log(0.66) ≈ 0.42

图说:如果模型更自信,给猫打出 3.0,概率变 0.84,损失降到 0.17;
如果它把最高分给了狗,猫只剩 0.10,损失飙到 2.30。
训练就是把几百万个这样的 0.42 一路压下去。

密度建模的裁判顺手在这里交代: 它叫负对数似然——似然(likelihood) 就是「模型给真实数据整体打的概率」;训练 = 让这个概率最大, 等价于让它的负对数最小。形式和交叉熵是亲戚:都是「给真实的东西打分,取负对数」5

3. 学「距离感」的裁判:对比损失

有一类任务的答案不是「是什么类」,而是「和谁像」。典型场景:人脸识别—— 你要的不是「这是第 37 号人」,而是「这两张脸是不是同一个人」。 这类任务叫度量学习(metric learning),目标是学出一种距离: 同类的样本距离近,异类的远6

它的裁判叫对比损失(contrastive loss),训练数据是三元组: 一张「锚」样本 xa、一张和锚同类的 xb、一张不同类的 xc。 损失要求模型给的打分满足:异类对的分数至少要比同类对高出一个边距(比如 1), 差不够就罚,罚的量线性增长——写成式子就是 max(0, 1 − f(xa,xc) + f(xa,xb)), 只有分差不够 1 时它才是正的7

锚:某人的脸 A 同类:此人的另一张脸 B 异类:陌生人的脸 C
模型给「A 对 C」的相异度打分 0.3,给「A 对 B」打分 0.1
罚 = max(0, 1 − 0.3 + 0.1) = 0.8 ← 分差只有 0.2,不到边距 1,罚 0.8
(这些数是为演示编的。)

图说:这个裁判不管绝对对错,只管「该近的近、该远的远,至少拉开一格」。

这个裁判会在第 10 章回来: 把图和文配上对的模型 CLIP 就是把对比损失用到 「图和文配不配对」上,一次对比一整批。

4. 裁判是替身,不是本尊

这是本节最重要的一句原书观点:训练时最小化的损失,通常不是你最终真正 想做得更好的东西,而是一个「找最优参数更容易」的替身8

为什么需要替身?拿分类说:你真正在意的是错误率(100 张里认错几张)。 但错误率对参数的变化是「阶跃式」的——参数挪一点点,认错的张数要么不变、 要么跳变,给不出「往哪挪会更好」的方向信息。而下一章会看到, 整个训练方法靠的就是这个方向信息——它有个名字,叫梯度,第 04 章专讲。交叉熵是连续变化的, 参数挪一点点它就变一点点,方向信息一直都在。所以大家都用交叉熵训练, 用错误率验收9

替身还可以加料:在损失里额外套一项,把模型往某种参数形态上引。 最常用的加料叫权重衰减(weight decay):在损失上加一项「所有参数的平方和」。 效果是训练时参数被轻轻往小里压——参数小,模型对数据的反应就不那么剧烈, 等价于对参数放了一个「偏爱小值」的事先信念(行话叫正则化:给模型加约束防过拟合)。 代价是训练集上的成绩变差一点,换来的是训练成绩和新数据成绩之间的差距缩小10

5. 序列怎么办:一次只猜下一个词

前四节的裁判都默认「一次出一个完整答案」。可文字是一长串—— 「生成一整段文字」这件事怎么进这台机器?

钥匙是概率论里的链式法则:「一整段话出现的概率」可以精确地拆成 一连串条件概率的乘积——第一个词的概率,乘上「已知第一个词时第二个词的概率」, 再乘上「已知前两个词时第三个词的概率」……一直到末尾。注意:这是恒等式, 不是近似。 所以只要模型会回答「已知前面这些,下一个词是什么」, 它就等于掌握了整段话的概率11

这里要先交代一个单位。模型处理的「词」严格说是把文本切碎后的最小单位, 行话叫 token,中文叫「词元」——它可能是一整个词,也可能是半个词、一个标点。

所有可能的 token 凑成一张有限的表,叫词表(vocabulary)。

把文本切成 token、 再切回来的那道独立工序,由一段专门的程序负责,它叫分词器(tokenizer); 常用的 BPE(Byte Pair Encoding,字节对编码)从字符出发,反复合并最常一起出现的 片段,造出一批「长短不一但出现频率相近」的 token——常见长词整个给一个, 生僻的拆成碎片段,所以任何词都切得出来12

每个位置都是一道分类题

一个「给定前 t−1 个 token、输出词表上每个 token 的打分」的模型, 配上第 2 节的 softmax 和交叉熵,就能训练:每个训练序列的每个位置, 都是一道「猜下一个」的分类题,所有位置的交叉熵加起来就是总损失。 这样训练出来的模型叫自回归模型(autoregressive model——「自回归」= 拿自己已经生成的东西当输入,继续往下生成)13

训练语料里有一句:「the capital of Japan is Tokyo」
模型要同时答对这五道题:
已知 ⟨空⟩ → 下一个该是 the
已知 the → 下一个该是 capital
已知 the capital → 下一个该是 of
……
每题都是一次交叉熵。生成时反过来:自己答、自己接、再答。

图说:训练是「每个位置都被批改一遍」;生成是「答一题、把答案写进题干、再答下一题」。

用的时候怎么监控好坏?行内不直接看交叉熵,而看它的 e 次幂,叫困惑度 (perplexity)。它有个好懂的读法:相当于「模型每次相当于在几个等可能的候选里 猜」——困惑度 20,就是模型的心算等价于在 20 个等可能的词里挑一个;越小越好14

6. 因果结构:一遍前向,全序列开课

上面还有个效率问题没解决:一段 500 个 token 的序列,难道要跑 500 次模型、 每次喂不同长度的前缀?序列一长(实际常常是几百到几千个 token)这完全受不了15

标准解法是给模型加一个结构约束,叫因果(causal)结构:让模型一次接收 整段序列、一次性输出所有位置的打分,但从构造上保证——第 t 个位置算出的打分, 只许依赖第 1 到 t−1 个位置的输入,不许偷看后面。名字叫「因果」, 取的是「未来不能影响过去」的意思16

训练:喂入「the capital of Japan is」整句(一次前向)
位置1 输出 → 批改(该答 capital)
位置2 输出 → 批改(该答 of) ← 同一趟前向,所有位置同时开课
……
生成:还是一个一个来——算第 5 个词时,前 4 个必须已经生成完毕

图说:因果结构让训练可以「一炖一大锅」,生成却仍得「一勺一勺舀」。
这个不对称就是聊天机器人「思考免费、说话很慢」的总根源。

第 08 章会再见到它: 因果性在那章要讲的核心零件里,就是加一张 「只许看左边」的掩码,一行改动。

7. 作者的判断与证据

  • 「softmax 更该叫 softargmax」是作者的措辞意见,顺带揭示了它的本质: 它不是「取最大」的近似计算技巧,而是「取最大」本身的软化版3
  • 「损失是替身」在原书里是明说的一般性原则,错误率没有信息量梯度是 他给的例子。这条原则在第 04 章(梯度是训练的唯一导航)那里兑现。
  • 「困惑度更好解释」是作者的实用推荐,原书原话是它「generally more interpretable」——它是行内论文与报告里的通用货币,第 12 章「压位数」一节还会用到。
  • 因果模型的效率论证是构造性的:原书给了「T 常是几百到几千」这个量级, 以及「一次前向出全部位置」的结构要求,逻辑完整。

8. 边界与局限

  • 本章只讲了「给定前文猜下一个」这一种序列建模方式;「双向看」的掩码重建 (一个叫 BERT 的模型那一系)原书放到了最后一章的「没讲的」里,我们在第 12 章补。
  • 对比损失的三元组形式只是代表;实际系统(如 CLIP)用的是一批内所有对, 细节见第 10 章。
  • 「边距 1」这类常数是超参数,原书没展开调法。
  • 交叉熵与负对数似然的等价性,本章按原书口径陈述,未做信息论层面的展开。

9. 可带走的

  1. 三类任务各有标准裁判:回归用均方误差,密度建模用负对数似然,分类用交叉熵;
  2. 分类模型的原始输出叫 logits,softmax 把它洗成概率,交叉熵 = 真实类概率的负对数;
  3. 交叉熵对「自信地答错」罚得极重——这是它当裁判的脾气;
  4. 学「像不像」用对比损失:不管绝对对错,只管同类近、异类远、至少拉开一个边距;
  5. 损失通常是替身:你想要错误率,但错误率给不出方向,所以用交叉熵训练、用错误率验收;
  6. 损失可以加料:权重衰减把参数往小压,缩小训练成绩与真实成绩的差距;
  7. 概率链式法则是恒等式:「生成一段」≡「反复猜下一个」。大语言模型的训练方式就是这句话;
  8. 困惑度 = 交叉熵的 e 次幂,读作「相当于在几个等可能候选里猜」;
  9. 因果结构 = 不许偷看未来。它让训练一遍覆盖所有位置,但生成仍要逐个来——这个不对称决定了大模型的成本形状。

10. 原文地图

主题原书章原文位置
三类任务的标准损失Lossestext/06-fm-losses.txt:4(搜「standard loss for predicting」) · text/06-fm-losses.txt:8(搜「likelihood of the data」)
logits / softmax / 交叉熵Lossestext/06-fm-losses.txt:17(搜「logit」) · text/06-fm-losses.txt:28(搜「softmax」) · text/06-fm-losses.txt:32(搜「maximize the probability」)
对比损失与三元组Lossestext/06-fm-losses.txt:52(搜「metric learn」) · text/06-fm-losses.txt:61(搜「triplets」)
损失是替身;错误率无梯度Lossestext/06-fm-losses.txt:72(搜「a proxy」) · text/06-fm-losses.txt:76(搜「no informative gradient」)
权重衰减Lossestext/06-fm-losses.txt:83(搜「weight de」)
概率链式法则Autoregressive modelstext/07-fm-autoregressive-models.txt:10(搜「chain rule from probability theory」)
自回归训练与采样Autoregressive modelstext/07-fm-autoregressive-models.txt:36(搜「sampling T tokens」) · text/07-fm-autoregressive-models.txt:41(搜「minimizing the sum」)
困惑度Autoregressive modelstext/07-fm-autoregressive-models.txt:51(搜「perplexity」)
因果模型与效率Autoregressive modelstext/07-fm-autoregressive-models.txt:71(搜「Causal models」) · text/07-fm-autoregressive-models.txt:87(搜「letting the future influence the past」)
分词器与 BPEAutoregressive modelstext/07-fm-autoregressive-models.txt:103(搜「Tokenizer」) · text/07-fm-autoregressive-models.txt:113(搜「Pair Encoding」)

Footnotes

  1. 出处:「Losses」第 2–10 段(text/06-fm-losses.txt:4,搜「standard loss for predicting」;text/06-fm-losses.txt:8,搜「likelihood of the data」)。

  2. 出处:「Losses」第 13–18 段(text/06-fm-losses.txt:17,搜「logit」)。原文:logit 是「the logarithm of a non-normalized probability」。

  3. 出处:「Losses」第 27–30 段(text/06-fm-losses.txt:28,搜「softmax」)。原文:「generally called the softmax, or more adequately, the softargmax」。 2

  4. 出处:「Losses」第 31–46 段(text/06-fm-losses.txt:32,搜「maximize the probability」)。原书公式 3.x 在此;该 PDF 公式经转码已成碎片,本拆解一律用文字重述(见第 01 章脚注 8 的声明)。

  5. 出处:「Losses」第 7–10 段(text/06-fm-losses.txt:8,搜「likelihood of the data」)。

  6. 出处:「Losses」第 48–59 段(text/06-fm-losses.txt:52,搜「metric learn」)。原书例子:xa、xb 是同一个人的两张照片,xc 是别人。

  7. 出处:「Losses」第 61–67 段(text/06-fm-losses.txt:61,搜「triplets」)。

  8. 出处:「Losses」第 69–73 段(text/06-fm-losses.txt:72,搜「a proxy」)。原文:「the loss minimized during training is not the actual quantity one wants to optimize ultimately, but a proxy」。

  9. 出处:「Losses」第 73–77 段(text/06-fm-losses.txt:76,搜「no informative gradient」)。

  10. 出处:「Losses」第 79–91 段(text/06-fm-losses.txt:83,搜「weight de」)。原书还给了等价读法:相当于对参数放了一个「偏爱小值」的事先信念。

  11. 出处:「Autoregressive models」第 8–16 段(text/07-fm-autoregressive-models.txt:10,搜「chain rule from probability theory」)。

  12. 出处:「Autoregressive models」第 103–116 段(text/07-fm-autoregressive-models.txt:103,搜「Tokenizer」;text/07-fm-autoregressive-models.txt:113,搜「Pair Encoding」)。

  13. 出处:「Autoregressive models」第 24–47 段(text/07-fm-autoregressive-models.txt:36,搜「sampling T tokens」)。

  14. 出处:「Autoregressive models」第 49–54 段(text/07-fm-autoregressive-models.txt:51,搜「perplexity」)。原文:「the number of values of a uniform distribution with the same entropy」。

  15. 出处:「Autoregressive models」第 71–76 段(text/07-fm-autoregressive-models.txt:74,搜「extremely inefficient」)。

  16. 出处:「Autoregressive models」第 77–95 段(text/07-fm-autoregressive-models.txt:87,搜「letting the future influence the past」)。