第9章 序列神经模型:RNN、LSTM、GRU 与双向结构
读完你能: 写出标准 RNN 的前向递推公式与各矩阵维度;区分序列到单值、单值到序列、同步序列标注与编码器—解码器结构;手算一步 LSTM 与 GRU 的状态更新;判断双向序列模型在哪些任务中适用、哪些任务中会造成未来信息泄漏。
1. 为什么词袋模型处理不好语序与长距离依赖
在词袋表示里,the service is not good 与 the service is good, not bad 只要词频接近,向量就很相似;普通线性分类器或前馈网络既没有记忆历史状态的结构,也难以自然处理长度可变的句子。
循环神经网络(RNN)按时间步 依次读入词向量 ,并用隐藏状态 保存截至当前位置的历史摘要。最基本的 Vanilla RNN 在每个时间步共享同一组参数:
设输入词向量维度为 、隐藏状态维度为 、输出类别数为 ,各量的尺寸如下:
| 符号 | 含义 | 维度 |
|---|---|---|
| 第 步输入向量、隐藏状态 | 、 | |
| 输入权重、循环权重、隐藏偏置 | 、、 | |
| 输出层权重、输出层偏置 | 、 |
无论句子有 5 个词还是 50 个词,复用的都是同一套 。词嵌入表负责把离散词元编号映射成稠密向量 ,而 RNN 负责沿着时间轴传递和更新状态 。
2. 手算两步标量 RNN
令所有维度都取 1,参数设为 ,初始状态 ,依次输入 、:
可以看到,尽管第二步输入 ,状态 依然非零,因为它从 继承了第一步的信息;同时由于乘了循环权重 并经过 压缩,信号强度也比第一步有所衰减。
3. 同一套循环递推,四种常见输入输出结构
根据任务对输入与输出形态的要求,RNN 可以组装成四种常见结构:
- 序列到单值(Sequence-to-One):读完整句后只输出一个类别,例如情感分类。通常取最后一步隐藏状态 (或所有时间步状态的池化)送入分类层。
- 单值到序列(One-to-Sequence):由一个初始向量出发逐步生成序列,例如根据图像特征生成一句图片描述。
- 同步序列到序列(Sequence-to-Sequence Tagging):每个输入词元 对应输出一个标签 ,输入与输出长度严格相等,例如词性标注(POS)和命名实体识别(NER)。
- 编码器—解码器(Encoder–Decoder):先用编码器读完源序列浓缩成上下文表示,再用解码器逐步生成目标序列,适合机器翻译、摘要等输入输出长度不等的任务。
在自回归文本生成中,第 步只能看到 来预测下一个词。训练时常直接把真实历史前缀喂给模型(teacher forcing),而测试生成时每一步只能把模型自己刚生成的词作为下一步输入;训练与推断的输入分布差异需要留意。此外,工程批处理(batching)会把长短不一的句子补齐(padding)到相同长度,计算损失、池化或取末态时必须用掩码(mask)屏蔽补齐位置。
4. 激活函数与梯度消失、梯度爆炸
序列模型里最常成对出现的两个非线性函数是 sigmoid 与 tanh:
- Sigmoid:,导数为 。因为输出落在 之间,非常适合用作控制信息开闭比例的“门”;但它的输出恒为正(非零中心),且当 较大时导数趋近 0。
- Tanh:,导数为 。它的输出以 0 为中心,适合表示正负兼有的状态和候选内容,但饱和区同样存在导数趋近 0 的问题。
当沿时间反向传播(BPTT)计算早期状态 对末步状态 的梯度时,链式法则会产生一连串雅可比矩阵的乘积:
如果这些雅可比矩阵的主特征值持续小于 1(再加上 的反复收缩),相隔几十步之后梯度就会呈指数级衰减到接近 0,导致模型学不到远距离依赖,即梯度消失;反之,若循环权重的主特征值大于 1,连乘会让梯度急剧放大,导致参数更新失控,即梯度爆炸。
梯度裁剪(见第10章)可以有效抑制梯度爆炸,但无法凭空恢复已经衰减殆尽的远距离梯度;要让长距离信号顺畅传递,需要从网络结构上改造状态更新方式。
5. LSTM:加法细胞通道与三道门
长短期记忆网络(LSTM)在隐藏状态 之外,专门维护一条承载长期记忆的细胞状态(cell state) ,并用遗忘门、输入门和输出门调控信息读写。记当前步拼接向量为 (等价于分别乘输入矩阵 和循环矩阵 后相加):
其中 表示逐元素相乘,候选状态 在许多文献中也记作 。四个分量的分工非常清晰:
| 分量 | 取值范围 | 作用 |
|---|---|---|
| 遗忘门 | 决定旧细胞状态 保留多少比例 | |
| 输入门 | 决定当前候选信息 写入多少比例 | |
| 候选状态 (或 ) | 由当前输入与前一隐藏状态提炼出的新候选内容 | |
| 输出门 | 决定更新后的细胞状态 对外暴露多少给 |
为什么 LSTM 能缓解梯度消失?关键在于 是线性加权相加,而不是普通 RNN 那样每一步都把旧状态套进 。当某个维度上的遗忘门 接近 1、输入门 接近 0 时,早期信息几乎可以无损地沿细胞通道传到很多步之后,对应方向的局部偏导也接近 1。
例1: 对一维 LSTM,已知旧细胞状态 ,当前步门值与候选为 ,则:
注意 与 的区别: 在内部通道上保持了 ,而对外输出的隐藏状态 经过了 压缩和输出门 的缩放。
6. GRU:合并细胞状态,只留重置门与更新门
门控循环单元(GRU)将细胞状态与隐藏状态合二为一,只维护单一状态向量 ,并用两道门控制更新,参数量比同维度的 LSTM 更少。
本章将更新门 定义为写入新候选状态的比例:
- **重置门 **:在构造当前步候选状态 时,控制保留多少过去状态 ;若 ,候选状态就近似只看当前输入 ,相当于“重置”历史。
- **更新门 **:在旧状态 与新候选 之间做凸组合,同时扮演了 LSTM 中遗忘门()和输入门()的角色。
例2: 设单维状态 ,算得候选状态 ,更新门 ,则新状态为
对照论文与框架代码时先核对更新门方向
深度学习框架(如 PyTorch 的 nn.GRU)和部分教材会把最后一步写成 ,也就是把 定义为“保留旧状态的比例”;同时重置门 作用在乘 之前还是之后也有细微差别。两种写法表达能力等价,但手算或迁移权重时务必先看清公式约定。
7. 双向 RNN:什么时候能看右侧上下文
阅读整句话做词性标注或实体识别时,一个词的意思往往同时取决于它前面和后面的词。双向循环网络(Bi-RNN / Bi-LSTM / Bi-GRU)设置两个独立的循环分支:
- 前向分支从左到右按 计算 ;
- 反向分支从右到左按 计算 ;
- 在每个位置 将两者拼接为 。
若单向隐藏维度为 ,拼接后的表示维度变为 ,下游全连接层的输入维度也相应翻倍。
双向结构适用的前提是推断时整段输入序列已经完整可见(如句子分类、整句 POS/NER、编码器端编码)。如果任务是因果语言建模或实时流式预测(根据 预测尚未发生的 ),反向分支会把包含 的未来信息直接传给位置 ,造成严重的信息泄漏。
自测
1. 在 LSTM 中,如果某一步遗忘门 f_t=1、输入门 i_t=0,细胞状态 c_t 和隐藏输出 h_t 会发生什么变化?
细胞状态完全保留上一步的值:。但隐藏状态 还受当前步输出门 的控制;只要 ,对外输出的 仍会改变。
2. 按本章第 6 节的 GRU 公式,z_t=0 和 z_t=1 分别对应什么行为?
在本章 的约定下: 时 ,完全保留旧状态、忽略新候选; 时 ,完全用新候选覆盖旧状态。
- 感谢你赐予我前进的力量

