objectives-and-evaluation.md · 可读全文

这里保留原文的中文、公式标记、代码和链接。可直接交给 Agent 读取,也可选取下方原文复制。此入口返回 HTML;原始 .md / .py 文件仍保留,完整候选包同时包含 UTF-8 原件。

# 把预测、训练与评价摊在同一张样本表上

课堂接续:[T15](https://codingai-lec05.pages.dev/classroom/T15.html?step=b0) · [T16](https://codingai-lec05.pages.dev/classroom/T16.html?step=b0) · [T17](https://codingai-lec05.pages.dev/classroom/T17.html?step=b0)。连续读本:[第2章:右移训练、loss与生成](https://codingai-lec05.pages.dev/lecture.html#chapter-2) · [第1章:计数与表示基础](https://codingai-lec05.pages.dev/lecture.html#chapter-1);本主题提供独立定义、例子、代码与来源。

同一源句为“我/昨天/给/了/他/一/本/书/。”,选定目标为 `I gave him a book yesterday . EOS`。目标、训练输入和生成输出必须先分开,才能解释一个指标到底在评价什么。

生成的下一步输入来自刚刚选择的词;训练已有参考译文,可以为每个位置提供正确历史。右移对齐如下:

|输入位置|BOS|I|gave|him|a|book|yesterday|.|
|---|---|---|---|---|---|---|---|---|
|本位置目标|I|gave|him|a|book|yesterday|.|EOS|

在gave这一输入行预测him时,可用历史只有BOS、I、gave及完整中文源句。him作为标签用于求loss,不能先送入同一预测位置。这就是teacher forcing使用真实历史的含义;所有位置的误差汇总后,通过输出头、decoder、encoder与embedding更新共享参数。

![输入gave与标签him分列,正确右移保持合法条件](https://codingai-lec05.pages.dev/assets/r72/classroom/T16-b1.svg)

训练与生成使用同一套条件概率模型,下一步历史的提供者不同。生成若选错一个词,后续条件会随之偏离真实历史;若第一个错误已经发生在两种前缀仍完全相同的位置,就不能将它归咎于更早的自馈错误。完整生成、EOS和任务评价仍须单独检查。


[阅读本主题](https://codingai-lec05.pages.dev/course/knowledge/objectives-and-evaluation.html) · [返回实验](https://deepnote.com/workspace/ise3309jingao-5ba66b0a-4283-4f5a-ae06-3f68d3201e99/project/Fall-26-Lecture-05-841ec8e7-e352-4840-b628-d3742b03d6d0/notebook/LAB-01-ec403d28cc2c400ba661cd270588669f?utm_content=ec403d28cc2c400ba661cd270588669f&utm_source=openai&utm_medium=mcp&utm_campaign=openaimcp&utm_term=get_notebook) · [与Agent共读全文](https://codingai-lec05.pages.dev/course/knowledge/objectives-and-evaluation.md.read.html)

读本:[ CLS 01 · 序列目标与共享状态 ](https://deepnote.com/workspace/ise3309jingao-5ba66b0a-4283-4f5a-ae06-3f68d3201e99/project/Fall-26-Lecture-05-841ec8e7-e352-4840-b628-d3742b03d6d0/notebook/CLS-01-b1c8e2fd764441e8820b808fc40ec3cb?utm_content=b1c8e2fd764441e8820b808fc40ec3cb&utm_source=openai&utm_medium=mcp&utm_campaign=openaimcp&utm_term=get_notebook),查找“把预测、训练与评价摊在同一张样本表上”;实验中查找“B · 同一预测目标,三个模型;训练一次,生成多次”。


<span id="objectives-and-evaluation-s01"></span>

## 目标右移一格以后,哪些位置有监督

下面切换到原合成反转任务:源序列是 `b d a d e`,参考目标是 `e d a d b EOS`,表中逐步展开这条目标的右移输入。后面的her语料另属独立算例。当前九单位翻译的完整右移已在上面给出;不能把不同任务、切分或checkpoint合并成一条运行。

|位置(从1开始)|decoder本步输入|目标|此步允许的目标历史|loss有效?|
|---|---|---|---|---|
|1|BOS|e|空前缀|是|
|2|e|d|e|是|
|3|d|a|e d|是|
|4|a|d|e d a|是|
|5|d|b|e d a d|是|
|6|b|EOS|e d a d b|是|

一个较短的 `a b c` 同批时,目标是 `c b a EOS PAD PAD`,decoder输入是 `BOS c b a EOS PAD`。后两格仍可能发生前向计算,但不计目标loss;EOS本身计入。LAB02使用PAD=0、BOS=1、EOS=2,字符a–f是3–8。输出时PAD/BOS被禁止。有效loss分母是所有非PAD目标位置数,而不是矩形总格数。

这里有三个不同的遮挡:encoder padding mask不让读取虚填源位置;causal mask不让Transformer的目标位置读取未来目标;loss mask不把PAD当真实答案。把PAD从loss里删掉,不能自动防止另一个位置读到它。RNN decoder逐步计算天然没有未来输入;Transformer并行训练必须显式保证同样的信息约束。

teacher forcing在每一步接回标准答案前缀,生成时接回模型自己已经选择的token。训练并没有把“本步答案”当本步输入;右移和mask就是为了阻止这种泄漏。真前缀下后续位置很容易,不意味着模型自己走得到那些前缀。

<span id="objectives-and-evaluation-s02"></span>

## 未见组合不是只靠多存几张表解决

假设训练文本里有 `drink hot tea` 与 `drink cold water`,从未有 `drink hot water`。三元计数模型对 `p(water|drink hot)` 给零,会把整句概率乘成零。加一平滑把每种候选先加一个伪计数,避免零概率,但也把概率分给许多不合理词。回退会在长上下文证据不足时使用 `p(water|hot)` 或更短分布;插值直接组合不同阶数。每一步都在交换具体性和估计可靠性,不是找到一个“永不出错”的补丁。

固定窗口神经网络把hot与cold等词的向量送到同一个函数,未见组合能借用参数。共享不是说不同上下文预测相同:函数相同,输入向量不同。它仍看不到窗口之外的主语或早期约定。n-gram用精确上下文计数;窗口网络用可学习函数推广;RNN把更早历史压进状态。后者让历史长度不再由输入拼接宽度固定,却没有自动解决保留和学习问题。

<span id="objectives-and-evaluation-s03"></span>

## n-gram:先限制条件,再数频率

完整前缀种类太多。n-gram 模型只保留最近 $n-1$ 个 token:

$$p(x_t\mid x_{<t})\approx p(x_t\mid x_{t-n+1:t-1}).$$

给定条件串$h$,最大似然估计为 $p(w\mid h)=C(h,w)/C(h)$。课堂取$h=\text{I gave}$,所以是包含两个条件token与一个目标token的trigram。her、him、you分别得到$3/4$、$1/4$和0。若测试句恰好包含`I gave you`,整个句子概率会变成0。这并不证明短语不合法,只说明有限训练数据没见到。

<span id="read-R08"></span>

Add-$\alpha$ 平滑把每个候选加上同样的伪计数:

$$p_\alpha(w\mid h)=\frac{C(h,w)+\alpha}{C(h)+\alpha V}.$$

平滑手算只设her、him、you三个候选,$\alpha=1$时得到$4/7,2/7,1/7$。her从$3/4$降到$4/7$,正好显示给未见项的质量要从重新分配中获得。另做一个包含结束符的四候选练习:词表为her、him、me、EOS,计数仍为3、1、0、0,则得到$4/8,2/8,1/8,1/8$;词表改变时分母必须同步改变。概率和仍为 1,但给大量未见事件分配相同质量往往过粗。另一种简单办法是插值:$p(w\mid h)=\lambda p_{\mathrm{bigram}}(w\mid h)+(1-\lambda)p_{\mathrm{unigram}}(w)$,在验证集选 $\lambda$。高阶上下文证据不足时借助低阶分布,而不是假装所有组合都已有足够统计。

更成熟的折扣与回退方法要同时考虑未见事件的概率质量和低阶估计。例如 Kneser–Ney 关心一个词出现在多少种不同前文之后,而不只看总频数;“Francisco”虽然在“San Francisco”里很多见,却未必适合接在任意前文之后。本章实现先用可核对的 add-$\alpha$ 或插值,进阶再读 [Chen 与 Goodman 对平滑方法的实证比较](https://aclanthology.org/P96-1041/)。平滑缓解数据稀疏,没有取消窗口之外的信息盲区。

<span id="read-R09"></span>

从计数表改用共享网络,首先改变的是怎样计算,而不是已经取得某种泛化成绩。以`I gave`为合法窗口,I与gave各查一个2维embedding,按顺序拼成4维输入;一组共享权重产生3维hidden,再给输出端的her、him、you、a、EOS五个演示候选各一个分数。输入embedding表另包含I、gave等token;五候选是为看清输出接口所选的局部模型,不是完整语言模型词表。因而“3维hidden”是内部表示宽度,“5维logits”才是一词一分数。不同窗口用相同参数,但输入和中间结果可以不同。

为看清最后一步,窗口算例给定五个输出分数$(\ln4,\ln2,0,0,\ln2)$;指数为$(4,2,1,1,2)$,总和10,softmax沿五个候选归一化,得到$(.4,.2,.1,.1,.2)$。这组数演示输出接口,未声称由前面的窗口运行已训练网络产生,也不等于3、1、0计数的经验频率。它让未见的you有可计算概率,但概率非零并不是“已经学会正确泛化”的证据。

分布形成以后,还有两个问题尚未回答。训练需要知道哪个词实际出现在这里,以它的负对数概率计算损失;生成需要一条选择规则,把分布变成一个要追加到前缀的词。接下来分别看loss、评价与选择规则。

<span id="objectives-and-evaluation-s04"></span>

## 一次训练:分布、loss 与梯度

当前him主例另设输出头候选him/yesterday/book,logits $(0,\ln2,\ln3)$,目标book时loss为 $-\ln(1/2)=\ln2$。这只是三候选手算,不是完整语言模型词表。下面her/a/book和第二项为真标签的构造继续保留旧独立数值,用来核对softmax梯度。

交叉熵的独立三候选例使用前缀 I gave her a、目标 book:候选 her/a/book 的 logits 为 $(0,\ln2,\ln3)$,概率为 $(1/6,1/3,1/2)$,损失为 $-\ln(1/2)\approx0.693147$,梯度为 $(1/6,1/3,-1/2)$。它与前面的五候选网络是两个明确分开的规模选择。

作为另一项独立三候选练习,设三个候选 token 的 logits 为 $(\log2,0,0)$,则 softmax 为 $(1/2,1/4,1/4)$。若真实目标是第二个 token,交叉熵为 $-\log(1/4)=\log4\approx1.386$。模型虽然给出了三个概率,训练损失只从真实标签取出对应的负对数;但反向传播会调整所有 logits:

$$\frac{\partial\ell}{\partial a_j}=p_j-\mathbb 1[j=y].$$

本例梯度为 $(0.5,-0.75,0.25)$。梯度下降在直接调整 logits 的局部直觉上会降低错误候选、提高目标候选;实际网络参数同时影响许多样本,不能保证每次更新让全部位置都变好。稳定 softmax 应先减去最大 logit;这个平移不改变分布。

<span id="read-R11"></span>

训练答案并不需要每个位置另请人标注。对一条现成文本,当前前缀就是输入,紧接着的token就是标签;沿句子移动位置,就重复得到同一类训练问题。模型看见标签来计算损失,与模型把标签提前作为预测条件,是两回事。

对“I gave her a book yesterday .”,输入可写为“BOS I gave her a book yesterday .”,对应目标为“I gave her a book yesterday . EOS”。在输入 gave 的位置预测 her,在输入 book 的位置预测 yesterday。错位一格的目的,是防止把当前答案直接作为当前预测的输入。后面 causal mask 允许读取本位置,也必须和这个错位约定一起理解。

给定一条训练样本,负对数似然为

$$L=-\sum_{t=1}^{T+1}\log p_\theta(x_t\mid x_{<t}).$$

这里临时用x表示通用语言模型的文本序列;翻译时恢复独立源条件,写成 $L=-\sum_t\log p_\theta(y_t\mid y_{<t},x_{src})$。目标语言评分与条件翻译共用概率形式,但不能省掉后者的源信息责任。

原本连乘的概率变成求和,数值更稳定,也能逐位置追踪错误。训练用真实前缀,因为目标正是估计数据在这些条件下的概率。部署时前缀里可能有模型自己的输出,两种条件分布并不总相同。


批量训练遇到不同长度序列时,PAD 只是补齐工具。应从损失与 token 计数中排除 PAD,明确是否计入 EOS。若对每个批次先求平均、最后又等权平均批次,大小不同的批次可能被错误加权。想得到整套测试语料的平均负对数似然,应先累加总负对数似然,再除以实际目标 token 总数。

<span id="read-R12"></span>

<span id="objectives-and-evaluation-s05"></span>

## 四个指标回答四种问题

![旧版独立扩展:每个右移位置的loss回传共享参数](https://codingai-lec05.pages.dev/assets/r71/classroom/S09-b2.svg)

在给定正确前缀时,token NLL看模型给正确token多少概率;token accuracy只看argmax是否正确;自由生成exact match要求整条输出(本课含EOS)完全等于目标;翻译评价还要处理不同措辞表达同一意思。合成反转只有一个精确目标,真实翻译通常有多个合格表达。

有一个不需训练的反例:三个二分类位置的真类概率从(.6,.6,.6)变为(.9,.9,.4)。平均NLL从0.510826降到0.375671,但argmax正确率从3/3降到2/3。前两处的概率改善抵过第三处的损失。它是构造算例,不是LAB02的训练曲线。真实checkpoint的97.77%真前缀token正确率与87%自由生成整句正确率,也用了不同输入条件与分母,不能简单相除来估计“错误传播率”。

<span id="objectives-and-evaluation-s06"></span>

## BLEU 到底计算了什么

BLEU 衡量候选译文与参考译文的 n-gram 重合。修改过的精确率会剪裁重复计数:候选某 n-gram 出现十次,参考只出现一次,不能得十分。对每个阶数 $n$,先在整套评价语料汇总剪裁后的匹配数和候选 n-gram 总数,得到 $p_n$,再计算

$$\mathrm{BLEU}=\mathrm{BP}\exp\left(\sum_{n=1}^{N}w_n\log p_n\right),\qquad
\mathrm{BP}=\begin{cases}1&c>r,\\ \exp(1-r/c)&0<c\le r.\end{cases}$$

$c$ 是候选总长度,$r$ 是按规定选择的参考长度总和。空候选单独记为零分。常见 BLEU-4 取四阶等权;这里用 BLEU-2 展示可手算机制。参考为“I gave her a book yesterday”,候选为“I gave a book yesterday”,均保留大小写、移除句末标点。候选的五个 unigram 全匹配,$p_1=5/5=1$;四个 bigram 为 I gave、gave a、a book、book yesterday,其中三个匹配,$p_2=3/4$。候选长 5,参考长 6,故

$$\mathrm{BLEU}_2=e^{-0.2}\sqrt{3/4}\approx0.7090,$$

按百分制约为 70.90。这个高分候选漏掉了接受者 her,正好暴露局部重合与忠实性之间的差别。若候选只有“the the the”,unigram 计数也必须按参考里 the 的出现次数剪裁,不能靠重复提高得分。原始定义见 [Papineni 等,BLEU,§2](https://aclanthology.org/P02-1040/)。

单句很短时,高阶 n-gram 可能完全不匹配,使未平滑 BLEU 变成零;不同平滑方法会给不同值。语料 BLEU 不是先算每句 BLEU 再取平均。分词、大小写、参考数、平滑和实现版本都需要记录。BLEU 适合比较固定条件下的系统,却不能判断所有同义改写,更不单独证明事实或语义正确。实验 D 同时看精确序列匹配、任务字段正确率和完整输出,会比只看一个分数更有解释力。

漏掉her仍有较高BLEU-2,是因为局部n-gram重合与长度惩罚不能完整表达施事/受事和省略的严重性。上面的单句教学值不是标准语料成绩。语料BLEU把全语料剪裁匹配数、候选n-gram数、有效参考长度汇总后计算,不是单句BLEU的平均。报告实际翻译基准还要给tokenizer、大小写、多参考、平滑与工具版本;只写“BLEU提高2”不足以复现。

<span id="objectives-and-evaluation-s07"></span>

## 从概率到候选,再到一句完整输出

greedy每步取最大概率;beam保留若干累计分数高的前缀,扩展后再筛;二者试图搜索模型偏好的输出。采样则允许在分布内产生变化,并不以找最大概率句为目标。

教学分布(A,B,C,D)=(.50,.25,.15,.10):温度T=2把每项开平方再归一,约为(0.3701,0.2617,0.2027,0.1655)。top-k=2只留A/B再归一;top-p=.7在原分布上要留A/B,因为首项.5未过阈值、前两项.75达到阈值。若先调温度再做top-p,集合可能变成A/B/C;因此实现必须写顺序。候选外概率置零之后,总质量需要重新归一。NLL评价使用原模型分布,不使用被采样策略改过的分布。

EOS也在候选里;不生成它就只是被最大步数截断,不算模型宣告结束。累计log概率通常惩罚更多乘法项,因此不同长度的比较会偏向短句;长度惩罚改变排序规则,但不等于给模型补上缺失事实。接着读路径A:同一个已经失败的样本,搜索到底有没有把正确序列留在beam里?

来源:同版读本第一至三章;M07–M11/M16;[BLEU原论文§2](https://aclanthology.org/P02-1040.pdf)。本节字符样本来自DN1存档测试集,其真实推理结果在“训练与生成”主题;n-gram与三位置NLL例是教学构造。


<span id="objectives-and-evaluation-s08"></span>

## 相邻知识与复核资源

[同一句话怎样成为分析对象与模型输入](https://codingai-lec05.pages.dev/course/knowledge/text-units-and-representations.html) · [状态在流动,梯度可以停在边界](https://codingai-lec05.pages.dev/course/knowledge/recurrent-state-and-credit.html)

[全部主题](https://codingai-lec05.pages.dev/course/knowledge/index.html) · [关键结果JSON](https://codingai-lec05.pages.dev/course/knowledge/data/learning-paths.json) · [只读诊断源码](https://codingai-lec05.pages.dev/course/knowledge/code/learning_paths.py.read.html) · [Seq2Seq完整实现](https://codingai-lec05.pages.dev/course/knowledge/code/seq2seq.py.read.html) · [视觉机制实现](https://codingai-lec05.pages.dev/course/knowledge/code/mechanisms.py.read.html) · [TinyDecoder与cache实现](https://codingai-lec05.pages.dev/course/knowledge/code/legacy_numpy.py.read.html)