1 RNN 与序列模型要回答什么
预测顾客是否流失时,每行可以放入最近 30 天的登录次数、累计付费金额和账户年龄。这样的表格把经历压缩成特征,模型未必知道登录发生的先后顺序。图像分类通常接收空间排列的像素;短文本分类则接收有顺序的词。“这部电影并不好看”和“这部电影并非不好看”包含相近的词,却表达不同倾向。序列模型要回答的是:当前输入的含义如何受到此前输入的影响,以及这种影响怎样用于预测。
序列并不等于带有时间戳的数据表。将用户编号从小到大排列,再把不同用户的流失记录连接起来,并没有产生有意义的经历。相反,句子即使没有时间戳,词的位置也决定了上下文。判断是否需要序列模型,应先问:如果交换位置,目标的含义是否改变;如果删去前文,当前信息是否仍足够。答案指向顺序作用时,才有必要付出保存和处理历史的成本。
循环神经网络,即 RNN,用隐藏状态保存随输入更新的信息。它读取当前词,同时读取此前状态,再产生新的状态。对于评论情感分类,可以在读完整篇评论后,把最终状态交给分类器,输出“正面”的概率。对于逐日风险预测,也可以在每个时间步输出概率。本课主要讨论前者,避免把整段分类、逐步预测和生成文本的目标混在同个实验中。
公开的 IMDb 影评情感数据适合作为贯穿示例:输入是英文影评,标签是正面或负面,任务是预测整段评论的倾向。这里的词序、否定词和转折关系都有实际意义。后文用中文短句解释机制,实验仍使用原始英文文本。不能把英文影评上的指标直接当成中文客服消息的性能,也不能因为都叫“情感分类”就省略新领域验证。
开始建模前,还要设立不使用顺序的参照。可以用训练集学习的 TF-IDF 特征配合逻辑回归,观察只看词语统计能做到什么。如果它已经满足需求,RNN 的复杂性就需要额外收益来说明。反过来,如果顺序敏感样本上的错误减少,而总分变化很小,也可能意味着新模型解决了特定问题。评价应同时覆盖总体表现、关键样本和运行成本。

2 隐藏状态、展开与长度边界
把隐藏状态想成边读边改的笔记,比把它理解成完整记忆更准确。读到“剧情”时,笔记可能记录讨论对象;读到“并不”时,笔记需要保留否定线索;读到“精彩”时,模型应结合此前线索更新判断。状态是固定长度的数值向量,无法保证原样保存所有文字,也没有供人直接阅读的“否定词栏”。哪些信息被保留,需要通过训练获得。
基础 RNN 的更新可简写为 h_t = tanh(W_x x_t + W_h h_(t-1) + b)。其中 x_t 是当前位置的词向量,h_t 是新状态,权重在所有位置共享。词向量把词编号映射成可训练的数值表示;词编号本身的大小不代表词义远近。初始状态常设为 0,不同评论通常各自重新初始化。整段分类可用 p = sigmoid(w·h_T + c) 输出正面概率,再按阈值形成类别。
所谓“展开”,就是把同个更新规则沿位置画开。图上出现多个方框,表示不同位置的计算,并非每个位置都有独立模型。共享权重使模型可以处理不同长度的输入,也让“好看”出现在句首或句尾时使用同套参数。位置仍然会影响结果,因为进入这个方框的旧状态不同。理解这一点,才能解释为什么交换词序可能改变预测。
长度至少有 3 种:原文分词后的真实长度、送入模型的有效长度、批处理为了对齐而补齐后的张量长度。例如评论有 73 个词,批内上限是 128,补齐产生的 55 个位置只是占位。若不处理这些位置,模型可能继续更新状态,让最终分类依赖补齐数量。实现时可使用长度信息打包序列,或者按真实末尾位置取状态;仅把补齐词向量设为 0,并不保证状态停止变化。
边界还包括样本边界。上一条影评的状态不能悄悄进入下一条独立影评。对于连续传感器数据,跨片段传递状态可能合理,但训练、验证和部署都必须说明如何开始、何时重置。双向 RNN 可以在完整文本上同时利用左右上下文,适合整段分类;对于只能看到过去的实时预测,利用未来输入就会破坏任务约定。本课使用单向模型,让信息可见范围保持清楚。

