假设你请了一位师傅教徒弟写作文,题目是“描写下雨天”。徒弟没法一口气写完,只能先写第一个词,然后根据自己刚写下的内容,再决定第二个词怎么写——每一句都站在前一句的肩膀上。问题来了:如果徒弟第二句就写了一个别扭的词,第三句就会在这个错误基础上继续编,越写越离谱,整篇作文崩盘。聪明的师傅有妙招——“你先别管前面,我把正确的前文写给你,你只管练好'当前这一句'怎么写。”这样徒弟能专注打磨每一步的功力,训练又快又稳。这个技巧,就是深度学习里的 Teacher Forcing(教师强制):训练时把“标准答案”喂给模型当上下文,让它每一步都从正确位置出发。但期末考试(推理)时师傅不在场,模型必须用自己的产出继续写,这时“一步错、步步错”的暴露偏差就出现了。本篇把这个故事讲透:原理、实现、问题、改进与工程实战,带你彻底吃透这个序列模型训练的标准技巧。
机器翻译、文本生成等序列任务都依赖 Teacher Forcing 才能稳定训练;它是 NLP 面试高频考点,也是你从“跑通模型”走向“训好模型”的必修课。
可视化演示
展示Seq2Seq中Teacher Forcing训练方法:编码器处理、GT输入训练、推理暴露偏差与Scheduled Sampling改进,分步交互查看。
本节配有交互动效(进入视口后自动加载,约 3KB)。
编码器处理:输入序列编码为上下文向量 输入token逐个送入Encoder 编码为固定维度的上下文向量C C = Encoder(x_1, x_2, ..., x_n) 上下文向量C作为Decoder的初始输入,驱动逐步生成。
序列模型基础
想象你请了一位师傅教徒弟写作文,题目是“描写下雨天”。徒弟不能一口气写完,只能先写第一个词,然后根据自己写下的内容,再写第二个词……这种“自己写完的话,决定下一句话”的过程,就像滚绣球一样一环扣一环。师傅没法跳过过程直接教结果,只能一个词一个词地陪练。
在深度学习里,“给一句话,生成另一句话”的任务由 Seq2Seq(序列到序列)模型承担。它像一个两人小组:编码器负责把输入的句子“读进脑子里”,压缩成一个隐状态;解码器负责从这个记忆出发,一个词一个词地把答案吐出来。解码器每吐出一个词,这个词又会被当作“已写出的前文”,参与下一个词的预测。这种“用自己的输出续写”的性质,叫作自回归——你可以理解为“自己接自己话”。
数学上,模型对整句输出的概率可以写作逐词条件概率的连乘:给定输入 X,最终输出句子 Y 的概率,等于每个位置在“已知它前面所有词和 X”时的条件概率相乘。
这里藏着整个故事的关键:公式里的“前文”到底由谁提供?如果由师傅(真实标签)提供,就是教师强制;如果由徒弟(模型自己)提供,就是推理时的自回归。一字之差,训练结果天差地别。
- 条件概率P(y_t | ……) 表示在给定前面所有词和输入序列的前提下,第 t 个位置是词 y_t 的可能性有多大,也就是“已知前文,猜下一个词”。
- 连乘记号∏_{t=1}^{T} 把每个位置猜对的概率乘起来,只有每个词都对,整句才算对,所以用乘法。
- 前文依赖y_1 到 y_{t-1} 是当前词之前的所有词。注意它们是谁提供的(标准答案还是自己写的),将直接影响训练效果——这正是后面几节的伏笔。
核心思想
如果让徒弟从第一个字就自己写,写错了师傅再去纠正,徒弟容易越错越远:第二句错,第三句就在错的基础上继续错。聪明的师傅换了个策略——“你只管写当前这个词,前面该有什么,我给你标准答案。”训练时,模型每一步的输入都被“强制”替换成真实标注的词(ground truth,即人工标注的标准答案),而不是它自己的预测。这就是 Teacher Forcing,直译“教师强制”。
技术上说,在训练阶段,解码器第 t 步的输入是真实标签序列中的 y_{t-1}^*,而非模型上一步的输出。模型只需要学习“在正确的前文下,下一步该说什么”。因为每一步都站在正确的位置上,误差不会在句子内部滚雪球,梯度信号也清晰,训练更快收敛——这正是它成为机器翻译等任务标配训练技巧的原因。
训练目标因此写成“在真实标签序列上的最大似然”:每个位置,模型给真实标签的概率越大,损失越小。
一句话概括:师傅每时每刻都把“正确的上一句”递到徒弟手边,徒弟只需要练好“写下一句”这一个动作。这正是 Teacher Forcing 能让训练又稳又快的根本原因。
- 标准答案标记y_t^* 的上标星号代表这是人工标注的真实词,不是模型自己生成的词。
- 条件概率 P_θ模型在参数 θ 下,预测“下一个词是标准答案”的概率,概率越大说明模型越懂这个位置。
- 对数似然对概率取对数再取负,把“最大化概率”变成“最小化损失”,方便梯度下降优化。
- 平均损失对所有位置的损失求和再除以 T,得到这条样本的平均损失,方便不同长度句子之间比较。
实现方式
具体到代码层面,这个“递标准答案”的动作怎么落地?其实就一句话:把解码器每一步的输入,从“模型上一时刻的输出”换成“上一时刻的真实标签”。在 PyTorch 这类框架里,就是在时间步循环里把 decoder_input 直接赋值为 target[:, t](真实标签),而不是 decoder_output。
更形式化地,训练与推理阶段对解码器输入的设定可以写成下面这个分情况公式,它像一道岔路口:左边通往“师傅代笔”,右边通往“自己动笔”。
工程上还有几个细节:序列开头要插入起始符 <sos>,让模型知道“现在开始生成”;训练时每个位置独立计算交叉熵损失再平均;教师强制的“标签”必须是训练语料里的真实词,不能是模型的高置信预测。把这些细节串起来,就是一个标准的 Teacher Forcing 训练循环——师傅逐词示范,徒弟逐词模仿。
- 训练分支input_t = y_{t-1}^*,也就是上一步的标准答案,模型在第 t 步看到的是“标准答案版本”的前文。
- 推理分支input_t = \hat{y}_{t-1},这是模型上一步自己 argmax 出来的词。推理时没有标准答案,只能自食其果。
- 分情况讨论花括号把两种模式并列在一起,强调它们唯一的区别就在于“上一步输入由谁提供”。
暴露偏差问题
期末考试到了,师傅不在场。徒弟在考场上写作文,第一句、第二句都顺利,第三句写错了一个字。接下来怎么办?他只能在自己写错的句子上继续往下编,于是第四句跟着错、第五句错得更远,最后整篇作文面目全非。问题不在徒弟“变笨了”,而在于他从来没有在“自己的错误前文”上练习过续写。
这正是暴露偏差(exposure bias):训练时,模型看到的输入永远来自真实标签分布(师傅代笔的前文);推理时,模型面对的输入却来自自己的输出分布(自己写的前文)。两种分布不一致,模型一旦在推理中途出错,错误就会顺着自回归链路一路传导,像滚雪球一样越滚越大。
把这一点量化,感受会更直观。假设模型每一步出错的概率是 ε,那么生成一个长度为 T 的句子,至少出现一处错误的概率是:
既然错误会滚雪球,那解决办法只有一个方向:让训练阶段也“见到”模型自己的错误输出,提前锻炼它在不完美前文下“爬出来”的能力。怎么做到?请看下一节师傅的放手艺术——计划采样。
- 单步正确率1-ε 表示模型某一步生成正确的概率,ε 越小说明单步越可靠。
- 连乘累积(1-ε)^T 是所有 T 步全部正确的概率,每一步都对,整句才可能对。
- 互补事件用 1 减去“全对”的概率,得到“至少错一处”的概率。当 T 很大时,这个概率趋近于 1,说明长序列几乎必然出岔子。
计划采样改进
聪明的师傅从来不是“第一天就撒手”,而是扶一段、放一段:前期步步把稳,等徒弟动作熟练了,再故意让他自己走两步,摔一下,学会自我纠偏。这个思想落到训练里,就是 Scheduled Sampling(计划采样,也叫调度采样)。
计划采样的做法很朴素:每一步以一个概率 ε 继续使用真实标签作为输入,以 1-ε 的概率改用模型自己的输出作为输入。也就是说,训练时解码器的输入是两种来源的随机混合,训练早期 ε 接近 1(师傅全程扶着),训练后期 ε 逐渐变小(师傅逐渐放手),模型慢慢适应“用自己写的前文续写”。
ε 怎么随时间变化?常用指数退火:训练轮数(epoch)越大,ε 越小。典型设置如下,先纯教师训练把模型扶稳,再让 ε 缓慢下降。
回看比喻:计划采样就是“循序渐进地放手”。ε 退火太快,徒弟摔得太狠,训练崩溃;太慢,徒弟永远依赖师傅代笔,考试照样翻车。两者之间的分寸,正是调参工程师的功夫。
- 初始值 ε0训练刚开始时 ε 通常设为 1,即先纯教师强制把模型“扶稳”。
- 衰减率 kk 是 0 到 1 之间的数,epoch 越大,k^epoch 越小,ε 单调下降。
- 下限 ε_minε 不会衰减到 0,而是稳定在一个小值(如 0.1),保证训练始终带一点“脚手架”,防止完全放飞后训练震荡。
其他改进方案
计划采样是“调整训练时的输入”,还有三套思路从不同角度对付暴露偏差:换考试策略、按整篇打分、多练题型。它们可以和计划采样组合使用,像给徒弟配齐了草稿纸、评分表和题库。
第一套是 Beam Search(束搜索)。推理时不再一个个词取最大概率,而是每一步都保留概率最高的 B 条候选路径,到最后整句一起评分。这就像期末考试时同时打几份草稿,最后挑最通顺的一份交上去。它不改变训练,只改变“怎么从模型概率里抽取结果”,能显著缓解单步失误被永久放大的问题。
第二套是强化学习(RL)。Teacher Forcing 优化的是“每一步词对不对”,但用户真正关心的是整句质量(比如 BLEU 分数,一种衡量机器翻译和参考译文相似度的指标)。RL 直接把整句指标作为奖励,目标变成“生成句子的期望奖励最大化”:
第三套是数据增强:通过回译、同义词替换、句式改写,让训练语料覆盖更多样化的“正确前文”,相当于让徒弟多练不同题材的范文。师傅给的标准答案见得越多,模型对前文的适应力越强,暴露偏差自然减轻。四套方案各有侧重:改输入(计划采样)、改解码(Beam Search)、改目标(RL)、改数据(增强),工程里常常组合出牌。
- 期望操作E_{Y ~ P_θ} 表示按模型自己的生成分布采样出句子,再对这些句子的奖励取平均。
- 奖励函数 R(Y)BLEU、ROUGE 等自动指标,相当于给整篇作文打分。奖励越大,这段路径在参数更新中被加强得越多。
工程实践经验
把前六节落到真实项目里,师傅的排课表是这样的:先用纯 Teacher Forcing 把模型训练到初步收敛(比如机器翻译模型的 BLEU 不再明显上涨);再切换计划采样,让 ε 随 epoch 退火,让模型适应自由运行;最后在评估集上以“自由运行”模式计算指标——注意,评估必须模拟推理环境,不能用教师强制,否则指标虚高,上线就露馅。
几个高频技巧值得记住。第一,标签平滑:把 one-hot 硬标签软化,避免模型对训练集过度自信,从而提升泛化能力:
第二,训练早期配合梯度裁剪和 warmup(先把学习率从小往大热起来),防止崩溃;第三,Teacher Forcing 的收敛曲线很漂亮,但别被它骗了——线上指标一定要看“自由运行”的翻译结果;第四,上线后监控长句生成质量,如果末尾出现胡言乱语,优先检查 ε 退火曲线和 beam size。回看整个比喻:训练是师傅扶着走,评估是模拟独自上路,上线才是真正的期末考试。把每一步都安排好,徒弟才能从考场全身而退。
- 硬标签 y真实标签的 one-hot 向量,正确词位置为 1,其余为 0。
- 平滑系数 α通常取 0.1 左右,α 越大,标签被抹得越平。
- 均分项 α/V把 α 的概率平均分给 V 个词,相当于给每个词一点点“可能性”,防止模型过度自信。
AI 应用场景
机器翻译平台训练
阶段:模型训练与优化
解决的问题:电商平台需要把商品描述批量从英文翻译成中文。传统做法是逐词拼接规则翻译,质量差且无法处理长句;改用 Seq2Seq 生成式翻译后,如果训练时不用 Teacher Forcing,模型早期生成的每个词都是垃圾,梯度充满噪声,训练几天都不收敛,甚至直接崩溃。
具体案例:某跨境电商团队用 Transformer 训练英中翻译模型,先以纯 Teacher Forcing 训练 20 个 epoch 让 BLEU 稳定上涨,再切到计划采样,ε 从 1.0 指数退火到 0.1,最后在评估集上用自由运行模式计算 BLEU 并调 beam size。上线后长句翻译的“末尾胡言乱语”明显减少,人工抽检通过率从 71% 提升到 89%。
智能客服话术生成
阶段:对话模型训练与调优
解决的问题:客服机器人的回复如果逐句自由生成,用户提问稍有偏差,模型就会在错误前文上“越描越黑”,输出前后矛盾的答案。Teacher Forcing 让它先学会“在标准话术下接话”,计划采样再让它适应真实对话中的口语化输入。
具体案例:某银行智能客服每天处理数十万次咨询。训练话术生成模型时,工程师把历史优质对话作为真实标签,前 10 个 epoch 全量 Teacher Forcing,之后每轮把教师比例降低 5%,并配合束搜索(beam size=5)解码。上线后回复的语义连贯性打分提升显著,需要人工兜底的比例下降约 40%。
新闻标题自动生成
阶段:文本摘要模型训练与评估
解决的问题:给长篇新闻自动生成标题,输出是一整段浓缩文本,比单句翻译更容易积累错误——开头一个小错,结尾可能完全跑题。单纯依赖 Teacher Forcing 会让模型“没见过自己的错”,摘要质量虚高。
具体案例:某资讯 App 用 BART 做标题生成,训练中采用“教师强制 + 计划采样 + 标签平滑”的组合拳,评估阶段专门用自由运行输出与人工标题对比 ROUGE 分数。经过两轮退火调参,标题可读性明显改善,编辑人工改写率从 55% 降到 32%。
Python 演示
import numpy as np V, T, H = 8, 5, 16 # 词表大小、序列长度、隐层维度LR = 0.3 def onehot(ids): """整数id或id数组转one-hot向量""" if isinstance(ids, int): ids = [ids] out = np.zeros((len(ids), V)) out[np.arange(len(ids)), ids] = 1.0 return out def make_batch(n=32, seed=0): """构造“倒序”任务:模型要学会把输入序列倒过来输出""" rng = np.random.default_rng(seed) src = rng.integers(1, V, (n, T)) return src, src[:, ::-1] class ToyRNN: def __init__(self): rng = np.random.default_rng(0) self.Wxh = rng.normal(0, 0.1, (V, H)) self.Whh = rng.normal(0, 0.1, (H, H)) self.Why = rng.normal(0, 0.1, (H, V)) self.bh = np.zeros(H) self.by = np.zeros(V) def step(self, x, h): h = np.tanh(x @ self.Wxh + h @ self.Whh + self.bh) z = h @ self.Why + self.by p = np.exp(z - z.max()) return h, p / p.sum() def train_step(self, src, tgt, ratio, lr=LR): """一次BPTT更新。ratio=真实标签被选作下一步输入的概率""" xs = onehot(src) h, hs, ps, loss = np.zeros(H), [np.zeros(H)], [], 0.0 for t in range(T): h, p = self.step(xs[t], h) hs.append(h) ps.append(p) loss += -np.log(p[tgt[t]] + 1e-9) if t < T - 1: nxt = tgt[t + 1] if np.random.rand() < ratio else int(np.argmax(p)) xs[t + 1] = onehot(nxt)[0] dWxh = np.zeros_like(self.Wxh) dWhh = np.zeros_like(self.Whh) dWhy = np.zeros_like(self.Why) dbh, dby = np.zeros(H), np.zeros(V) dh_next = np.zeros(H) for t in reversed(range(T)): dz = ps[t].copy() dz[tgt[t]] -= 1.0 dWhy += np.outer(hs[t + 1], dz) dby += dz dh = dz @ self.Why.T + dh_next dh_raw = (1 - hs[t + 1] ** 2) * dh dWxh += np.outer(xs[t], dh_raw) dWhh += np.outer(hs[t], dh_raw) dbh += dh_raw dh_next = dh_raw @ self.Whh.T for w, dw in ((self.Wxh, dWxh), (self.Whh, dWhh), (self.Why, dWhy), (self.bh, dbh), (self.by, dby)): w -= lr * dw return loss / T def infer(self, src): """推理:完全用模型自己的上一步输出作为下一步输入""" xs = onehot(src) h, preds = np.zeros(H), [] for t in range(T): h, p = self.step(xs[t], h) preds.append(int(np.argmax(p))) if t < T - 1: xs[t + 1] = onehot(preds[-1])[0] return np.array(preds) def evaluate(model, n=60): src, tgt = make_batch(n, seed=7) return float(np.mean([np.mean(model.infer(src[i]) == tgt[i]) for i in range(n)])) def train(model, ratio, epochs=150): for ep in range(epochs): src, tgt = make_batch(32, seed=ep) for i in range(32): model.train_step(src[i], tgt[i], ratio) def main(): for name, ratio in (('教师强制', 1.0), ('自由运行', 0.0), ('计划采样', 0.7)): model = ToyRNN() train(model, ratio) print('%s: 推理准确率 %.2f' % (name, evaluate(model))) if __name__ == '__main__': main()
nxt = tgt[t + 1] if np.random.rand() < ratio else int(np.argmax(p))教师强制的核心:按概率决定这一步喂真实标签还是模型自己的输出。xs[t + 1] = onehot(nxt)[0]把选中的 token 编码后注入下一时刻的输入,这就是“前文替换机制”的落地。dz[tgt[t]] -= 1.0softmax 交叉熵对 logits 的梯度,等于预测概率减去真实标签的 one-hot,是整个反向传播的关键一行。for w, dw in ((self.Wxh, dWxh), ...)一行循环把 5 组参数全部按梯度更新,等价于优化器的一步。preds.append(int(np.argmax(p)))推理时用模型自己上一步的输出作为下一步输入,这正是暴露偏差的来源。print('%s: 推理准确率 %.2f' % (name, evaluate(model)))用自由运行模式评估,三种训练策略高下立判:教师强制训练稳但评估暴露问题,计划采样最接近实用。
常见误区
误区“模型推理时,我也可以把标准答案手动喂进去,这样输出肯定更准。既然训练时是这么干的,推理时也照做不就行了?”
正解推理时根本没有标准答案可用——如果有,就不需要模型了。Teacher Forcing 只能在训练阶段使用,因为它依赖真实标签;推理时模型只能用自己上一步的输出。这就好比期末考试,师傅不会坐到考场里帮徒弟写前文。训练时“扶着走”是为了学本领,考场上“独自走”才是真正的检验。
为何常见:初学者容易把“训练技巧”误当成“通用推理手段”,没有意识到 Teacher Forcing 依赖人工标注数据这个前提。
误区“既然 Teacher Forcing 会造成训练和推理不一致,那干脆完全不用的好,直接用模型自己的输出训练,训练和推理就完全一致了。”
正解完全自由运行的训练在早期几乎无法收敛:模型第一步输出就是垃圾,后面的梯度充满噪声,训练曲线剧烈震荡甚至直接炸掉。Teacher Forcing 的价值是“扶着走”的脚手架,让模型先学会单步能力;真要解决不一致,应该用计划采样逐步放手,而不是从悬崖边直接跳下去。
为何常见:只看到了 Teacher Forcing 的“不一致”缺点,没看到它是让前期训练稳定的必要手段。
误区“Teacher Forcing 名字里带 Teacher,和课程学习一样,都是让模型由易到难学习。”
正解课程学习是“按难度排序训练数据”,Teacher Forcing 是“用真实标签替换模型输出作为输入”,机制完全不同。不过计划采样(Scheduled Sampling)确实有点课程学习的味道:先全真值(简单)、后自输出(困难),但它只是 Teacher Forcing 的一个改进版。名字像,机理不同,别混为一谈。
为何常见:中文语境里“教师”“课程”容易引发联想混淆,缺乏对机制层面的区分。
误区“训练时模型每步都有真实标签,所以训练阶段根本不会犯错,暴露偏差是推理阶段才出现的问题。”
正解暴露偏差恰恰是指“训练和推理的输入分布不一致”:训练时模型从未把自己的错误输出当作输入,推理时却必须这么做。问题出在“训练时没见过这种输入”,而不是“推理时突然变笨”。用计划采样,就是让训练阶段也模拟推理时的输入分布,提前打预防针。
为何常见:把现象(推理崩坏)当成了原因(训练策略导致的分布不一致),没有意识到问题在训练时就已经埋下。
误区“计划采样混合了真实标签和模型输出,那教师比例 ε 一直设成 0.9,模型学得又快又稳,应该是最优解。”
正解ε 恒高等于几乎一直在用 Teacher Forcing,暴露偏差依旧存在。ε 应该是“前期大、后期小”的退火曲线,否则模型永远学不会自我纠错。经验做法是:先全 Teacher Forcing 若干 epoch,再让 ε 指数或线性衰减到 0.1 甚至 0.05,让模型逐步适应自由运行环境。
为何常见:把“训练稳”当成了唯一目标,忽略了最终要适应推理时“没有师傅”的环境。
面试题
Q1. 在 Seq2Seq 训练中使用 Teacher Forcing 时,解码器第 t 步的输入是什么?
- A.模型上一步预测的词
- B.上一步的真实标签← 正确答案
- C.编码器的末层隐状态
- D.随机采样的一个词
答案:B。Teacher Forcing 的核心就是用上一步的真实标签替换模型自己的输出作为输入,让模型每一步都从正确位置出发。就像师傅递给徒弟标准答案前文。模型上一步预测词只在推理时使用。
Q2. 模型在测试(推理)阶段生成下一个词时,输入是什么?
- A.上一步的真实标签
- B.自己上一步生成的词← 正确答案
- C.训练集的平均词向量
- D.不需要任何输入
答案:B。推理时没有真实标签可用,模型只能把自己上一步生成的词当作输入,这是自回归的必然要求,也是暴露偏差产生的根本背景。师傅不在考场,徒弟只能接自己的话。
Q3. Teacher Forcing 带来的最主要好处是?
- A.显著减小模型参数量
- B.训练更稳定且收敛更快← 正确答案
- C.推理速度提升数倍
- D.不再需要人工标注数据
答案:B。Teacher Forcing 让每一步输入都是正确的标准答案前文,误差不会在句子内部滚雪球,梯度信号清晰,所以训练稳定、收敛快。它既不改变模型大小,也不影响推理速度,更不省标注。
Q4. “暴露偏差”的核心原因是?
- A.训练数据被恶意污染
- B.训练与推理的输入分布不一致← 正确答案
- C.梯度在反向传播中消失
- D.词表过大导致显存不足
答案:B。训练时输入来自真实标签分布,推理时输入来自模型自己的输出分布,两种分布不一致导致模型面对陌生输入时错误累积。这是训练策略与推理方式之间的错位,并非数据或硬件问题。
Q5. Scheduled Sampling 中,ε 表示什么?
- A.使用真实标签作为输入的概率← 正确答案
- B.使用模型输出作为输入的概率
- C.模型的学习率衰减系数
- D.词表中被屏蔽词的比例
答案:A。计划采样中 ε 是“教师信号保留概率”:以 ε 概率用真实标签,以 1-ε 概率用模型自输出。ε 大等于多扶着走,ε 小等于多放手,与学习率和词表屏蔽无关。
Q6. 训练初期,计划采样中的 ε 通常设置为?
- A.接近 0
- B.接近 1← 正确答案
- C.固定 0.5
- D.随机波动
答案:B。训练初期模型能力弱,需要师傅多扶,ε 一般取接近 1(甚至直接取 1 纯 Teacher Forcing 若干轮),再随训练推进退火下降。一上来就放手会让训练崩溃。
Q7. 关于 Teacher Forcing 理解正确的有哪些?
- A.训练时用真实标签替代模型上一步输出← 正确答案
- B.推理阶段也依赖真实标签输入
- C.能使训练损失曲线更平滑← 正确答案
- D.可完全消除推理阶段的所有错误
答案:AC。A 是定义本身,C 是稳定收敛的直接表现。B 错误,推理时没有真实标签;D 错误,暴露偏差只是被缓解,无法被完全消除,长句仍可能出错。
Q8. 关于计划采样退火公式 ε = max(ε_min, ε0·k^epoch),下列说法正确的是?
- A.k 越大说明退火越快,模型很快完全自跑
- B.ε_min 通常取接近 1 的值以保持训练稳定
- C.ε0 一般初始设为 1,即早期全用真实标签← 正确答案
- D.退火只在每个 batch 内部进行衰减
答案:C。k 在 0~1 之间,k 越大衰减越慢;ε_min 通常接近 0,只是下限保护;退火按 epoch 或 step 进行,不是只在 batch 内部。ε0 初始为 1 是先扶稳再放手的标准做法。
Q9. 下列哪些策略可以缓解暴露偏差或长序列退化?
- A.Scheduled Sampling 混合真实标签与模型输出← 正确答案
- B.Beam Search 解码时保留多条候选路径← 正确答案
- C.用 BLEU 等序列指标构造强化学习目标← 正确答案
- D.训练时完全禁止真实标签进入解码器
答案:ABC。计划采样让训练适应自身输出分布,束搜索通过多路径降低单步错误被放大的风险,强化学习直接优化整句指标。D 完全禁止真实标签会让训练无法稳定起步,反而更糟。
Q10. Teacher Forcing 训练使用的损失函数本质上是?
- A.模型输出与真实标签的交叉熵← 正确答案
- B.预测值与标签的均方误差
- C.编码器与解码器的余弦相似度
- D.生成样本的对抗判别损失
答案:A。每个位置都在最大化“真实标签词被预测出来的概率”,等价于最小化预测分布与真实 one-hot 标签之间的交叉熵。MSE 不适合离散词表,余弦相似度与对抗损失都不是序列生成的标配。