核心目标与重点
在深入代码之前,我们先明确一下本章的重点。目标是掌握循环神经网络的核心原理、经典变体结构,以及在文本序列任务中的实战开发流程。理解 RNN 的循环计算机制是关键,同时要学会使用 TensorFlow/Keras 搭建基础 RNN 与 LSTM 模型,完成实际的文本分类任务。
循环神经网络核心原理
为什么需要 RNN
传统的前馈神经网络(如 CNN、全连接网络)通常假设输入和输出是相互独立的。但在处理自然语言文本、语音信号或时间序列数据时,这种假设就不成立了。序列数据的核心特点是当前时刻的信息和之前时刻的信息紧密相关。
循环神经网络通过引入隐藏状态,可以存储历史信息,从而有效捕捉序列数据的上下文依赖关系。
RNN 的循环计算机制
RNN 的核心结构是循环核。它的本质是一个带有自连接的神经元结构。循环核会在每一个时间步接收输入数据和上一个时间步的隐藏状态,计算当前时间步的输出和新的隐藏状态。
计算过程大致分为三步:
- 初始化隐藏状态 h₀,通常设置为全零向量。
- 对每个时间步 t,计算当前隐藏状态 hₜ = tanh(Wₓₕxₜ + Wₕₕhₜ₋₁ + bₕ)。
- 根据隐藏状态计算当前时间步输出 yₜ = Wₕᵧhₜ + bᵧ。
⚠️ 注意:基础 RNN 存在梯度消失或梯度爆炸问题。它无法有效捕捉长序列的依赖关系,因此实际应用中更多使用其变体模型。
import tensorflow as tf
from tensorflow.keras.layers import SimpleRNN
# 定义基础 RNN 层
# units: 隐藏状态维度,return_sequences: 是否返回所有时间步输出
rnn_layer = SimpleRNN(units=64, return_sequences=True, input_shape=(10, 20))
# 模拟输入:批次大小 32,序列长度 10,每个时间步特征维度 20
input_seq = tf.random.normal(shape=(32, 10, 20))
# 执行 RNN 计算
output_seq = rnn_layer(input_seq)
print("RNN 输出形状:", output_seq.shape)
# 输出形状 (32, 10, 64)
RNN 的梯度问题与改进方向
基础 RNN 在处理长序列时,梯度在反向传播过程中会随着时间步的增加而指数级衰减或膨胀。这会导致模型无法学习到长距离的依赖关系。
为了解决这个问题,研究者提出了两种经典的 RNN 变体:长短期记忆网络(LSTM) 和 门控循环单元(GRU)。它们通过引入门控机制,来控制信息的遗忘和更新,从而有效缓解梯度消失问题。


