神经网络与深度学习:神经网络基础(第7-8讲)

2945 个字
15 分钟
神经网络与深度学习:神经网络基础(第7-8讲)

神经网络与深度学习:循环神经网络(第 7-8 讲)#

本文档涵盖循环神经网络(RNN)的核心内容,包括基本 RNN 结构与训练方法、梯度消失/爆炸问题、LSTM 与 GRU 门控机制、以及 RNN 的主要应用模式。掌握这些内容是理解序列建模和后续 Transformer 架构的基础。

一、循环神经网络基础#

1.1 为什么需要 RNN?#

核心动机:前馈神经网络(Feedforward NN)将每个输入视为独立样本,无法处理具有时序依赖关系的数据。现实世界中大量数据是序列化的——文本、语音、时间序列——它们的当前状态依赖于历史信息。

序列数据的典型场景:

  • 自然语言文本:词的含义取决于上下文,“苹果”在不同句子中含义不同

  • 语音信号:当前音素的识别依赖前后音素的组合

  • 时间序列:股价、气温等数据具有时序相关性

  • 视频帧序列:动作识别需要理解帧与帧之间的关系

1.2 RNN 与前馈网络的关键区别#

循环神经网络(RNN)

  • 具有循环连接(recurrent connection)

  • 维护隐藏状态hth_t 作为”记忆”

  • 参数在时间步之间共享

  • 输入/输出长度可变

前馈神经网络(FNN)

  • 信号单向从输入层到输出层

  • 无内部记忆,每个样本独立处理

  • 各层参数独立

  • 输入/输出维度固定

1.3 基本 RNN 公式#

RNN 递推公式:

隐藏状态更新:ht=σ(Whhht1+Wxhxt+bh)h_t = \sigma(W_{hh} \cdot h_{t-1} + W_{xh} \cdot x_t + b_h)

输出计算:yt=Whyht+byy_t = W_{hy} \cdot h_t + b_y

各符号含义:

符号含义
xtx_t时刻 t 的输入向量
hth_t时刻 t 的隐藏状态(hidden state),编码了历史信息
ht1h_{t-1}上一时刻的隐藏状态
WxhW_{xh}输入到隐藏层的权重矩阵
WhhW_{hh}隐藏层到隐藏层的权重矩阵(循环权重)
WhyW_{hy}隐藏层到输出层的权重矩阵
bh,byb_h, b_y偏置项
σ\sigma激活函数(通常为 tanh 或 ReLU)

1.4 时间展开(Unfolding in Time)#

RNN 的循环结构可以沿时间轴展开(unfold),形成一个等价的深度前馈网络。每个时间步对应网络中的一”层”,但所有层共享相同的参数 Whh,Wxh,WhyW_{hh}, W_{xh}, W_{hy}

展开后的关键性质:

  • 网络深度等于序列长度 T,因此长序列 = 极深网络

  • 参数共享使得模型可以处理任意长度的序列

  • 展开后可以使用标准的反向传播算法

1.5 训练:BPTT(Backpropagation Through Time)#

BPTT 是标准反向传播在时间维度上的推广:

  1. 前向传播:按时间顺序 t=1,2,,Tt = 1, 2, \ldots, T 计算所有隐藏状态和输出

  2. 计算损失L=t=1TLt(yt,y^t)L = \sum_{t=1}^{T} L_t(y_t, \hat{y}_t)

  3. 反向传播:从 t=Tt = T 逆序回溯到 t=1t = 1,累积梯度

  4. 参数更新:梯度求和后一次性更新共享参数

对权重 WhhW_{hh} 的梯度为:

LWhh=t=1Tk=1tLthththkhkWhh\frac{\partial L}{\partial W_{hh}} = \sum_{t=1}^{T} \sum_{k=1}^{t} \frac{\partial L_t}{\partial h_t} \cdot \frac{\partial h_t}{\partial h_k} \cdot \frac{\partial h_k}{\partial W_{hh}}

Truncated BPTT:实践中,为减少计算量和缓解梯度问题,通常将序列截断为固定长度的片段进行反向传播,而不是完整回溯到 t=1t=1


二、梯度问题#

2.1 问题本质#

在 BPTT 中,梯度从时刻 t 传播到时刻 k 需要经过连乘:

梯度传播公式:

