2026/3/27 15:37:22
网站建设
项目流程
可视网站开发工具,建筑业招聘网站,wordpress前面增加new,昌乐营销型网站建设Day 10: 循环神经网络 (RNN) 摘要#xff1a;人类阅读时不会每看一个词都把前面的忘了#xff0c;我们的思维是连贯的。循环神经网络 (RNN) 赋予了机器这种“记忆”能力。本文将带你理解 RNN 如何处理序列数据#xff0c;剖析其致命弱点#xff08;梯度消失#xff09;人类阅读时不会每看一个词都把前面的忘了我们的思维是连贯的。循环神经网络 (RNN) 赋予了机器这种“记忆”能力。本文将带你理解 RNN 如何处理序列数据剖析其致命弱点梯度消失并深入图解 LSTM 和 GRU 是如何通过精妙的“门控机制”解决长距离依赖问题的。1. 为什么需要 RNN在 CNN 和 MLP 中输入和输出是独立的看这张猫图和看下一张狗图没关系。但在处理序列数据 (Sequence Data)时前后的顺序至关重要自然语言“我 喜欢 吃 苹果” vs “苹果 喜欢 吃 我”。时间序列今天的股票价格依赖于过去几天的走势。语音当前的音素与前后的发音紧密相关。RNN 的核心思想是不仅利用当前的输入还利用上一时刻的“状态” (Hidden State)。2. RNN 基础原理2.1 结构拆解RNN 可以看作是一个在时间轴上展开的网络。x t x_txtt tt时刻的输入。h t h_thtt tt时刻的隐状态记忆。核心公式h t tanh ( W i h x t W h h h t − 1 b ) h_t \tanh(W_{ih} x_t W_{hh} h_{t-1} b)httanh(WihxtWhhht−1b)y t W h y h t b y y_t W_{hy} h_t b_yytWhyhtby名词解释权重矩阵 (Weight Matrix)公式里的W WW就是神经网络要学习的参数。W i h W_{ih}Wih决定了当前输入x t x_txt如何影响新的记忆。W h h W_{hh}Whh决定了旧记忆h t − 1 h_{t-1}ht−1如何转化为新记忆。梯度消失/爆炸就是因为W h h W_{hh}Whh在时间维度上连乘了太多次几百次循环导致数值失控。通俗理解想象你在读一本书。x t x_txt是你当前看到的词h t − 1 h_{t-1}ht−1是你脑子里对前文的记忆。你把“当前词”和“前文记忆”融合生成新的记忆h t h_tht并以此预测下一个词y t y_tyt。2.2 致命弱点梯度消失/爆炸在反向传播时BPTT梯度需要通过时间维度一步步往回传。如果权重矩阵W 1 W 1W1连乘多次后梯度趋近于 0 ——梯度消失 (Vanishing Gradient)。这导致网络**“记不住”**很久以前的信息例如开头说了 “Alice”结尾忘了是 “She”。如果权重矩阵W 1 W 1W1连乘多次后梯度趋近无穷大 ——梯度爆炸 (Exploding Gradient)。3. LSTM (Long Short-Term Memory)为了解决梯度消失Schmidhuber 等人在 1997 年提出了 LSTM。LSTM 的设计哲学是专门搞一个“高速公路”Cell State让信息能无损地流传下去。3.1 核心组件三个门 (Gates)所有的门都由 Sigmoid 函数控制输出 0~10 代表关遗忘/拦截1 代表开通过。遗忘门 (Forget Gate)f t f_tft决定丢弃哪些旧信息。“这句话讲完了句号了把上一句的主语忘了吧。”输入门 (Input Gate)i t i_tit决定存入哪些新信息。“这个词‘但是’很重要表示转折得记下来。”输出门 (Output Gate)o t o_tot决定当前的隐状态h t h_tht输出什么。3.2 细胞状态 (Cell State)C t C_tCt这是 LSTM 的核心——信息的传送带。C t f t ⋅ C t − 1 i t ⋅ C ~ t C_t f_t \cdot C_{t-1} i_t \cdot \tilde{C}_tCtft⋅Ct−1it⋅C~t旧记忆C t − 1 C_{t-1}Ct−1乘以遗忘门保留一部分。加上新记忆C ~ t \tilde{C}_tC~t乘以输入门存入一部分。关键点这里是加法更新而不是乘法。加法让梯度能更稳定地回传避免了连乘导致的消失问题。4. GRU (Gated Recurrent Unit)LSTM 太复杂了三个门两个状态计算慢。2014 年Bengio 团队提出了 GRU它是 LSTM 的简化版效果差不多但跑得更快。4.1 简化策略合并状态把 Cell StateC t C_tCt和 Hidden Stateh t h_tht合二为一。合并门把遗忘门和输入门合并为更新门 (Update Gate)z t z_tzt。z t z_tzt决定了我是保留旧记忆还是用新输入替换它重置门 (Reset Gate)r t r_trt决定如何将新的输入与旧记忆结合。4.2 LSTM vs GRUGRU参数少3组权重训练快小数据集首选。LSTM参数多4组权重表达能力稍强大数据集或超长序列可能更好。5. 双向 RNN (Bidirectional RNN)有些时候我们不仅需要知道“过去”还需要知道“未来”。例子填空题 “He said ____ to me.”只看前面 “He said”可能是 “hello”, “goodbye”, “nothing”。看了后面 “to me”范围没变。如果句子是 “He said ____ to the crowd.”那可能是 “loudly”。原理两个 RNN一个从左往右读一个从右往左读。最后把两个h t h_tht拼起来。6. Seq2Seq 与 Encoder-Decoder这是 RNN 最辉煌的应用形式也是机器翻译的基础。Encoder (编码器)把输入序列中文压缩成一个上下文向量 (Context Vector)。Decoder (解码器)根据这个向量一步步生成输出序列英文。问题不管句子多长都要压缩成一个固定长度的向量容易**“消化不良”**信息丢失。这直接催生了后来的Attention 机制。7. 代码实践LSTM 文本分类importtorchimporttorch.nnasnnclassRNNClassifier(nn.Module):def__init__(self,vocab_size,embed_dim,hidden_dim,output_dim,n_layers,dropout):super().__init__()# 1. Embedding层把词索引变成稠密向量self.embeddingnn.Embedding(vocab_size,embed_dim)# 2. LSTM层# batch_firstTrue - (batch, seq_len, features)# bidirectionalTrue - 双向LSTMself.lstmnn.LSTM(embed_dim,hidden_dim,num_layersn_layers,bidirectionalTrue,dropoutdropout,batch_firstTrue)# 3. 全连接层# 双向LSTM输出维度是 hidden_dim * 2self.fcnn.Linear(hidden_dim*2,output_dim)self.dropoutnn.Dropout(dropout)defforward(self,text):# text: [batch_size, seq_len]embeddedself.dropout(self.embedding(text))# embedded: [batch_size, seq_len, embed_dim]# output: 每个时间步的输出# hidden: 最后一个时间步的隐状态 (h_n, c_n)output,(hidden,cell)self.lstm(embedded)# hidden: [n_layers * n_directions, batch_size, hidden_dim]# 我们取最后一层的最后时刻状态# 提取正向和反向的最后状态hidden_forwardhidden[-2,:,:]hidden_backwardhidden[-1,:,:]# 拼接 (Concatenate)把两个向量并排粘在一起# 结果维度: [batch_size, hidden_dim * 2]# 不是相加也不是平均而是保留正反向的所有信息hidden_finaltorch.cat((hidden_forward,hidden_backward),dim1)returnself.fc(hidden_final)8. 总结RNN引入了时间维度的记忆。LSTM用“门”和“传送带”解决了长距离遗忘的问题。GRU是 LSTM 的高效简化版。Bi-RNN同时看上下文。Seq2Seq开启了序列生成的时代。虽然 Transformer 现在接管了 NLP但在小模型、流式计算实时语音、时间序列预测等领域LSTM/GRU 依然有一席之地。参考资料Understanding LSTM Networks (Colah’s Blog)Empirical Evaluation of Gated Recurrent Neural Networks on Sequence Modeling