循环神经网络是专门设计用于处理序列数据的一类神经网络。与传统的前馈网络(Feedforward Networks, FNN)不同,RNN 引入了 “循环”机制,使得网络能够利用先前的信息来影响当前时刻的输出,从而具备了记忆能力。
一、 理论基础
1. 序列数据与挑战
序列数据是指数据点之间存在时间或逻辑顺序依赖关系的数据,例如:
- 文本: 一个词的含义取决于前后的词。
- 语音: 一个音素的识别依赖于前后的发音。
- 时间序列: 股票价格、天气变化等。
对于序列数据,传统 FNN 的挑战在于:
- 无法共享特征: 每次输入(如文本中的一个词)都被视为独立的输入,网络无法学习序列中共同的模式。
- 无法建模长期依赖: 网络的输入长度是固定的,无法处理长度可变的序列,也无法记住很早以前的信息。
2. 核心思想:循环连接
RNN 的关键在于其隐藏层(Hidden State)的输出不仅传递给下一层(输出层),还会循环地传递给自身,作为下一时刻的输入。
在时刻 ttt,RNN 的核心计算公式如下:
-
隐藏状态(hth_tht)的计算:
ht=f(Whhht−1+Wxhxt+bh)h_t = f(W_{hh} h_{t-1} + W_{xh} x_t + b_h)ht=f(Whhht−1+Wxhxt+bh)- xtx_txt: 当前时刻的输入。
- ht−1h_{t-1}ht−1: 上一时刻的隐藏状态(即记忆)。
- WxhW_{xh}Wxh: 输入到隐藏层的权重矩阵。
- WhhW_{hh}Whh: 上一时刻隐藏状态到当前时刻隐藏层的权重矩阵(循环权重)。
- bhb_hbh: 隐藏层的偏置项。
- fff: 激活函数,通常是 tanh\text{tanh}tanh 或 ReLU\text{ReLU}ReLU。
-
输出(yty_tyt)的计算:
yt=g(Whyht+by)y_t = g(W_{hy} h_t + b_y)yt=g(Whyht+by)- WhyW_{hy}Why: 隐藏层到输出层的权重矩阵。
- ggg: 激活函数,如 softmax\text{softmax}softmax(用于分类)或 ReLU\text{ReLU}ReLU(用于回归)。
核心洞察: 在整个序列中,权重矩阵 WxhW_{xh}Wxh, WhhW_{hh}Whh, WhyW_{hy}Why 是共享的。这体现了 RNN 通过共享参数来处理不同长度序列的能力,也大大减少了需要学习的参数数量。
二、 结构与展开(Unrolling)
虽然我们在概念上将其视为一个循环结构,但在实际计算中,RNN 会沿着时间轴展开(Unrolling),变成一个很深的前馈网络,深度与序列的长度相等。
序列长度 TTT 的展开图示:
- t=1t=1t=1: h1=f(Whhh0+Wxhx1+bh)h_1 = f(W_{hh} h_0 + W_{xh} x_1 + b_h)h1=f(Whhh0+Wxhx1+bh)
- t=2t=2t=2: h2=f(Whhh1+Wxhx2+bh)h_2 = f(W_{hh} h_1 + W_{xh} x_2 + b_h)h2=f(Whhh1+Wxhx2+bh)
- …
- t=Tt=Tt=T: hT=f(WhhhT−1+WxhxT+bh)h_T = f(W_{hh} h_{T-1} + W_{xh} x_T + b_h)hT=f(WhhhT−1+WxhxT+bh)
不同的 RNN 结构(基于输入和输出的对应关系):
| 名称 | 输入-输出 关系 | 举例 |
|---|---|---|
| One-to-One | FNN 的标准结构 | 图像分类 |
| One-to-Many | 单一输入,序列输出 | 图像描述生成 |
| Many-to-One | 序列输入,单一输出 | 情感分析(判断一句话是积极还是消极) |
| Many-to-Many | 序列输入,序列输出 | 机器翻译 (Sequence-to-Sequence) |
| Many-to-Many (同步) | 输入和输出序列等长 | 视频帧分类,命名实体识别 (NER) |
三、 训练与挑战:梯度问题
RNN 的训练采用 时间反向传播(Backpropagation Through Time, BPTT 算法。
1. BPTT 机制
BPTT 本质上就是将展开后的 RNN 视为一个深度网络,然后使用标准的反向传播算法。由于隐藏状态 hth_tht 依赖于所有之前的隐藏状态 ht−1,ht−2,…,h0h_{t-1}, h_{t-2}, \dots, h_0ht−1,ht−2,…,h0,梯度需要沿着时间轴反向传播,累乘所有的循环权重 WhhW_{hh}Whh。
2. 梯度问题(Gradient Problem)
这是标准 RNN 最大的局限性,导致其难以学习长期依赖(Long-Term Dependencies):
-
梯度消失 (Vanishing Gradient):
- 当循环权重 WhhW_{hh}Whh 的值较小(或其特征值小于 1)且激活函数(如 tanh\text{tanh}tanh)的导数值小于 1 时,梯度在时间轴上反向传播时会不断连乘这些小值。
- 结果是,对于很早之前的输入 x1x_1x1,它的梯度会变得极其微小(趋近于 0),网络无法有效学习到远距离的依赖关系。
-
梯度爆炸 (Exploding Gradient):
- 当循环权重 WhhW_{hh}Whh 的值较大(或其特征值大于 1)时,梯度在反向传播时会不断连乘这些大值。
- 结果是,梯度会变得极大,导致模型权重更新过大,训练过程不稳定,甚至发散。
- 解决方案: 梯度裁剪(Gradient Clipping)。当梯度向量的 L2 范数超过某个阈值时,将其缩放回该阈值以内。
四、 进阶模型:解决长期依赖
为了克服梯度消失问题,研究人员设计了更复杂的门控循环单元(Gated Recurrent Units),它们通过引入门控机制来显式地控制信息的流动。
1. 长短期记忆网络 (Long Short-Term Memory, LSTM)
LSTM 是最成功的 RNN 变体,它引入了 “细胞状态”(Cell State, CtC_tCt),作为一条独立的、对线性信息流友好的高速公路,专门用于传输长期信息。
LSTM 的核心在于 三个“门” 来控制细胞状态和隐藏状态的更新:
- 遗忘门 (Forget Gate, ftf_tft): 决定从细胞状态 Ct−1C_{t-1}Ct−1 中丢弃(遗忘)多少信息。
ft=σ(Wf⋅[ht−1,xt]+bf)f_t = \sigma(W_f \cdot [h_{t-1}, x_t] + b_f)ft=σ(Wf⋅[ht−1,xt]+bf) - 输入门 (Input Gate, iti_tit): 决定有多少新的信息 C~t\tilde{C}_tC~t 要被添加到细胞状态中。
it=σ(Wi⋅[ht−1,xt]+bi)i_t = \sigma(W_i \cdot [h_{t-1}, x_t] + b_i)it=σ(Wi⋅[ht−1,xt]+bi) - 候选细胞状态 (C~t\tilde{C}_tC~t): 产生新的待加入的信息。
C~t=tanh(WC⋅[ht−1,xt]+bC)\tilde{C}_t = \text{tanh}(W_C \cdot [h_{t-1}, x_t] + b_C)C~t=tanh(WC⋅[ht−1,xt]+bC) - 更新细胞状态 (CtC_tCt): 结合遗忘门和输入门来更新长期记忆。
Ct=ft∗Ct−1+it∗C~tC_t = f_t * C_{t-1} + i_t * \tilde{C}_tCt=ft∗Ct−1+it∗C~t - 输出门 (Output Gate, oto_tot): 决定细胞状态 CtC_tCt 的哪些部分将被输出到隐藏状态 hth_tht。
ot=σ(Wo⋅[ht−1,xt]+bo)o_t = \sigma(W_o \cdot [h_{t-1}, x_t] + b_o)ot=σ(Wo⋅[ht−1,xt]+bo)
ht=ot∗tanh(Ct)h_t = o_t * \text{tanh}(C_t)ht=ot∗tanh(Ct)
深刻理解: 细胞状态 CtC_tCt 的更新是一个加法操作(ft∗Ct−1+…f_t * C_{t-1} + \dotsft∗Ct−1+…),这使得梯度可以更稳定地通过时间步传播,从而有效缓解了梯度消失问题。
2. 简化版:门控循环单元 (Gated Recurrent Unit, GRU)
GRU 是 LSTM 的一个简化版本,它将遗忘门和输入门合并为 “更新门”(Update Gate, ztz_tzt),并将细胞状态和隐藏状态合并为一个单一的隐藏状态 hth_tht。
GRU 只有两个门:
- 更新门 (ztz_tzt): 决定 ht−1h_{t-1}ht−1 有多少信息被带到 hth_tht,以及新的信息 h~t\tilde{h}_th~t 有多少信息被添加。
- 重置门 (rtr_trt): 决定忽略多少过去的隐藏状态 ht−1h_{t-1}ht−1 信息。
GRU 的参数更少,计算更快,在某些任务上性能与 LSTM 相当。
五、 实践应用
| 应用领域 | 具体任务 | RNN/LSTM/GRU 结构 | 关键特点 |
|---|---|---|---|
| 自然语言处理 (NLP) | 机器翻译 | Many-to-Many (Seq2Seq) | 编码器-解码器结构,常配合 Attention 机制。 |
| 文本生成 | One-to-Many | 基于前一个词预测下一个词。 | |
| 情感分析 | Many-to-One | 整个序列输入,最终状态 hTh_ThT 预测类别。 | |
| 语音识别 | 语音转文本 | Many-to-Many (同步) | 输入是音频特征序列,输出是音素或字符序列。 |
| 时间序列 | 股票预测 | Many-to-One / Many-to-Many | 捕捉时间上的依赖关系和周期性。 |
| 计算机视觉 | 图像/视频描述 | One-to-Many / Many-to-Many | LSTM 接受 CNN 提取的图像特征并生成文本。 |
实践模型结构:双向 RNN (Bidirectional RNN)
在许多任务中,当前时刻的输出不仅依赖于过去的信息,也依赖于未来的信息(例如:完形填空,或者句子中一个词的词性)。
双向 RNN (Bi-RNN/Bi-LSTM) 包含两个独立的 RNN 层:
- 前向层: 按时间正向处理输入序列 (x1→xT)(x_1 \to x_T)(x1→xT)。
- 后向层: 按时间反向处理输入序列 (xT→x1)(x_T \to x_1)(xT→x1)。
当前时刻的最终隐藏状态 hth_tht 是两个方向的隐藏状态的拼接:ht=[ht→;ht←]h_t = [\overrightarrow{h_t}; \overleftarrow{h_t}]ht=[ht;ht]
这使得模型能够利用整个序列的上下文信息,在 NER、语音识别等任务中表现优异。
总结
标准 RNN 是序列建模的基石,通过循环连接实现记忆和参数共享,但其在处理长序列时受到梯度消失的严重限制。LSTM 和 GRU 通过引入复杂的门控机制,有效地解决了这一问题,成为现代序列处理任务(尤其是 NLP 领域)中应用最广泛的模型,直到 Transformer 架构的出现。
25万+

被折叠的 条评论
为什么被折叠?



