循环神经网络(RNN)与序列数据处理实战
在处理自然语言、语音或时间序列数据时,传统的前馈神经网络往往显得力不从心。它们假设输入输出相互独立,无法捕捉序列中前后时刻的上下文关联。循环神经网络(RNN)通过引入隐藏状态来存储历史信息,从而有效解决这一问题。本文将深入探讨 RNN 的核心原理,对比 LSTM 与 GRU 等改进模型,并基于 TensorFlow/Keras 完成一个完整的文本情感分类实战。
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 与门控机制
为了解决梯度问题,Hochreiter & Schmidhuber 于 1997 年提出了长短期记忆网络(LSTM)。它通过遗忘门、输入门和输出门协同工作,实现对信息的选择性记忆与遗忘。
- 遗忘门:决定丢弃哪些旧信息(Sigmoid 输出 0~1)。
- 输入门:决定更新哪些新信息(筛选 + 候选值生成)。


