循環神經網絡
循環神經網絡
這一章主要介紹了循環神經網絡(Recurrent neural network, 簡稱RNN),主要用來處理序列數據,比如一些文字序列或時序數據。對于這類數據,基本的前饋神經網絡會對每一個輸入的特征都訓練一個單獨的參數,而不能很好的進行參數的共享,而RNN就可以通過對不同時間點的特征共享參數而更容易的進行訓練,泛化效果也更好。上一章CNN也可以實現參數共享,RNN與其不同的地方在于其每一點的輸出還依賴于之前的結果。
循環
recurrent也得名于 \(t\) 時刻的狀態依賴于 \(t-1\) 時刻的狀態。當然,我們可以把該式不斷的展開直至可以用對于初始狀態 \(s^{(1)}\) 的不斷的函數疊加來表示,如圖所示,我們可以將計算圖展開如下

如果我們對于該系統由外部信號驅動,則可以表示為 \(s^{(t)}=f\left(s^{(t-1)}, x^{(t)} ; \theta\right)\) 。RNN就采取的類似的循環公式,只不過用hidden units來代表狀態,即 \(h^{(t)}=f\left(h^{(t-1)}, x^{(t)} ; \theta\right)\) 。同樣的,可以將其計算圖展開如下,展開圖可以有助于理解信息傳播方向和梯度的反向傳播方向:

我們可以將 \(h^{(t)}\) 看做是之前的輸入向量序列 \(\left(x^{(t)}, x^{(t-1)}, \ldots, x^{(1)}\right)\) 的一種有損的表示。根據不同的需要,我們可以控制損失的精度,例如對于一些語言模型,可能只有附近的文字信息比較重要,我們就不需要存儲所有 \(t\) 之前的序列信息。
RNN網絡結構
了解了這些基本概念,我們就可以構建RNN了,最基本的結構如下圖所示

即在每一個時間點都產生輸出,并且hidden units之間有循環鏈接,圖中 \(y\) 為該點的真實目標 值, \(L\) 為模型預測的輸出值 \(O\) 與真實值 \(y\) 間的損失函數如交叉熵,總的損失為各 \(L^{(t)}\) 之和。由 于該結構hidden units之間有循環鏈接,計算時我們需要順序計算,而不能進行并行計算,所以訓練過程較為緩慢。而且該模型需要輸入與輸出序列長度相同。
Teacher forcing
假如我們損失一點模型普適性,去掉hidden units之間的循環鏈接,而是建立前一時間點真實目標值與當前hidden unit的鏈接,則當前點hidden unit并不依賴于前一點hidden unit計算結束,則我們可以有效地將訓練過程并行化,當然 \(y^{(t-1)}\) 并不能完全代表 \(h^{(t-1)}\) 所包含的所有信息,所以 在提高訓練效率的同時降低了一些模型的普適性,這一方法叫做teacher forcing,其計算圖可作如下展開:

還有一種常見的結構是將一個向量而不是向量序列作為輸入,輸出一個序列,這經常用在image caption中,即給定一個圖像,我們常常用CNN得到其特征向量,再將這個特征向量作為輸入,得到描述該圖片的輸出文字序列。這種結構如下圖所示:

上下文RNN
由于之前基本的RNN結構要求輸入與輸出同等長度,而實際應用如語音識別、機器翻譯等往往輸入輸出的長度不同,為了解決這一問題我們可以把上述兩種結構結合起來,即先用一個RNN將輸入序列轉化為一個向量,通常是其最終的隱藏態的一個函數,這一過程稱作encoder或reader,然后再將這一定長的向量作為輸入,利用上圖所示結構產生序列輸出,這一過程稱作decoder或reader,結合起來就是經典的encoder-decoder或稱作sequence-to-sequence結構。注意經過這兩步,輸出和輸入序列不再需要滿足長度相同的條件,如下圖所示 \(n_x\) 與 \(n_y\) 可取不同長度:

