一、 常用的循環神經網絡結構
前面的内容裡我們介紹了循環神經網絡的基本結構,這一小節裡我們介紹幾種更常用的循環神經網絡的結構。
1. 多層循環神經網絡
多層循環神經網絡是最容易想到的一種變種結構,它的結構也很簡單,就是在基本的循環神經網絡的基礎上增加了隐藏層的數量。

圖1 多層循環神經網絡結構
多層循環神經網絡按時間展開後,每一層的參數和基本的循環神經網絡結構一樣,參數共享,而不同層的參數則一般不會共享(可以類比CNN的網絡結構)。和基本結構的循環神經網絡相比,多層循環神經網絡的泛化能力更強,不過訓練的時間複雜度和空間複雜度也更高。在TensorFlow裡,我們可以借助MultiRNNCell這個類來實作深度循環神經網絡,下面我們用一個具體的例子來示範TensorFlow中多層循環神經網絡的實作。
示例:航班乘客人數預測
本示例所使用的資料來自DataMarket:https://datamarket.com/data/set/22u3/international-airline-passengers-monthly-totals-in-thousands-jan-49-dec-60#!ds=22u3&display=line。該資料集包含了從1949年到1960年共144個月的乘客總人數的資料,每個月的乘客人數是一條記錄,共144條記錄。其中部分資料顯示如下:
我們将所有資料可視化顯示:
圖2 資料可視化效果圖
從可視化的效果可以看到資料的變化呈現周期性,對于RNN來說,學習這種很明顯的序列關系并非難事。我們定義一個多層循環神經網絡(完整項目代碼可以在本書配套的GitHub項目中找到):
在第1行代碼中定義了一個方法用來傳回單層的cell,在第6行代碼中,我們使用MultiRNNCell類生成了一個3層的循環神經網絡。最終的預測結果如下圖左側所示:
圖3 多層循環神經網絡的預測結果
上圖中,藍色線條是原始資料,綠色線條是從原始資料中劃分出來的測試資料,紅色線條是在測試資料上的預測效果,左側是多層循環神經網絡的預測結果,右側是單層循環神經網絡的預測結果(除網絡層數不同外,其它參數均相同)。可以看到兩個預測結果都幾乎和真實資料重合,仔細比較會發現,多層循環神經網絡的拟合效果更好一些。
2. 雙向循環神經網絡
無論是簡單循環神經網絡還是深度循環神經網絡[1],網絡中的狀态都是随着時間向後傳播的,然而現實中的許多問題,并不都是這種單向的時序關系。例如在做詞性标注的時候,我們需要結合這個詞前後相鄰的幾個詞才能對該詞的詞性做出判斷,這種情況就需要雙向循環神經網絡來解決問題。
圖4 雙向循環神經網絡結構
圖檔來源于http://www.wildml.com
雙向循環神經網絡可以簡單的看成是兩個單向循環神經網絡的疊加,按時間展開後,一個是從左到右,一個是從右到左。雙向循環神經網絡的計算與單向的循環神經網絡類似,隻是每個時刻的輸出由上下兩個循環神經網絡的輸出共同決定。雙向循環神經網絡也可以在深度上進行疊加:
圖5 深度雙向循環神經網絡結構
在下一章的項目實戰部分,我們會使用TensorFlow來實作深度雙向循環神經網絡解決文本多分類問題,會結合代碼來介紹雙向循環神經網絡。
3. 遞歸神經網絡
遞歸神經網絡[2](recursive neuralnetwork,RNN)是循環神經網絡的又一個變種結構,看它們的名稱縮寫,很容易将兩者混淆(通常我們說的RNN均特指recurrent neural network,同時也不建議将recurrent neural network說成是遞歸神經網絡。一般預設遞歸神經網絡指的是recursive neural network,而循環神經網絡指的是recurrentneural network)。我們前面所介紹的循環神經網絡是時間上的遞歸神經網絡,而這裡所說的遞歸神經網絡是結構上的遞歸。遞歸神經網絡相較于循環神經網絡有它一定的優勢,當然這個優勢隻适用于某些特定場合。目前遞歸神經網絡在自然語言處理和計算機視覺領域已經有所應用,并獲得了一定的成功,但是由于其對輸入資料的要求相對循環神經網絡更為苛刻,是以并沒有被廣泛的應用。
圖6 遞歸神經網絡結構示意圖
二、 長期依賴問題及其優化
1. 長期依賴問題
什麼是長期依賴?我們知道循環神經網絡具有記憶能力,憑着它的記憶能力,能夠較好的解決一般的序列問題,這些序列問題的資料内部基本上都存在着一定的依賴性,例如我們在前面提到過的詞性标注的問題以及我們在示範項目裡面人工構造的二進制資料。在有些現實問題中,資料間的依賴都是局部的、較短時間間隔的依賴。還是以詞性标注為例,判斷一個詞是動詞還是名詞,或者是形容詞之類,我們往往隻需要看一下這個詞前後的兩個或多個詞就可以做出判斷,這種依賴關系在時間上的跨度很小。
圖7 時間跨度較小的依賴關系示意圖
如上圖所示,時刻網絡的輸出(上圖中到是隐藏層的輸出)除了與目前時刻的輸入相關之外,還受到和時刻網絡的狀态影響。像這種依賴關系在時間上的跨度較小的情況下,RNN基本可以較好地解決,但如果出現了像圖6-12所示的依賴情況,就會出現長期依賴問題:梯度消失和梯度爆炸。
圖8 時間跨度較大的依賴關系示意圖
什麼是梯度消失和梯度爆炸?圖9是一個較為形象的描述,在深層的神經網絡中,由于多個權重矩陣的相乘,會出現很多如圖所示的陡峭區域,當然也有可能會出現很多非常平坦的區域。在這些陡峭的地方,Loss函數的倒數非常大,導緻最終的梯度也很大,對參數進行更新後可能會導緻參數的取值超出有效的取值範圍,這種情況稱之為梯度爆炸。而在那些非常平坦的地方,Loss的變化很小,這個時候梯度的值也會很小(可能趨近于0),導緻參數的更新非常緩慢,甚至更新的方向都不明确,這種情況稱之為梯度消失。長期依賴問題的存在會導緻循環神經網絡沒有辦法學習到時間跨度較長的依賴關系。
圖9 導緻梯度爆炸的情況
圖檔引用自Razvan Pascanu的論文:《On thedifficulty of training recurrent neural networks》
正如上面所說,長期依賴問題普遍存在于層數較深的神經網絡之中,不僅存在于循環神經網絡中,在深層的前饋神經網絡中也存在這一問題,但由于循環神經網絡中循環結構的存在,導緻這一問題尤為突出,而在一般的前饋神經網絡中,這一問題其實并不嚴重。
值得注意的是,在第三章中介紹激活函數的時候我們其實已經提到過梯度消失的問題,這是由于Sigmoid型的函數在其函數圖像兩端的倒數趨近于0,使得在使用BP算法進行參數更新的時候會出現梯度趨近于0的情況。針對這種情況導緻的梯度消失的問題,一種有效的方法是使用ReLU激活函數。但是由于本節所介紹的梯度消失的問題并不是由激活函數引起的,是以使用ReLU激活函數也無法解決問題。下面我們來看一個簡單的例子。
圖10 參數W在循環神經網絡中随時間傳遞的示意圖
如上圖所示,我們定義一個簡化的循環神經網絡,該網絡中的所有激活函數均為線性的,除了在每個時間步上共享的參數W以外,其它的權重矩陣均設為1,偏置項均設為0。假設輸入的序列中除了的值為1以外,其它輸入的值均為0,則根據前一篇講解RNN的原理内容,可以知道:
公式1
最終可以得到,神經網絡的輸出是關于權重矩陣W的指數函數。當W的值大于1時,随着n的增加,神經網絡最終輸出的值也成指數級增長,而當W的值小于1時,随着n的值增加,神經網絡最終的輸出則會非常小。這兩種結果分别是導緻梯度爆炸和梯度消失的根本原因。
從上面的例子可以看到,循環神經網絡中梯度消失和梯度爆炸問題産生的根本原因,是由于參數共享導緻的。
2. 長期依賴問題的優化
對于梯度爆炸的問題,一般來說比較容易解決。我們可以用一個比較簡單的方法叫做“梯度截斷”,“梯度截斷”的思路是設定一個門檻值,當求得的梯度大于這個門檻值的時候,就使用某種方法來進行幹涉,進而減小梯度的變化。還有一種方法是給相關的參數添加正則化項,使得梯度處在一個較小的變化範圍内。
梯度消失是循環神經網絡面臨的最大問題,相較于梯度爆炸問題要更難解決。目前最有效的方法就是在模型上做一些改變,這就是我們下一節要介紹的門控循環神經網絡。本篇主要介紹了RNN的一些常用的循環網絡結構,以及長期問題和如何優化。下一篇我們将介紹基于門控制的循環神經網絡,也就是大家常見的LSTM以及GRU模型原理。
原文釋出時間為:2018-11-19
本文來自雲栖社群合作夥伴“
磐創AI”,了解相關資訊可以關注“
”。