3 BPTT、梯度消失与门控直觉
模型刚开始并不知道应该把哪些信息写进状态。训练时,先顺序读取输入并产生概率,再把预测与真实标签比较得到损失。正面评论若只得到很低的正面概率,损失就会推动相关参数改变。梯度告诉优化器,参数朝哪个方向小幅调整有望降低当前损失。这个过程仍是常见的监督学习,只是同组参数在多个时间步重复参与计算。
沿时间反向传播通常写作 BPTT。对于最终状态分类,损失的影响先经过末尾状态,再沿展开后的连接向更早位置传递。如果句首的“并不”应该改变句尾的判断,训练信号就要经过中间许多次状态更新,才能把这种关系归因到较早的计算。这里的“反向”指求导方向;模型读取文本的方向并没有因此反转,也不等于额外看到了未来数据。
可以把梯度传播理解为沿途反复缩放的信号。若许多环节使信号变弱,传到远处时就可能接近 0,早期线索很难得到有效调整,这叫梯度消失。若信号反复被放大,则可能产生梯度爆炸,训练损失突然变得很大甚至出现非数值。实际网络中的向量和非线性比这个比喻复杂,但它说明了为什么较长输入带来困难:读过某条线索,不代表模型能稳定学会利用它。
梯度裁剪可以在梯度过大时限制其整体大小,减轻更新失控;它不能恢复已经衰减到很弱的信号。降低学习率可能缓和震荡,却也不等于解决长距离依赖。排查时要同时看训练损失是否异常、验证指标是否改善,以及长文本或远距离线索样本是否更差。只凭总损失下降,就宣布模型“记住了全文”,证据并不充分。
LSTM 和 GRU 引入门控机制,让模型学习哪些旧信息需要保留、哪些新信息值得写入。可以把门理解为可调节的信息通道:遇到无关修饰时尽量保留有用线索,遇到新的关键信息时更新状态。门的开合是通过数据学习的连续数值,并非人为写好的语法规则。它们往往比基础 RNN 更容易训练,但仍受数据、状态容量、长度处理和优化条件限制。
还要区分输入截断与反向传播截断。前者直接删去部分词,模型根本看不到;后者保留前向读取,却在指定边界切断梯度联系。截断 BPTT 可以减少反向传播需要保存的计算历史,代价是跨边界的直接训练信号受到限制。若整段只有末尾标签,并在边界分离状态,损失无法直接回传到此前计算。状态仍可能携带旧信息,因此这也不等于前向记忆被清空。门控无法找回被删掉的输入,也不能绕过人为切断的梯度路径。