c是上下文向量,為Encoder網絡的輸出,包含了所有輸入的信息。通常我們需要c有足夠的維度,這樣才有足夠的信息去描述輸入的信息。Decoder則是采用了向量生成序列的網絡結構。
LSTM與GRU
一個需要注意的問題是,在RNN中,由于相同的權重矩陣被不斷的在hidden state上疊加,梯度會隨著循環次數的增加呈指數的衰減或爆炸,造成模型無法有效的學習long-term的相互作用。即我們每次循環可用 \(h^{(t)}=W h^{(t-1)}\) 表示,假設對權重矩陣 \(W\) 可做本征分解 \(W=Q \Lambda Q^T\) , 則 \(h^{(t)}=Q \Lambda^t Q h^{(0)}\) ,為本征值的\(t\)次方的形式,對于本征值小于 1 的方向會衰減至零而本征值 大于1的方向爆炸。為了解決這種長程作用的問題,一系列gated RNN模型被提出,其中比較常用 的是LSTM和GRU。
LSTM(Long short-term memory)基本單元結構如下圖所示,在hidden state \(h_t\) 的基礎上又添 加了一個新的cell state \(c_t\) ,旨在長程有效的傳遞信息。同時引入了四個作用不同的gate:
-
\(f\)代表forget gate,經過sigmoid函數,其大小在 \((0,1]\) 之間,代表了我們會保留之前的cell state的多 少信息。
-
\(i\)代表input gate,同樣的經過sigmoid函數大小在 \((0,1]\) 之間,代表對于這個cell,有哪些值需要更新。
3)\(g\)經過tanh函數,其大小在 \((-1,1)\) 之間,代表了這些需要更新的值得具體的大小,與input gate做元素積則可求出cell state需要update的值。
4)\(o\)代表output gate,即需要將 哪些 \(c_t\) 的值輸出到hidden state \(h_t\) 。通過這一結構,在一個單元中,我們可以合理的保存某些前 一個單元攜帶的長程信息,以及本單元的一些更新信息,而不是簡單的權重矩陣的乘積,從而解決 了長程作用的問題。

GRU(gated recurrent unit)可以看做是將LSTM中的forget gate和input gate合并成了一個update gate,即下式中的 \(z_t\) ,同時將cell state也合并到hidden state中。由于該模型相較LSTM更為簡化,計算量更小,且最終模型性能類似,所以最近越來越廣泛的得到應用。

LSTM與GRU之所以可以獲得成功,是由于其forget gate的效果,能夠實時地調整過去記憶的獲取方式,從而能夠更容易從記憶中獲得需要的信息量。詳細的LSTM和GRU的推導不再給出,可在花書上找到。
基于記憶力的RNN網絡
改進的RNN模型,如長短時記憶網絡(LSTMs),使長序列訓練克服了梯度消失等問題。然而,即使是更高級的模型也有其局限性,研究人員在處理長數據序列時也很難開發出高質量的模型。例如,在機器翻譯中,RNN必須找到由幾十個單詞組成的長輸入和輸出句子之間的聯系?,F有的RNN體系結構似乎需要改變和適應,以便更好地處理這些任務。
Attention是結合在RNN中的一種機制,它可以在預測輸出序列的某一部分時,將注意力集中在輸入序列的某一部分,從而使學習更容易,質量更高。注意機制使其在許多任務中的性能得到提高,使其成為現代RNN網絡的一個組成部分。
經典上下文RNN
首先介紹一下傳統的RNN結構圖,方便我們在之后比較attention RNN與traditional RNN的區別

RNN編碼器有一個輸入序列\(x_1\), \(x_2\), \(x_3\), \(x_4\)。我們用\(c_1\), \(c_2\), \(c_3\)表示編碼器的狀態。編碼器輸出單個輸出向量c作為輸入傳遞給解碼器。和編碼器一樣,解碼器也是一個單層的RNN,我們用\(s_1\), \(s_2\), \(s_3\)表示解碼器的狀態,用\(y_1\), \(y_2\), \(y_3\), \(y_4\)表示網絡的輸出。
這種結構的問題在于解碼器需要將整個輸入序列\(x_1\), \(x_2\), \(x_3\), \(x_4\)表示為單個向量\(c\),這會導致信息丟失。此外,解碼器需要從這個單一向量中解碼傳遞的信息,這本身就是一項復雜的任務。
這種編譯碼方法的一個潛在問題是,神經網絡需要能夠將源語句的所有必要信息壓縮成一個固定長度的向量。這可能會使神經網絡難以處理長句,尤其是那些比訓練語料庫中的句子長的的長句。
帶注意力機制的RNN

