為什么使用序列模型(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深度學習框架》