RNN 与序列数据处理实战
在处理自然语言、语音或时间序列数据时,传统的前馈神经网络往往显得力不从心。这类数据的显著特征是上下文关联性强,当前时刻的信息依赖于之前的历史状态。循环神经网络(RNN)正是为了解决这一问题而设计的,它通过引入隐藏状态来记忆历史信息。
核心原理与计算机制
为什么需要 RNN
普通神经网络假设输入输出相互独立,无法捕捉序列中的依赖关系。RNN 的核心在于其循环核结构,本质上是一个带有自连接的神经元。在每个时间步,它不仅接收当前输入,还结合上一时刻的隐藏状态进行计算。
计算过程可以概括为:
- 初始化隐藏状态 $h_0$,通常设为全零向量。
- 对每个时间步 $t$,更新隐藏状态:$h_t = \tanh(W_{xh}x_t + W_{hh}h_{t-1} + b_h)$。
- 基于隐藏状态生成输出:$y_t = W_{hy}h_t + b_y$。
⚠️ 注意:基础 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)
经典变体:LSTM 与 GRU
为了解决长距离依赖问题,研究者提出了门控机制。长短期记忆网络(LSTM) 是最常用的变体,它通过遗忘门、输入门和输出门控制信息的流动,有效缓解了梯度消失。
LSTM 的门控机制
- 遗忘门:决定丢弃哪些旧信息(Sigmoid 输出 0~1)。
- 输入门:筛选新信息并更新细胞状态。
- 输出门:决定当前细胞状态中哪些部分作为隐藏状态输出。
- 细胞状态:贯穿整个序列的记忆载体。