注意力模型有一個單層的RNN編碼器,同樣有4個步驟。我們用\(x_1\), \(x_2\), \(x_3\), \(x_4\)表示編碼器的輸入向量,用\(h_1\), \(h_2\), \(h_3\), \(h_4\)表示輸出向量。
注意力機制位于編碼器和解碼器之間,其輸入是由編碼器的輸出向量\(h_1\), \(h_2\), \(h_3\), \(h_4\)和解碼器的狀態\(s_0\), \(s_1\), \(s_2\), \(s_3\)構成,注意力的輸出向量序列被稱為上下文向量用 \(c_1\), \(c_2\), \(c_3\), \(c_4\)表示。
上下文向量
上下文向量使解碼器能夠在預測輸出時關注輸入的某些部分。每個上下文向量是編碼器的輸出向量\(h_1\), \(h_2\), \(h_3\), \(h_4\) 的加權和,每個向量 \(hi\) 包含整個輸入序列信息(因為它在計算時可以得到編碼器的狀態),這個向量強烈關注第 \(i\) 個輸入序列向量的周圍部分。向量\(h_1\), \(h_2\), \(h_3\), \(h_4\) 被 \(\alpha_{ij}\) 進行加權,得到輸入\(x_j\)對于輸出 \(i\) 時刻的 \(y_i\) 的相關程度。
上下文向量 \(c_1\), \(c_2\), \(c_3\), \(c_4\)這樣得到:
注意力權重是通過一個額外的全連接的淺網絡來學習的,用fc表示,這就是注意力機制輸入的\(s_0\), \(s_1\), \(s_2\), \(s_3\)部分發揮作用的地方。注意力權重的計算方法為:
使用注意力全連接網絡和softmax函數學習注意力權值

在時間步\(i\),注意力機制使用\(h_1\), \(h_2\), \(h_3\), \(h_4\)和 \(s_{i-1}\) 作為輸入,它使用fc神經網絡和softmax函數計算權重\(\alpha_{i1}\),\(\alpha_{i2}\),\(\alpha_{i3}\),\(\alpha_{i4}\),從而計算上下文向量。相比于傳統的上下文RNN,attention機制的RNN在原來的上下文位置引入了一個fc網絡,對于decoder RNN的每次輸入,由原本的固定上下文變量\(c\),變成了 \(\alpha_{ij}\)和\(h_j\)的加權和,其中 \(\alpha_{ij}\) 是 \(s_{i}\) 和 \(h_{j}\) 作為輸入,由fc和softmax層輸出的結果。
可以看到在上面的圖片中,向量的全連接網絡使用 [\(s_{i-1}\),\(h_i\)] 作為輸入在時間步 \(i\) 。網絡有一個全連接層、輸出層用\(e_{ij}\)表示,經過softmax函數計算權重的取值范圍為[0,1]。
注意,我們對所有對 [\(s_{i-1}\),\(h_1\)], [\(s_{i-1}\),\(h_2\)], [\(s_{i-1}\),\(h_3\)], [\(s_{i-1}\),\(h_4\)]使用相同的全連接網絡,這意味著存在一個學習注意力權重的單一網絡。

注意力權重\(\alpha_{ij}\)反映的是\(h_j\)對前面的隱藏狀態\(s_{i-1}\)在決定下一個狀態\(s_i\)和生成\(y_i\)時候的重要性。大的\(\alpha_{ij}\)會導致RNN關注輸入\(x_j\)(通過編碼器的輸出hj來表示),來對\(y_i\)的輸出進行預測。
思考:個人認為在此softmax僅僅只是起到歸一化的作用,而非是為了輸出概率,雖然也可以將attention解釋為概率分布,但是需要注意的是,之所以在離散分布的輸出層使用softmax是由于我們采用了最大似然估計的損失函數作為優化目標,在這種情況下softmax的exp函數可以和log抵消,從而有效地進行梯度下降。然而在此我們并不是需要輸出的分布和log進行抵消,因為這個操作已經在輸出 \(y\) 的分布中實現了,所以在此處使用softmax層并不是必須的,同時在此使用softmax層反而可能會造成梯度消失的問題。因此我認為可以使用簡單的線性歸一化,而非softmax的指數歸一化。
利用反向傳播對fc網絡與編碼器、解碼器進行訓練,將RNN的預測誤差項反向傳播到解碼器,然后通過fc注意力網絡,再從解碼器反向傳播到編碼器。注意,由于注意力的權重是使用一個額外的神經網絡fc學習的,我們有一組額外的權重來允許這個學習發生,我們用\(W_a\)表示這個權重矩陣。
一個包含4個輸入時間步長和4個輸出時間步長的RNN,在訓練過程中會對以下權重矩陣進行微調。注意注意矩陣的維數4×4,將每個輸入連接到每個輸出:

這種機制使解碼器能夠決定輸入序列的哪些部分需要注意。通過讓解碼器具有注意力機制,我們將編碼器從必須將輸入序列中的所有信息編碼為單個向量中解放出來。信息可以傳播到\(h_1\), \(h_2\), \(h_3\), \(h_4\) 序列中,解碼器可以選擇性地檢索這些序列。
這種方法與基本編碼碼器最重要的區別在于,它不試圖將整個輸入語句編碼成一個固定長度的向量。相反,它將輸入的句子編碼成一個向量序列,并在解碼時自適應地選擇這些向量的子集。這使得神經翻譯模型不必將源句的所有信息(無論其長度)壓縮到一個固定長度的向量中。

浙公網安備 33010602011771號