4 动手:对比不同截断长度的效果
本实验比较“只保留评论末尾 L 个词”的输入截断,取 L = 32、128、512。选择末尾是明确的实验约定,不能默认它总比保留开头更好。保留全文的变长模型也可以作为后续参照。本轮固定为单向 GRU,目标是研究可见上下文长度的影响;它不直接测量截断 BPTT 的效果,也不能把观察到的差异全部解释为梯度消失。
IMDb 提供 25000 条训练影评和 25000 条测试影评,标签整体均衡。本实验从原始训练部分按标签分层划出 20000 条训练和 5000 条验证,使用固定种子保存样本编号。原始测试部分只用于最终评估,不参加词表构建、阈值选择或长度选择。公开数据自带的未标注文本本轮不使用。若发现重复或高度相似的文本,应先按重复组处理划分,并记录实际样本数,避免同篇评论同时出现在训练与验证中。
预处理固定为简单英文分词规则,保留否定词、标点和词序,不把停用词清单直接用于删词。只在训练部分统计词频,建立最多 20000 个词的词表,另设未知词和补齐标记。先按真实词序分词,再保留末尾 L 个词;短文本补齐时携带真实长度。验证和测试出现的新词映射为未知词,不能为了降低未知词比例而重新用全部数据建词表。
建议起始配置为词向量维度 64、隐藏状态维度 64、批大小 64、Adam 学习率 0.001,最多训练 8 轮,梯度范数上限设为 1。它们是实验起点,不是保证最优的答案。每组使用相同的 3 个随机种子,例如 11、22、33,以验证集 F1 选择各自检查点。各组都经过验证集选择长度后,再固定最终配置使用测试集;不能看过测试成绩后继续调整词表、阈值或保留方向。
操作顺序可以写成下面的实验规程。这里给的是实现步骤,尚未运行,后续报告应填入真实日志与测量结果。
保存训练、验证、测试的样本编号与标签定义
仅用训练文本建立分词词表,固定预处理版本
对 L = 32、128、512,分别使用种子 11、22、33
保留每条评论末尾的 L 个词,记录实际长度
初始化同规格 GRU;按真实长度读取最终状态
训练并按验证 F1 保存检查点,同时记录时间和显存
用验证结果选择长度与固定阈值,形成待评估配置
在测试集评估最终配置,并保存分组指标与错误样本
把正面设为正类时,precision 表示预测为正面的评论中有多少确为正面,recall 表示真实正面评论中找回多少,F1 综合这 2 项。ROC-AUC 使用连续概率衡量排序,不需要先选分类阈值。先固定阈值 0.5 是容易复现的起点;如果业务要调阈值,只能使用验证集,并完整记录规则。另报负类 F1 或宏平均 F1,避免“正面预测很好”掩盖负面识别问题。
结果表至少保留每个 L 的验证 F1、ROC-AUC、训练耗时、峰值显存和各随机种子的离散程度。若另行预先约定对全部候选做测试对照,也必须明确测试仅用于报告,不再据此挑选配置。按原始长度分组,例如不超过 32、33 至 128、超过 128,并报告每组数量、F1 与截断比例。长组天然可能更难,因此分组差异只能提示问题;同批文本在不同 L 下的配对变化更接近长度处理本身的影响。

