在深度學習領域,傳統的多層感知機(MLP)具有出色的表現,取得了許多成功,它曾在許多不同的任務上——包括手寫數字識別和目標分類上創造了記錄。甚至到了今天,MLP在解決分類任務上始終都比其他方法要略勝一籌。盡管如此,大多數專家還是會達成共識:MLP可以實現的功能仍然相當有限。究其原因,人類的大腦有着驚人的計算功能,而“分類”任務僅僅是其中很小的一個組成部分。我們不僅能夠識別個體案例,更能分析輸入信息之間的整體邏輯序列。這些信息序列富含有大量的內容,信息彼此間有着復雜的時間關聯性,並且信息長度各種各樣。這是傳統的MLP所無法解決的,RNN 正式為了解決這種序列問題應運而生,其關鍵之處在於當前網絡的隱藏狀態會保留先前的輸入信息,用來作當前網絡的輸出。
許多任務需要處理序列數據,比如Image captioning, speech synthesis, and music generation 均需要模型生成序列數據,其他領域比如 time series prediction, video analysis, and musical information retrieval 等要求模型的輸入為序列數據,其他任務比如 機器翻譯,人機對話,controlling a robot 的模型要求輸入輸出均為序列數據。 RNN 模型可以用來處理序列數據, RNN 包含了大量參數,且難於訓練(時間維度的 vanishing/exploding),所以出現一系列對 RNN 優化 ,比如網絡結構、求解算法與並行化。今年來 bidirectional RNN (BRNN)與 LSTM 在 image captioning, language translation, and handwriting recognition 這幾個方向上有了突破性進展 。下面從 RNN 開始來逐一介紹這些網絡模型。
RNN 的結構不同於 MLP ,輸入層與來自序列中上一元素隱層的信號共同作用到當前的隱藏層,如下圖所示:
下圖能更清楚的展示 RNN 的結構:
看下面關於 RNN BP分析之前,請確保之前看過 多層感知機及其BP算法(Multi-Layer Perceptron),此文為 RNN BP 的基礎,現在來看 RNN 的 BP 算法,對於長度為 $T$ 的序列 $x$ ,RNN 的輸入層大小為 $I$ ,隱層大小為 $H$ ,輸出層大小為 $K$ ,可以得到上圖中三個矩陣的維度分別為 : $U \in \mathbb{R}^{I \times H} , W \in \mathbb{R}^{H \times H} , V \in \mathbb{R}^{H \times K} $ ,這里 $x^t$ 代表序列第 $t$ 項 的輸入, $a^t$ 代表第 $t$ 項隱層的輸入,$b^t$ 代表對 $a^t$ 做非線性激活也即為神經網絡的輸出 ,這里 $a^t$ 由輸入層 $x^t$ 與 上一層隱層的輸出 $b^{t-1}$ 共同決定:
\[a_h^t =\sum_iw_{ih}x_i^t +\sum_{h'}w_{h'h}b_{h'}^{t-1}\]
\[b_h^t = f(a_h^t)\]
這里 序列從狀態 $t=1$開始,一般設置 $b^0 = 0 $ 即可,接下來將隱層傳導至輸出層即可,通常 RNN 的輸出層采用與傳統 MLP 的類似的 $softmax$ 來進行分類任務.即輸出層的輸出為:
\[a_k^t = \sum_hw_{hk}b_h^t\]
\[y_k^t = \frac{e^{a_k^t}}{\sum_j e^{a_j^t}}\]
注意 RNN 中由於輸入時疊加了之前的信號,所以反向傳導時不同於傳統的 MLP ,因為對於時刻 $t$ 的輸入層,其殘差不僅來自於輸出,還來自於之后的隱層入下圖所示:
時刻 $t$ ,RNN 輸出層的算殘差項同 MLP 為 $ \delta_k^t = y_k^t-z^t_k$,由於前向傳導時隱層需要接受上一個時刻隱層的信號,所以反向傳導時根據 BPTT 算法,隱層還需接收下一時刻的隱層的反饋:
\[\delta_h^t = f'(a_h^t) \left (\sum_k\delta_k^tw_{hk} + \sum_{h'} \delta^{t+1}_{h'}w_{hh'} \right )\]
當序列長度為 $T$ ,則殘差 $\delta^{T+1}$ 均為 0 。並且整個網絡其實就只有一套參數 $U$、$V$、$W$ , 對於時刻 $t$ 其倒數分別為:
\[U: \ \frac{\partial O}{\partial w_{ih}}= \frac{\partial O}{\partial a_h^t}\frac{\partial a_h^t}{\partial w_{ih}}=\delta_h^tx_i^t\]
\[V: \ \frac{\partial O}{\partial w_{hk}}= \frac{\partial O}{\partial a_k^t}\frac{\partial a_k^t}{\partial w_{hk}}=\delta_k^tb_h^t\]
\[W: \ \frac{\partial O}{\partial w_{h'h}}= \frac{\partial O}{\partial a_h^t}\frac{\partial a_h^t}{\partial w_{h'h}}=\delta_k^tb_{h'}^t \]
為了方便表示,寫成統一的形式(假設對輸入層有 $x_i^t = a_i^t =b_i^t$):
\[\frac{\partial O}{\partial w_{hij}}= \frac{\partial O}{\partial a_j^t}\frac{\partial a_j^t}{\partial w_{ij}}=\delta_j^tb_i^t\]
最后,由於 RNN 的遞歸性 ,對於時刻 $t = 1,2,...,T$ ,將其進行求和即可,下面為最終得 RNN 網絡的關於權重參數的導數:
\[\frac{\partial O}{\partial w_{ij}}= \sum_t\frac{\partial O}{\partial a_j^t}\frac{\partial a_j^t}{\partial w_{ij}} = \sum _t \delta_j^tb_i^t\]
Bidirectional RNNs
RNN 中對於當前時刻 t 通常會考慮之前時刻的信息而沒有考慮下文的信息,Bidirectional RNNs 克服了這一缺點,其引入了對下文的考慮,其結構如下:
可見 BRNN 引入了一套額外的隱層,但是輸入與輸出層是共享的,多了一個隱層意味着多了三套參數分別為 $U'$、$V'$、$W'$ 。BRNN 的訓練算法類似於 RNN ,forward pass 的過程如下:
backward pass 的過程如下:
計算完殘差后,分別對前向參數 $U$、$V$、$W$ 后向參數 $U'$、$V'$、$W'$ 求導即可,至此 BRNN 的訓練算法介紹完畢, 目前 ,BRNN 在 NLP 的序列標注任務中取得了極大的成功。