循環神經網絡(Recurrent Neural Network,RNN)是深度學習中專門用于處理序列數據的一類神經網絡。與不同,RNN 不只是把輸入從前向后逐層傳遞,而是在處理序列時引入“隱藏狀態”,讓模型能夠把前面時間步的信息傳遞到后面時間步。
在很多任務中,數據并不是彼此獨立的靜態樣本,而是按照時間、位置或順序排列的序列。
例如:
? 一句話中的詞語有前后順序
? 一段語音由連續聲音幀組成
? 一支股票的價格隨時間變化
? 一個用戶的行為記錄具有先后關系
? 一段傳感器數據由連續采樣點組成
這類數據的核心特點是:當前輸入的含義往往依賴前面的上下文。
循環神經網絡正是為這類序列數據設計的基礎模型。它通過在時間步之間傳遞隱藏狀態,使模型能夠在處理當前輸入時“記住”前面已經看到的信息。
一、為什么需要循環神經網絡
普通(Feedforward Neural Network,FNN)通常假設輸入是固定長度向量,并且一次性完成從輸入到輸出的映射。
例如,一個前饋網絡可以寫為:
其中:
? x 表示輸入樣本
? ? 表示模型預測結果
? f 表示由多層計算組成的函數
? θ 表示模型中的可訓練參數
這種結構適合處理固定長度、整體輸入的任務,例如表格分類、圖像分類中的分類頭等。
但是,序列數據通常具有兩個特點。
第一,序列長度可能不固定。
一句話可能有 5 個詞,也可能有 50 個詞;一段時間序列可能有幾十個時間點,也可能有幾千個時間點。
第二,序列中的元素具有順序依賴。
同一個詞出現在不同上下文中,含義可能不同;同一個數值在不同時間趨勢中,也可能代表不同含義。
例如,句子:
這部電影一點也不好看如果只看“好看”兩個字,可能會誤判為正面評價;但結合前面的“一點也不”,整體語義實際上是負面評價。
普通前饋網絡如果直接把句子或時間序列展平成固定向量,通常難以自然表示這種前后依賴關系。
![]()
圖 1:從前饋神經網絡到循環神經網絡
循環神經網絡的基本思想是:按時間步依次讀取序列,并在每個時間步更新隱藏狀態,使模型能夠把歷史信息傳遞到后續計算中。
可以簡單理解為:
? 前饋神經網絡:一次性處理一個整體輸入
? 循環神經網絡:按順序處理輸入,并不斷更新“記憶”
這里的“記憶”并不是人工寫入的規則,而是模型在訓練過程中學習到的隱藏狀態表示。
二、RNN 的基本結構
![]()
圖 2:RNN 的基本循環結構
循環神經網絡的核心結構是循環單元。它在每個時間步接收兩個輸入:
? 當前時間步的輸入 x?
? 上一個時間步的隱藏狀態 h???
然后計算當前時間步的隱藏狀態 h?:
其中:
? x? 表示第 t 個時間步的輸入
? h??? 表示上一個時間步的隱藏狀態
? h? 表示當前時間步的隱藏狀態
? W? 表示輸入到隱藏狀態的權重矩陣
? W? 表示隱藏狀態到隱藏狀態的權重矩陣
? b 表示偏置向量
? φ 表示激活函數,常見為 tanh 或 ReLU
如果需要在每個時間步輸出結果,可以繼續寫為:
其中:
? y? 表示第 t 個時間步的輸出
? W? 表示隱藏狀態到輸出的權重矩陣
? c 表示輸出層偏置
? g 表示輸出層變換
從結構上看,RNN 的關鍵不是某一層有多復雜,而是它在時間維度上反復使用同一組參數。
也就是說,第 1 個時間步、第 2 個時間步、……、第 T 個時間步,使用的是同一個 RNN 單元和同一組參數。
這類似于 CNN 中的“權重共享”:CNN 在空間位置上共享卷積核參數,RNN 在時間步上共享循環單元參數。
三、按時間展開:理解隱藏狀態如何傳遞
RNN 的循環結構可以按時間展開(Unroll)來理解。
![]()
圖 3:RNN 按時間展開的結構
假設輸入序列為:
RNN 會依次計算:
一直到:
其中:
? T 表示序列長度
? h? 表示初始隱藏狀態,通常可以設為零向量
? h?、h?、…、h? 表示不同時間步的隱藏狀態
從這個過程可以看出,h? 不只依賴當前輸入 x?,也間接依賴前面所有時間步的信息。
例如:
? h? 依賴 x? 和 h?
? h? 依賴 x? 和 h?
? h? 依賴 x? 和 h?
因此,h? 實際上包含了 x?、x?、x? 的歷史信息。
這就是 RNN 能夠處理序列數據的原因。
四、RNN 的輸入、輸出與常見任務形式
RNN 可以根據任務需要設計不同的輸入輸出形式。常見形式包括一對一、一對多、多對一和多對多。
![]()
圖 4:RNN 的常見輸入輸出形式
1、一對一:普通非序列任務
一對一形式類似普通前饋網絡:
一個輸入 → 一個輸出
例如:
? 圖像分類
? 表格分類
? 單樣本回歸
這類任務本身不一定需要 RNN。
2、一對多:從一個輸入生成一個序列
一對多形式是:
一個輸入 → 多個輸出
例如:
? 圖像生成文字描述
? 給定主題生成文本
? 給定初始條件生成時間序列
這類任務需要模型從一個初始信息開始,逐步生成序列輸出。
3、多對一:序列分類
多對一形式是:
多個輸入 → 一個輸出
例如:
? 文本情感分類
? 用戶流失預測
? 時間序列故障判斷
? 語音片段分類
在這種任務中,模型讀取完整序列后,根據最后的隱藏狀態或聚合后的隱藏狀態給出一個整體預測。
例如,文本情感分類可以理解為:
詞語序列 → RNN → 最終隱藏狀態 → 情感類別
4、多對多:序列標注或序列生成
多對多形式是:
多個輸入 → 多個輸出
例如:
? 詞性標注
? 命名實體識別
? 機器翻譯
? 語音識別
? 每個時間點的狀態預測
如果輸入序列和輸出序列長度相同,可以在每個時間步輸出一個預測結果。
如果輸入序列和輸出序列長度不同,則通常需要編碼器—解碼器結構。
五、隱藏狀態、記憶能力與局限
RNN 的隱藏狀態可以理解為模型對歷史信息的壓縮表示。
在第 t 個時間步,隱藏狀態 h? 匯總了當前輸入 x? 和此前隱藏狀態 h??? 中的信息。這樣,模型就能在處理后續輸入時利用前面的上下文。
從直觀角度看:
隱藏狀態 = 當前輸入 + 歷史信息的綜合表示
但是,普通 RNN 的記憶能力并不是無限的。
在較長序列中,早期信息需要經過很多時間步才能影響后面的輸出。反向傳播時,梯度也需要沿時間步不斷向前傳遞。這會帶來兩個經典問題:
? 梯度消失
? 梯度爆炸
1、梯度消失
(Vanishing Gradient)是指梯度在反向傳播過程中逐漸變得非常小,導致較早時間步的參數難以有效更新。
在長序列任務中,這意味著模型很難學習遠距離依賴。
例如,在句子:
雖然這部電影前半段節奏很慢,但結尾非常精彩,所以我還是很喜歡如果模型需要根據句子后面的“很喜歡”判斷整體情感,就必須結合前面的轉折結構。如果序列很長,普通 RNN 可能難以穩定保留遠處信息。
2、梯度爆炸
(Exploding Gradient)是指梯度在反向傳播過程中不斷放大,導致參數更新過大,訓練不穩定,甚至出現損失變成異常值的情況。
常見緩解方法包括:
? 梯度裁剪
? 更合適的初始化
? 使用 LSTM 或 GRU
? 使用更穩定的優化器
在 PyTorch 中,梯度裁剪常用寫法是:
torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)3、普通 RNN 的主要局限
![]()
圖 5:RNN 的隱藏狀態與長距離依賴問題
普通 RNN 的主要局限包括:
? 難以建模長距離依賴
? 訓練時可能出現梯度消失或梯度爆炸
? 序列計算難以完全并行
? 對較長文本或復雜上下文任務表現有限
因此,在很多實際任務中,普通 RNN 常被 LSTM、GRU、Transformer 等結構替代或擴展。
六、LSTM 與 GRU:對普通 RNN 的改進
為了解決普通 RNN 難以建模長距離依賴的問題,研究者提出了更復雜的循環結構,其中最經典的是 LSTM 和 GRU。
1、LSTM:加入門控機制與記憶單元
(Long Short-Term Memory,LSTM)在普通 RNN 的基礎上引入了記憶單元和門控機制。
LSTM 的核心思想是:讓模型自己學習哪些信息應該保留,哪些信息應該遺忘,哪些新信息應該寫入。
它通常包含三個重要門控:
? 遺忘門:決定保留多少過去信息
? 輸入門:決定寫入多少當前信息
? 輸出門:決定輸出多少內部記憶
可以簡單理解為:
? 普通 RNN:所有信息都混合在隱藏狀態中
? LSTM:通過門控機制管理信息的保留、寫入和輸出
LSTM 更適合處理較長序列和復雜上下文關系。
2、GRU:更簡化的門控循環單元
(Gated Recurrent Unit,GRU)可以看作一種更簡化的門控 RNN。它通常包含:
? 更新門
? 重置門
GRU 的結構比 LSTM 更簡單,參數更少,訓練速度通常更快。在很多任務中,GRU 能取得接近 LSTM 的效果。
3、普通 RNN、LSTM 與 GRU 的關系
可以粗略理解為:
? RNN:基礎循環結構,簡單但長距離記憶能力有限
? LSTM:加入更完整的門控機制,適合長序列建模
? GRU:結構更簡潔的門控循環網絡,在效率和效果之間折中
![]()
圖 6:RNN、LSTM 與 GRU 的結構對比
在學習路徑上,普通 RNN 適合幫助理解序列建模的基本思想;LSTM 和 GRU 則是更常見的實用循環網絡結構。
七、PyTorch 實現:使用 RNN 進行文本情感分類
下面使用 PyTorch 構建一個簡單 RNN,用于演示文本情感分類的基本流程。
![]()
圖 7:RNN 文本分類的訓練與預測流程
為了避免依賴外部大型數據集,示例使用一個小型中文樣例數據集。這個示例的目標不是訓練高性能模型,而是幫助理解 RNN 的基本輸入、隱藏狀態和訓練閉環。
任務是:根據一句中文短句,判斷它是正面情感還是負面情感。
1、導入庫并準備數據
構造一個簡單數據集:
為了簡化演示,這里按“單字”構建詞表。真實任務中通常會使用分詞器、子詞模型或預訓練詞向量。
2、構建字符表與編碼函數
其中:
? char_to_id 用于把字符轉換為整數編號
? pad_id=0 表示填充符
? encode_text() 把文本轉換為編號序列
例如:
print(encode_text("電影好看"))輸出可能類似:
[33, 22, 16, 34]3、定義數據集與填充函數
因為不同句子的長度可能不同,所以需要在一個批次中把它們填充到相同長度。
其中:
? Dataset 用于定義樣本讀取方式
? collate_fn 用于處理一個 batch 中不同長度的序列
? pad_sequence 用于把序列填充到相同長度
? batch_first=True 表示輸出形狀為 batch_size × sequence_length
構建 DataLoader:
4、定義 RNN 文本分類模型
文本輸入需要先經過嵌入層(Embedding Layer),把整數編號轉換為稠密向量。
這個模型包含三部分:
Embedding → RNN → Linear
其中:
? Embedding 把字符編號轉換為向量
? RNN 按順序讀取字符向量并更新隱藏狀態
? Linear 根據最終隱藏狀態輸出類別得分
需要注意:
? x 的形狀是 batch_size × sequence_length
? embedded 的形狀是 batch_size × sequence_length × embed_dim
? hidden 的形狀是 num_layers × batch_size × hidden_size
? last_hidden 表示最后一層 RNN 的最終隱藏狀態
? logits 的形狀是 batch_size × num_classes
5、定義模型、損失函數和優化器
其中:
? vocab_size 表示詞表大小
? embed_dim 表示字符向量維度
? hidden_size 表示隱藏狀態維度
? num_classes=2 表示二分類
? CrossEntropyLoss 用于多類分類,包括二分類的兩個類別輸出
? Adam 用于更新模型參數
這里模型最后輸出的是 logits,不需要手動添加 Softmax。
6、訓練模型
訓練流程仍然是深度學習中的標準閉環:
前向傳播 → 計算損失 → 清空舊梯度 → 反向傳播 → 更新參數
其中:
? logits = model(batch_x, lengths) 表示前向傳播
? loss = criterion(logits, batch_y) 表示計算分類損失
? optimizer.zero_grad() 清空舊梯度
? loss.backward() 自動計算新梯度
? optimizer.step() 根據梯度更新參數
7、預測新句子
測試預測:
print(predict_sentiment("服務太差了"))可能輸出:
負面由于這里的數據集非常小,模型只是演示 RNN 的基本流程,不能代表真實中文情感分析系統的效果。真實任務通常需要更大數據集、更可靠的分詞方法、更復雜的模型結構,以及驗證集和測試集評估。
8、查看張量形狀
可以通過打印形狀來理解 RNN 的輸入輸出:
可能看到類似結果:
最終隱藏狀態形狀: torch.Size([1, 4, 32])其中:
? 4 表示 batch_size
? 8 表示當前批次中填充后的序列長度
? 16 表示嵌入向量維度
? 32 表示隱藏狀態維度
? 1 表示 RNN 層數
八、RNN 的適用場景、局限與擴展方向
RNN 是序列建模中的基礎模型。它雖然在許多現代任務中已經被 LSTM、GRU 或 Transformer 替代,但仍然是理解序列神經網絡的重要入口。
![]()
圖 8:RNN 的適用場景、局限與擴展方向
1、適用場景
RNN 適合處理具有順序關系的數據,例如:
? 文本分類
? 時間序列預測
? 語音識別
? 序列標注
? 用戶行為建模
? 傳感器數據分析
? 簡單序列生成任務
這些任務的共同特點是:數據元素之間存在順序依賴。
2、主要優勢
RNN 的主要優勢包括:
? 能處理變長序列
? 能通過隱藏狀態傳遞歷史信息
? 參數在時間步之間共享
? 適合解釋序列建模的基本思想
? 可以擴展為 LSTM、GRU、編碼器—解碼器結構
與前饋神經網絡相比,RNN 更適合處理“前后相關”的數據。
3、主要局限
普通 RNN 也有明顯局限:
? 長距離依賴建模能力有限
? 容易出現梯度消失或梯度爆炸
? 時間步之間存在依賴,難以完全并行計算
? 對長文本和復雜上下文任務表現有限
? 實際應用中常被 LSTM、GRU 或 Transformer 替代
這些局限并不意味著 RNN 不重要。相反,RNN 是理解序列建模、隱藏狀態和時間展開的重要基礎。
4、擴展方向
從普通 RNN 出發,可以繼續學習:
? LSTM:通過門控機制增強長期記憶能力
? GRU:更簡潔的門控循環網絡
? 雙向 RNN:同時利用前向和后向上下文
? 編碼器—解碼器結構:用于序列到序列任務
? 注意力機制:幫助模型直接關注重要時間步
? Transformer:用自注意力機制替代循環結構,提升并行能力和長距離建模能力
這些模型雖然結構更復雜,但都可以從 RNN 的基本問題出發理解:如何讓模型有效利用序列中的上下文信息。
小結
循環神經網絡通過隱藏狀態在時間步之間傳遞歷史信息,使模型能夠處理文本、語音、時間序列等順序數據。普通 RNN 適合理解序列建模的基本思想,但在長距離依賴上存在梯度消失和訓練效率問題。LSTM、GRU 和 Transformer 等結構,正是在此基礎上進一步改進而來。
“點贊有美意,贊賞是鼓勵”
特別聲明:以上內容(如有圖片或視頻亦包括在內)為自媒體平臺“網易號”用戶上傳并發布,本平臺僅提供信息存儲服務。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.