5 表达力与训练稳定性取舍
延长输入让模型有机会看到更多证据,但也增加逐步计算的工作量。RNN 在同条序列上通常要依次更新状态,长度从 32 增至 128,不只是数组变长,还意味着需要经过更多更新步骤。同批序列长度差异很大时,补齐也会浪费计算。按相近长度组成批次可以减少浪费,但不应把同个来源或标签系统性地集中到某个划分中。
扩大隐藏状态可以容纳更丰富的表示,同时增加参数量和过拟合风险。在基础 RNN 中,隐藏状态到隐藏状态的参数量与隐藏维度的平方有关;门控网络还有多组相关参数。因此把维度从 64 调到 128,不能简单认为成本只增加 2 倍。对于入门实验,应先保持维度不变比较长度,之后再研究容量,避免把同时改变多个因素的收益归给长度。
完整展开训练通常需要为反向传播保存多个时间步的信息,内存开销会随批大小、长度和隐藏维度增加。具体数值取决于框架、精度、优化器与实现。滑块中的相对开销仅展示固定批大小和维度时的长度关系;它不能预测设备上的显存,也不能用滑块合成“实测 F1”。准确率与成本的关系必须通过实验点来补充。
如果 L 增大后验证 F1 没有提升,至少有几种可能:新增上下文不重要、模型没有学会利用、噪声更多,或者训练设置不足。若训练 F1 提升而验证下降,过拟合值得关注;若训练和验证都很低,应检查输入、标签及优化过程。若只有长依赖诊断样本改善,说明收益可能集中在特定语义关系。不能把“长度更大”直接写成“理解能力更强”。
稳定性还包括重复训练后的波动。某个种子恰好领先 0.2 个百分点,未必足以支持更昂贵配置。可以比较 3 次运行的平均值和范围,并在相同样本上观察预测差异。训练时间应说明硬件与测量范围,推理延迟应注明批大小和文本长度。部署通常可以边读边更新状态,训练则要保留求导所需信息,因此推理内存和训练内存不能混为同项指标。
资源有限时,可以优先采取长度分桶、合理限制输入和设置早停等容易解释的做法。换成 LSTM 或 GRU 是模型选择,使用截断 BPTT 是训练路径选择,删去输入前缀是数据选择,它们解决的问题不同。每次只改变明确因素,才容易理解所得收益是否值得付出成本。更复杂的注意力机制留待后续课程讨论。
6 常见坑:打乱顺序仍当序列任务
“训练要打乱数据”说的是通常应打乱独立样本的顺序,而不是把每条文本内部的词随机排列。评论 A 和评论 B 在批次中的先后可以变化,但“不是很好”和“很好不是”不能被当作相同输入。对于单条连续时间流,还要额外考虑状态是否跨片段传递;若传递,任意打乱片段会把不相邻的历史接在一起。数据加载器的打乱选项必须结合样本定义解释。
把词序打乱可以作为诊断实验,观察模型对顺序是否敏感。若表现几乎不变,可能是数据主要依赖词语统计,也可能是模型没有有效利用顺序,或者评价集合缺少顺序敏感案例。这个结果不足以证明词序不重要。应同时看无顺序基线和人工构造的最小对照句,确认模型究竟利用了哪些信号。诊断输入经过人为破坏,不能替代真实使用分布的总体指标。
数据泄漏经常比模型结构错误更隐蔽。先用全部文本统计词表再划分,会让训练预处理接触测试分布;从同篇长文切出多个片段后随机划分,可能让近似内容跨集合出现;同个用户的连续行为分散到训练和测试,也可能使模型通过身份线索得到虚高成绩。对于用户日志,应根据部署目标按用户分组或按时间划分。是否允许同用户历史进入训练,要在实验前说清。
类别不平衡会让单个总分误导判断。例如某批客服消息中只有 10% 是投诉,全部预测为非投诉也能得到 90% 准确率,却找不回任何投诉。若把投诉设为正类,应关注 recall、precision、F1,必要时增加 PR-AUC,并说明各类数量。IMDb 的均衡标签不代表真实业务也均衡;阈值从公开数据搬到业务数据时,预测为正的比例和 precision 都可能改变。
时间和领域变化也会破坏效果。影评里的“吓人”可能是恐怖片的赞美,客服消息里的同个表达却可能指严重问题。新词、讽刺、表情符号和不同长度分布都能引发分布偏移。未知词比例、截断比例与类别比例值得监控,但这些代理量正常也不能保证 F1 正常。需要持续获得带标签的抽样数据,才能判断真实性能是否下降。
最后检查标签含义。整段情感并不总能由最后的形容词决定,混合评价也可能存在标注分歧。发现错误时,应先确认文本、标签、分词结果和模型实际看到的词,再讨论“模型忘记了”。如果关键词已被预处理删掉,调整门控单元不会解决根因;如果预测概率合理而阈值不合适,则应该评估决策规则。排查必须沿着证据走。