hthk=i=k+1tWhhdiag(σ(zi))\frac{\partial h_t}{\partial h_k} = \prod_{i=k+1}^{t} W_{hh} \cdot \text{diag}(\sigma'(z_i))

其中 zi=Whhhi1+Wxhxi+bhz_i = W_{hh} \cdot h_{i-1} + W_{xh} \cdot x_i + b_hσ\sigma' 为激活函数的导数。

这是一个矩阵连乘,其行为由 WhhW_{hh} 的特征值决定:

2.2 梯度消失 vs 梯度爆炸#

问题梯度消失(Vanishing)梯度爆炸(Exploding)
条件WhhW_{hh} 的最大特征值 <1< 1WhhW_{hh} 的最大特征值 >1> 1
现象梯度以指数速度趋近于 0梯度以指数速度趋近于 \infty
后果无法学习长程依赖关系参数更新过大,训练不稳定(NaN)
直觉类比反复乘以 0.9:0.91000.0000270.9^{100} \approx 0.000027反复乘以 1.1:1.1100137811.1^{100} \approx 13781
解决方案LSTM/GRU 门控机制、残差连接梯度裁剪(Gradient Clipping)

2.3 梯度裁剪(Gradient Clipping)#

梯度裁剪公式(解决梯度爆炸):

g>threshold\|g\| > \text{threshold},则:gthreshold×ggg \leftarrow \text{threshold} \times \frac{g}{\|g\|}

即保持梯度方向不变,但将其范数缩放到阈值以内。

直觉理解:梯度裁剪相当于在梯度空间中设定一个”速度上限”,防止参数更新步幅过大导致训练发散。


三、LSTM(Long Short-Term Memory)#

3.1 设计动机#

引入细胞状态(Cell State)CtC_t 作为信息传输的”高速公路”。细胞状态通过加法更新(而非乘法),使梯度能够无衰减地长距离流动,从根本上解决梯度消失问题。

3.2 LSTM 结构概览#

3.3 三个门(Gates)详解#

所有门都使用 sigmoid 激活函数,输出值在 [0,1][0, 1] 之间,起到”开关”的作用:0 表示完全阻断,1 表示完全通过。

(1)遗忘门(Forget Gate)#

决定从细胞状态中丢弃什么信息

ft=σ(Wf[ht1,xt]+bf)f_t = \sigma(W_f \cdot [h_{t-1}, x_t] + b_f)

ft0f_t \approx 0 时,旧信息被遗忘;当 ft1f_t \approx 1 时,旧信息被保留。

(2)输入门(Input Gate)#

决定存储什么新信息到细胞状态

门控信号:it=σ(Wi[ht1,xt]+bi)i_t = \sigma(W_i \cdot [h_{t-1}, x_t] + b_i)

候选值:C~t=tanh(WC[ht1,xt]+bC)\tilde{C}_t = \tanh(W_C \cdot [h_{t-1}, x_t] + b_C)

iti_t 控制候选值中哪些分量被写入细胞状态。

(3)输出门(Output Gate)#

决定从细胞状态中输出什么信息作为隐藏状态

ot=σ(Wo[ht1,xt]+bo)o_t = \sigma(W_o \cdot [h_{t-1}, x_t] + b_o)

输出门过滤细胞状态,生成当前时刻的隐藏状态。

3.4 状态更新公式#

细胞状态更新(加法结构——梯度高速公路):

Ct=ftCt1+itC~tC_t = f_t \odot C_{t-1} + i_t \odot \tilde{C}_t

隐藏状态输出:

ht=ottanh(Ct)h_t = o_t \odot \tanh(C_t)

为什么解决梯度消失?

  • 细胞状态通过加法更新,梯度沿 CtC_t 传播时:CtCt1=ft\frac{\partial C_t}{\partial C_{t-1}} = f_t

  • 遗忘门 ftf_t 可以学习到接近 1 的值,使梯度几乎无损传播

  • 相比标准 RNN 的连续矩阵乘法,LSTM 的加法结构避免了指数衰减


四、GRU(Gated Recurrent Unit)#

4.1 设计思想#

GRU 是 LSTM 的简化版本,将 3 个门简化为 2 个门,同时将细胞状态和隐藏状态合并为一个状态。在许多任务上 GRU 的性能与 LSTM 相当,但参数更少、训练更快。

4.2 GRU 公式#

更新门(合并了 LSTM 的遗忘门和输入门):

zt=σ(Wz[ht1,xt])z_t = \sigma(W_z \cdot [h_{t-1}, x_t])

重置门(控制遗忘多少历史信息):

rt=σ(Wr[ht1,xt])r_t = \sigma(W_r \cdot [h_{t-1}, x_t])

候选隐藏状态

h~t=tanh(W[rtht1,xt])\tilde{h}_t = \tanh(W \cdot [r_t \odot h_{t-1}, x_t])

最终隐藏状态(插值更新):

ht=(1zt)ht1+zth~th_t = (1 - z_t) \odot h_{t-1} + z_t \odot \tilde{h}_t

直觉理解:

  • **更新门 **ztz_t:决定”保留多少旧状态 vs 接受多少新信息”——当 zt=0z_t = 0 时完全保留旧状态,zt=1z_t = 1 时完全使用新候选值

  • **重置门 **rtr_t:决定计算候选值时”参考多少历史”——当 rt=0r_t = 0 时忽略历史,相当于从头开始

4.3 LSTM vs GRU 对比#

特性LSTMGRU
门的数量3 个(遗忘、输入、输出)2 个(更新、重置)
状态细胞状态 CtC_t + 隐藏状态 hth_t仅隐藏状态 hth_t
参数量4×(n2+nm+n)4 \times (n^2 + nm + n)3×(n2+nm+n)3 \times (n^2 + nm + n)
计算复杂度较高(更多矩阵运算)较低(约 LSTM 的 75%)
长序列建模略优(独立的细胞状态通道)稍逊
训练速度较慢较快
适用场景长序列、需要精细记忆控制中等序列、计算资源有限
输出暴露通过输出门过滤直接暴露全部状态

五、RNN 应用模式#

5.1 四种基本模式#

Many-to-One(序列分类)

输入:整个序列 x1,x2,,xTx_1, x_2, \ldots, x_T

输出:单个标签 yy

典型应用:情感分析、文档分类

方法:取最后时刻隐藏状态 hTh_T 进行分类

One-to-Many(序列生成)

输入:单个向量 xx(如图像特征)

输出:序列 y1,y2,,yTy_1, y_2, \ldots, y_T

典型应用:图像描述生成、音乐生成

方法:初始输入驱动,逐步生成

Many-to-Many(Seq2Seq)

输入:序列 x1,,xTx_1, \ldots, x_T

输出:不同长度序列 y1,,yTy_1, \ldots, y_{T'}

典型应用:机器翻译、文本摘要

方法:Encoder-Decoder 架构

Many-to-Many Synced(序列标注)

输入:序列 x1,x2,,xTx_1, x_2, \ldots, x_T

输出:等长序列 y1,y2,,yTy_1, y_2, \ldots, y_T

典型应用:词性标注(POS)、NER

方法:每个时间步都有对应输出

5.2 Encoder-Decoder 架构(Seq2Seq)#

工作流程:

  1. Encoder:将输入序列编码为固定长度的上下文向量 c=hTencc = h_T^{enc}

  2. Decoder:以上下文向量为初始状态,逐步生成输出序列

  3. Decoder 每一步的输入为上一步的输出(Teacher Forcing 训练时用真实标签)

瓶颈问题:所有输入信息被压缩为单个向量 cc,对长序列信息损失严重。这一问题催生了注意力机制(Attention),将在后续课程中详细讨论。


六、双向 RNN(Bidirectional RNN)#

6.1 动机与结构#

标准 RNN 只能利用过去的信息(从左到右),但很多任务中未来的上下文同样重要。例如在命名实体识别中,判断一个词是否为人名需要同时看其前后的词。

双向 RNN 结构:

前向隐藏状态:ht=σ(Whht1+Wxhxt+bh)\overrightarrow{h_t} = \sigma(W_{\overrightarrow{h}} \cdot \overrightarrow{h_{t-1}} + W_{x\overrightarrow{h}} \cdot x_t + b_{\overrightarrow{h}})

反向隐藏状态:ht=σ(Whht+1+Wxhxt+bh)\overleftarrow{h_t} = \sigma(W_{\overleftarrow{h}} \cdot \overleftarrow{h_{t+1}} + W_{x\overleftarrow{h}} \cdot x_t + b_{\overleftarrow{h}})

最终表示:ht=[ht;ht]h_t = [\overrightarrow{h_t}; \overleftarrow{h_t}](拼接)

特点:

  • 每个时刻的表示融合了过去和未来的完整上下文信息

  • 参数量翻倍(前向和反向各有独立参数)

  • 不适用于实时/在线任务(需要完整序列才能计算反向状态)

  • 非常适合分类和标注任务(如 BERT 的本质就是双向编码)


七、深层 RNN(Deep/Stacked RNN)#

7.1 结构#

将多个 RNN 层垂直堆叠,下层的隐藏状态序列作为上层的输入序列:

ht(l)=σ(Whh(l)ht1(l)+Wxh(l)ht(l1)+bh(l))h_t^{(l)} = \sigma(W_{hh}^{(l)} \cdot h_{t-1}^{(l)} + W_{xh}^{(l)} \cdot h_t^{(l-1)} + b_h^{(l)})

其中 ll 表示层索引,ht(0)=xth_t^{(0)} = x_t

实践建议:

  • RNN 通常堆叠 2-4 层效果最佳(不像 CNN 可以堆几十层)

  • 层间可加 Dropout(注意:仅在层间应用,不在时间步间应用)

  • 深层 RNN + 双向 + LSTM/GRU 是经典的强基线配置


八、总结#

  • RNN 通过隐藏状态实现”记忆”,参数在时间步间共享

  • BPTT 训练时梯度连乘导致消失/爆炸问题

  • LSTM 用加法细胞状态 + 三门机制解决梯度消失

  • GRU 是 LSTM 的简化版(2 门,单一状态)

  • 梯度裁剪解决梯度爆炸

  • 四种应用模式:分类/生成/Seq2Seq/标注

8.1 公式汇总#

模型/概念核心公式
基本 RNNht=σ(Whhht1+Wxhxt+bh)h_t = \sigma(W_{hh} h_{t-1} + W_{xh} x_t + b_h)
梯度传播hthk=i=k+1tWhhdiag(σ(zi))\frac{\partial h_t}{\partial h_k} = \prod_{i=k+1}^{t} W_{hh} \cdot \text{diag}(\sigma'(z_i))
梯度裁剪gthreshold×ggif g>thresholdg \leftarrow \text{threshold} \times \frac{g}{\|g\|} \quad \text{if } \|g\| > \text{threshold}
LSTM 遗忘门ft=σ(Wf[ht1,xt]+bf)f_t = \sigma(W_f \cdot [h_{t-1}, x_t] + b_f)
LSTM 输入门it=σ(Wi[ht1,xt]+bi)i_t = \sigma(W_i \cdot [h_{t-1}, x_t] + b_i)
LSTM 候选值C~t=tanh(WC[ht1,xt]+bC)\tilde{C}_t = \tanh(W_C \cdot [h_{t-1}, x_t] + b_C)
LSTM 输出门ot=σ(Wo[ht1,xt]+bo)o_t = \sigma(W_o \cdot [h_{t-1}, x_t] + b_o)
LSTM 细胞更新Ct=ftCt1+itC~tC_t = f_t \odot C_{t-1} + i_t \odot \tilde{C}_t
LSTM 隐藏状态ht=ottanh(Ct)h_t = o_t \odot \tanh(C_t)
GRU 更新门zt=σ(Wz[ht1,xt])z_t = \sigma(W_z \cdot [h_{t-1}, x_t])
GRU 重置门rt=σ(Wr[ht1,xt])r_t = \sigma(W_r \cdot [h_{t-1}, x_t])
GRU 输出ht=(1zt)ht1+zth~th_t = (1-z_t) \odot h_{t-1} + z_t \odot \tilde{h}_t

8.2 常见问题#

  1. 为什么 RNN 会出现梯度消失?LSTM 如何解决?

  2. LSTM 的遗忘门如果恒为 1、输入门恒为 0 会怎样?(答:细胞状态不更新,完美保持记忆)

  3. GRU 相比 LSTM 的优势和劣势?

  4. 为什么门控单元使用 sigmoid 而不是 tanh?(答:需要 0-1 范围的”门控”语义)

  5. 双向 RNN 为什么不能用于语言模型?(答:语言模型是自回归的,生成时无法看到未来)

(注:内容由 AI 生成,请谨慎参考)

分享到社交平台

将本文分享给你的朋友们

神经网络与深度学习:神经网络基础(第7-8讲)
https://firefly.cuteleaf.cn/posts/神经网络/神经网络与深度学习循环神经网络第7-8讲/
作者
Zhongye
发布于
2026-06-07
版权声明
CC BY-NC-SA 4.0

评论

Profile Image of the Author
Zhongye
南漂中
公告
新的博客站!旧站点传送门 zhongye1.github.io/Arknight-notes
音乐
专辑封面

音乐

暂无播放

0:00 0:00
暂无歌词
分类
标签
站点统计
文章数
147
分类数
15
标签数
214
总字数
365,610
运行天数
0
最后更新
0 天前

目录