RNN 处理序列数据的基本原理
1. 核心思想:带"记忆"的循环结构
传统前馈网络(MLP/CNN)处理的是固定大小的独立输入,每个输入之间没有关联。RNN 的关键创新是引入了隐藏状态(hidden state),在时间步之间传递信息,形成对序列的"记忆"。
时间步 t=1: h₁ = f(W_xh · x₁ + W_hh · h₀ + b) 时间步 t=2: h₂ = f(W_xh · x₂ + W_hh · h₁ + b) 时间步 t=3: h₃ = f(W_xh · x₃ + W_hh · h₂ + b) ...其中:
xₜ:当前时间步的输入hₜ₋₁:上一时间步的隐藏状态(即"记忆")hₜ:当前时间步的隐藏状态W_xh、W_hh:所有时间步共享的权重矩阵f:非线性激活函数(通常为 tanh 或 ReLU)
2. 展开图示
RNN 在时间维度上展开后,等价于一个深层网络:
x₁ → [RNN cell] → h₁ → [RNN cell] → h₂ → [RNN cell] → h₃ → ... ↑ ↑ ↑ h₀ h₁ h₂每个时间步:
- 接收当前输入
xₜ和前一步隐藏状态hₜ₋₁ - 计算新的隐藏状态
hₜ - 可选地输出
yₜ = g(W_hy · hₜ + b)
3. 参数共享的意义
RNN 在所有时间步使用同一组参数(W_xh、W_hh、W_hy),这带来两个关键优势:
- 模型大小与序列长度无关:无论输入序列有 10 个词还是 1000 个词,参数量不变
- 位置无关的规律学习:序列中出现的模式无论在哪个位置,都能被同一组参数捕获
为什么能处理变长输入?
RNN 处理变长输入的能力来自以下机制:
机制一:逐步处理,无需预知长度
RNN 按时间步逐个处理输入,每一步只看一个元素。不需要预先知道序列总长度,循环结构天然支持"处理到序列结束为止":
序列 A (长度 3): x₁ → x₂ → x₃ → 结束 序列 B (长度 5): x₁ → x₂ → x₃ → x₄ → x₅ → 结束同一个 RNN cell 可以处理任意长度的序列,因为参数共享,不依赖序列长度。
机制二:灵活的输入输出模式
RNN 通过不同的输入输出配置,适配各种变长场景:
(1) 多对多(等长):序列标注 x₁ → h₁ → y₁ x₂ → h₂ → y₂ x₃ → h₃ → y₃ (2) 多对一:文本分类 x₁ → h₁ x₂ → h₂ x₃ → h₃ → y (只用最后一步的隐藏状态做分类) (3) 一对多:文本生成 x₁ → h₁ → y₁ → y₂ → y₃ (4) 多对多(不等长):机器翻译(Encoder-Decoder) 编码器: x₁ → h₁, x₂ → h₂, x₃ → h₃ → context 解码器: context → y₁ → y₂ → y₃ → y₄机制三:填充与打包(工程实现)
实际工程中,为了批量训练,通常用Padding + Packing处理变长:
原始批次: 序列1: [a, b, c] 长度 3 序列2: [d, e] 长度 2 序列3: [f, g, h, i, j] 长度 5 Padding 到等长: 序列1: [a, b, c, <PAD>, <PAD>] 序列2: [d, e, <PAD>, <PAD>, <PAD>] 序列3: [f, g, h, i, j] Packing(记录真实长度,跳过 PAD 位置的计算): → RNN 只在真实 token 上运算,不浪费计算资源PyTorch 中对应pack_padded_sequence/pad_packed_sequence。
RNN 的核心问题
虽然 RNN 能处理变长序列,但存在一个严重缺陷——梯度消失/爆炸:
反向传播时梯度沿时间链式传播: ∂L/∂h₁ = ∂L/∂h₃ · (∂h₃/∂h₂) · (∂h₂/∂h₁) ↑ ↑ 每步都乘 W_hh,连乘 T 次 当 T 很大时: ||W_hh|| > 1 → 梯度爆炸 ||W_hh|| < 1 → 梯度消失(长距离依赖丢失)这导致标准 RNN 实际只能捕获5-10 步以内的依赖关系。后续改进方案:
| 模型 | 解决方式 |
|---|---|
| LSTM | 引入门控机制(遗忘门、输入门、输出门)+ 细胞状态,让梯度有"高速公路"直通 |
| GRU | LSTM 的简化版,合并门控,减少参数 |
| Transformer | 彻底放弃循环结构,用自注意力直接建模任意距离的依赖 |
总结
RNN 处理序列数据的基本原理是通过隐藏状态在时间步之间传递信息,形成对历史输入的记忆,且所有时间步共享同一组参数。它能处理变长输入的根本原因是逐步循环处理 + 参数共享——模型结构不绑定固定长度,循环可以自然地进行到序列结束。但其梯度链式传播的特性导致长距离依赖建模困难,这也是 LSTM/GRU/Transformer 相继出现的直接动因。