7 案例:长依赖被截断导致误解否定
考虑说明句:“我不认为这部电影在经历了冗长的铺垫、反复的解释和许多无关支线之后,算得上精彩。”这里的“不认为”对后面的评价产生作用。为了让边界清楚,可以在英文诊断集中使用 I do not think ... this film is good,逐步增加中间的中性描述。它是机制演示,不是 IMDb 原始样本,也不能把模型在这些句子上的表现冒充公开测试集成绩。
假设使用只保留末尾 32 个词的策略,而“不认为”落在保留范围外。模型实际看到的可能只有铺垫描述和“算得上精彩”。这时失误首先是可见信息不足,不应立即归结为“GRU 记忆差”。对文本末尾做分类的模型,即便状态容量更大,也无法从已删除的前缀中读取否定。可以通过打印词编号对应的保留文本确认边界,避免只看原始句子产生错觉。
诊断集合应围绕同种关系建立配对样本。保留肯定版本和否定版本,控制主要内容相近,再分别设置较短、中等和较长的间隔。标注者需要检查否定作用范围,排除含义模糊或不自然的句子。“并不是不好看”带有双重否定,不应与普通否定混成同类。还可以加入转折句,例如前文称赞、结尾批评,避免只针对否定词编写特例。
对同条样本记录原文长度、保留区间、否定线索是否可见、模型概率、阈值和预测类别。先比较 L 为 32 与 128 的版本:如果关键线索重新进入输入后错误消失,支持“截断影响了该样本”的解释。它仍不能证明总体收益都来自否定关系,因为新增文本也带来了其他信息。可以再用保留关键线索的紧凑改写进行对照,并检查多个例子是否呈现相似模式。
若否定完整可见,模型仍判为正面,才继续研究状态保留、训练样本覆盖和标签噪声。查看相同间隔下基础 RNN 与 GRU 的差异,可以提供线索,但要保持词表、划分与调参预算可比较。若使用截断 BPTT,还应确认否定与末尾损失是否位于梯度可连接的范围。不能仅从最终概率恢复内部因果机制,入门阶段先把可验证的输入与训练路径交代清楚。
修复也需要分层评估。增加 L 可能改善这些样本,却增加延迟;保留开头可能救回否定,却漏掉结尾转折;组合首尾片段可能引入新的断接边界,必须说明并重新验证。人工挑选的诊断集用于发现机制,总体保留集用于确认普遍效果。修复后同时报告否定组、长文本组和总体指标,才不至于只解决被展示的例子。

8 把序列假设写进模型方案
模型方案首先要定义序列单位。对于影评,每条评论是独立序列,词为时间步,输出是整段情感;对于用户行为,可能每个用户最近 30 天的事件组成序列,输出是未来 7 天是否流失。事件时间、标签观察窗口和数据可用时间必须对应。若用预测日之后的退款或注销信息构造输入,即使按照时间排序,也已经泄漏了答案。
随后说明顺序究竟表达什么。文本顺序表达语言结构,用户事件顺序可能表达行为过程,传感器顺序则反映连续测量。基础 RNN 按步更新,并不会自动理解相邻事件相差 1 分钟还是 10 天。如果时间间隔有用,需要作为额外特征或采用明确的采样规则。缺失时刻、同时间戳事件和乱序到达数据,也应给出确定处理方式,保证离线训练和上线输入一致。
状态策略必须能够由实现者照着执行:独立样本从 0 状态开始,批内补齐不计入有效长度,最终分类取真实末尾状态;连续流则说明状态与哪个实体绑定、何时过期、断流后如何恢复。训练集和验证集之间不能沿用状态。推理时如果跨请求保存状态,还要避免把不同用户或文档接在一起。状态是数据处理协议的一部分,不只是神经网络内部的细节。
评估约定应写在调参前。公开数据保存官方测试集,业务数据依据目标选择时间划分或实体分组;词表、标准化参数和重采样规则只从训练部分学习。验证集用于选择长度、模型和阈值,测试集用于最终报告。类别不平衡时,除整体指标外报告各类 precision、recall 和 F1;跨领域使用时,新增有标签的目标领域评估,不能仅靠源领域 ROC-AUC 背书。
还要把“暂不确定”写成可执行的观察项。例如最大长度是否足够,可以通过截断比例、关键线索可见率和不同长度组的错误来检查;是否需要门控,可以用相同预算下的基础 RNN 与 GRU 作对照;是否值得上线,则结合关键指标、成本和错误代价判断。这样的方案允许结果推翻假设,也使后续维护者知道哪些约定不能随意改变。
9 从RNN 与序列模型走向NLP 基础(A26)
到这里,序列模型已经有了清楚的位置:它接收按约定排列的表示,通过状态更新聚合上下文,再为任务产生预测。但它并没有直接接收人类理解的“词义”。文本首先要经过字符处理、切分、编号和向量化,任何环节改变,都可能改变有效长度、未知词比例以及否定词是否可见。序列建模与文本表示紧密相关,却是可以分别检查的环节。
例如同句英文按空格切分与按子词切分,得到的时间步数可能不同。原先 L 为 128 时保留的大部分评论,换切分方法后可能被截去更多内容。因此长度不能只写“128”,还要注明单位是字符、词还是子词。中文也不能假定每个字等于每个词。讨论模型能处理多长文本时,应同时说明切分规则、截断方向和有效输入统计。
词袋基线忽略顺序,却能说明词语本身有多少预测信号;词向量提供可训练表示,却不保证相近向量一定符合当前任务;RNN 聚合上下文,却会受到可见长度与训练路径约束。把这几层分清,接下来学习 NLP 基础时就能追问:错误源于文本清理、词表覆盖、表示能力,还是上下文组合。不要把所有失败都塞进“模型不够大”的解释中。
带到 A26 的材料可以很具体:固定的数据划分、训练词表版本、长度分布、无顺序基线、GRU 的验证记录,以及含否定、转折和未知词的错误样本。对每个样本保留原文与模型实际输入,后续改变切分或表示方式时,才能判断改进来自哪里。大型预训练模型、复杂注意力结构和生成训练目标留到后续展开;当前先建立表示与评价之间可追踪的联系。

