為什麼使用序列模型(sequence model)?標準的全連線神經網路(fully connected neural network)處理序列會有兩個問題:1)全連線神經網路輸入層和輸出層長度固定,而不同序列的輸入、輸出可能有不同的長度,選擇最大長度並對短序列進行填充(pad)不是一種很好的方式;2)全連線神經網路同一層的節點之間是無連線的,當需要用到序列之前時刻的資訊時,全連線神經網路無法辦到,一個序列的不同位置之間無法共享特徵。而迴圈神經網路(Recurrent Neural Network,RNN)可以很好地解決問題。
1. 序列資料
在介紹迴圈神經網路之前,先來了解一些序列資料:
圖 1:序列資料
輸入 $x$ 和輸出 $y$ 可能都是序列,也可能只有一個是序列;輸入 $x$ 和輸出 $y$ 兩個序列的長度可能相等也可能不等。下文介紹迴圈神經網路結構時,輸入 $x$ 和輸出 $y$ 兩個序列的長度相同。(下文出現的 $h$ 和最終的輸出結果 $y$ 在本文中被認為不相同)
2. 迴圈神經網路的結構
圖 2 展示了一個經典的迴圈神經網路(RNN):(這張圖初次看真的讓人很懵)
圖 2:迴圈神經網路經典結構示意圖
對於 RNN,一個非常重要的概念就是時刻。RNN 會對每一個時刻的輸入結合當前模型的狀態給出一個輸出。圖 2 中,$t$ 時刻 RNN 的主體結構 A 的輸入除了來自輸入層 $X_t$,還有一個迴圈的邊來提供從 $t-1$ 時刻傳遞來的隱藏狀態。(這一段看不懂沒關係,看下面)
RNN 可以被看作是同一個神經網路結構按照時間序列複製的結果。圖 3 展示了一個展開的 RNN。(展開圖相對比較好理解)
圖 3:迴圈神經網路按時間展開
從 RNN 的展開結構可以很容易得出它最擅長解決的問題是與時間序列相關的。RNN 也是處理這類問題時最自然的神經網路結構。
RNN 的主體結構 A 按照時間序列複製了多次,結構 A 也被稱之為迴圈體。如何設計迴圈體 A 的網路結構是 RNN 解決實際問題的關鍵。和卷積神經網路(CNN)過濾器中引數共享類似,在 RNN 中,迴圈體 A 中的引數在不同時刻也是共享的。
圖 4 展示了一個最簡單的使用單個全連線層作為迴圈體 A 的 RNN,圖中黃色的 tanh 小方框表示一個使用 tanh 作為啟用函式的全連線層。
圖 4:使用單層全連線神經網路作為迴圈體的 RNN 結構圖
圖 5:圖 4 中各種符號代表的含義
(注:Pointwise Operation在圖 4 中沒有出現)
$t$ 時刻迴圈體 A 的輸入包括 $X_t$ 和從 $t-1$ 時刻傳遞來的隱藏狀態 $h_{t-1}$(依據圖 5 copy 標誌,$t-1$ 和 $t$ 時刻迴圈體 A 之間連線的箭頭即表示隱藏狀態 $h_{t-1}$ 的傳遞)。迴圈體 A 的兩部分輸入如何處理呢?依據圖 5 ,將 $X_t$ 和 $h_{t-1}$ 直接拼接起來,成為一個更大的矩陣/向量 $[X_t, h_{t-1}]$。假設 $X_t$ 和 $h_{t-1}$ 的形狀分別為 [1, 3] 和 [1, 4],則最後迴圈體 A 中全連線層輸入向量的形狀為 [1, 7]。拼接完後按照全連線層的方式進行處理即可。
為了將當前時刻的隱含狀態 $h_t$ 轉化為最終的輸出 $y_t$,迴圈神經網路還需要另一個全連線層來完成這個過程。這和卷積神經網路中最後的全連線層意義是一樣的。(如果不考慮 RNN 的輸出還需要一個全連線層的情況,那麼 $h_t$ 和 $y_t$ 的值是一樣的)
RNN 的前向傳播計算過程如下圖所示:
圖 6:RNN的前向傳播計算過程示意圖
圖 6 很清晰地向我們展示了 RNN 迴圈體 A 中具體的計算流程,以及當前隱藏狀態 $h_t$ 轉化為最終輸出 $y_t$ 的過程。
3. 迴圈神經網路的型別
圖 7:RNN 的型別
(1)one to one:其實和全連線神經網路並沒有什麼區別,這一類別算不得是 RNN。
(2)one to many:輸入不是序列,輸出是序列。
(3)many to one:輸入是序列,輸出不是序列。
(4)many to many:輸入和輸出都是序列,但兩者長度可以不一樣。
(5)many to many:輸出和輸出都是序列,兩者長度一樣。
4. 基礎迴圈神經網路的侷限
上述圖片中展示的都是單向的 RNN,單向 RNN 有個缺點是在 $t$ 時刻,無法使用 $t+1$ 及之後時刻的序列資訊,所以就有了雙向迴圈神經網路(bidirectional RNN)。
“需要特別指出,理論上迴圈神經網路可以支援任意長度的序列,然而在實際中,如果序列過長會導致優化時出現梯度消散的問題(the vanishing gradient problem),所以實際中一般會規定一個最大長度,當序列長度超過規定長度之後會對序列進行截斷。”
RNN 面臨的一個技術挑戰是長期依賴(long-term dependencies)問題,即當前時刻無法從序列中間隔較大的那個時刻獲得需要的資訊。在理論上,RNN 完全可以處理長期依賴問題,但實際處理過程中,RNN 表現得並不好。
但是 GRU 和 LSTM 可以處理梯度消散問題和長期依賴問題。
5. 門控迴圈單元(Gated Recurrent Unit,GRU)和 長短時記憶網路(Long Short Term Memory,LSTM)
相比於基礎的RNN,GRU 和 LSTM 與之不同的地方在於迴圈體 A 的網路結構。
GRU 和 LSTM 都引入了一個的概念,門(gate)。GRU 有兩個“門”(“更新門”和“重置門”),而 LSTM 有三個“門”(“遺忘門”、“輸入門”和“輸出門”)。
圖 8:LSTM
圖 9:GRU
GRU 和 LSTM 靠一些“門”的結構讓資訊有選擇地影響迴圈神經網路中每個時刻的狀態。所謂“門”結構,就是一個使用 sigmoid 的全連線層和一個按位做乘法的操作,這兩個操作合起來就是一個“門”結構,如圖 9所示。
圖 9:“門”結構
之所以叫“門”結構,是因為使用 sigmoid 作為啟用函式的全連線神經網路層會輸出一個 0 到 1 之間的數值,描述當前輸入有多少資訊量可以通過這個結構。於是這個結構的功能就類似於一扇門,當門開啟時(sigmoid 全連線層輸出為 1 時),全部資訊可以通過;當門關上時(sigmoid 神經網路層輸出為 0 時),任何資訊都無法通過。
LSTM 有三個門,分別是“遺忘門”(forget gate)、“輸入門”(input gate)和“輸出門”(output gate)。“遺忘門”的作用是讓迴圈神經網路“忘記”之前沒有用的資訊。“輸入門”決定哪些資訊進入當前時刻的狀態。通過“遺忘門”和“輸入門”,LSTM 結構可以很有效地決定哪些資訊應該被遺忘,哪些資訊應該得到保留。LSTM 在得到當前時刻狀態 $C_t$ 之後,需要產生當前時刻的輸出,該過程通過“輸出門”完成。
GRU 的兩個門:一個是“更新門”(update gate),它將 LSTM 的“遺忘門”和“輸入門”融合成了一個“門”結構;另一個是“重置門”(reset gate)。“從直觀上來說,‘重置門’決定了如何將新的輸入資訊與前面的記憶相結合,‘更新門’定義了前面記憶儲存到當前時刻的量。” “那些學習捕捉短期依賴關係的單元將趨向於啟用‘重置門’,而那些捕獲長期依賴關係的單元將常常啟用‘更新門’。”
LSTM 和 GRU 更多內容,請參考 Understanding LSTM Networks 和 機器之心GitHub專案:從迴圈到卷積,探索序列建模的奧祕。
(注:文中出現的字母 $h$ 表示 hidden state, $C$ 表示 cell state。)
References
The Unreasonable Effectiveness of Recurrent Neural Networks
Course 5 Sequence Models by Andrew Ng
《TensorFLow實戰Google深度學習框架》