放进方案里
本方案以公开 IMDb 影评开展整段情感分类,正面为正类,每条评论构成独立序列,时间步单位为按固定规则切分的英文词。保留官方测试部分,从官方训练部分按标签分层划出训练与验证,并保存样本编号。先检查重复文本,重复组不得跨集合;若去重改变数量,以实际划分清单为准。词表仅由训练文本建立,否定词与词序保留,测试标签不参与预处理或模型选择。
以 TF-IDF 加逻辑回归为参照,主模型采用单向 GRU。固定词向量与隐藏状态维度为 64、批大小为 64,比较末尾保留 32、128、512 个词。每组使用相同的 3 个种子与训练预算,以验证 F1 选择检查点和长度。独立评论重置状态,补齐位置不作为有效输入,分类读取真实末尾状态。本轮研究输入截断,不使用截断 BPTT;不得把结果解释为梯度截断实验。
固定正类阈值后报告 precision、recall、F1、ROC-AUC 与负类表现,并记录耗时、峰值显存和种子波动。按原始长度、截断与否划分观察组,另建带人工核对标签的否定诊断集。人工诊断集用于定位问题,最终测试集用于报告总体性能。若延长输入只改善少量样本,应结合延迟和错误代价决定是否采用。
部署前以目标来源的带标签样本复核领域变化,监控未知词率、截断率与类别比例,并定期抽样重标。发现否定错误,先核对实际可见输入,再排查状态边界与训练记录。阈值、词表、长度策略和模型作为同版配置保存。未经实验的指标留空,以真实日志补齐;后续更换切分规则或接入中文文本时,重新验证长度含义与整体效果。
10 小结:下一步NLP 基础(A26)
RNN 通过共享的状态更新处理有序输入,BPTT 将损失沿展开计算传播。门控帮助学习保留信息,但不能补回被删掉的文本。比较长度时,先区分输入可见范围与梯度传播范围,再固定划分、基线、指标和成本口径。
自测时试着解释:打乱独立评论与打乱词序有什么区别;否定词被截掉后增加隐藏维度为何未必有效;验证集和测试集各自能参与哪些决定;总体 F1 不变时为何仍要检查长文本组。能够结合本课实验回答,就可以进入 A26,继续研究文本如何变成模型可使用的表示。