循環神經網絡(recurrent neural network)或RNN(Rumelhart et al.,1986c)是一類用于處理序列數據的神經網絡。就像卷積網絡是專門用于處理網格化數據 X(如一個圖像)的神經網絡,循環神經網絡是專門用于處理序列的神經網絡。正如卷積網絡可以很容易地擴展到具有很大寬度和高度的圖像,以及處理大小可變的圖像,循環網絡可以擴展到更長的序列(比不基于序列的特化網絡長得多)。大多數循環網絡也能處理可變長度的序列。
從多層網絡出發到循環網絡,我們需要在模型的不同部分共享參數。參數共享使得模型能夠擴展到不同形式的樣本(這里指不同長度的樣本)并進行泛化。當信息的特定部分會在序列內多個位置出現時,這樣的共享尤為重要。考慮這兩句話:“I went to Nepal in 2009’’ 和“In 2009, I went to Nepal.” 如果我們讓一個機器學習模型讀取這兩個句子,并提取敘述者去Nepal的年份,無論 “2009年’’ 是作為句子的第六個單詞還是第二個單詞出現,我們都希望模型能認出 “2009年’’ 作為相關資料片段。假設我們要訓練一個處理固定長度句子的前饋網絡。傳統的全連接前饋網絡會給每個輸入特征分配一個單獨的參數,所以需要分別學習句子每個位置的所有語言規則。相比之下,循環神經網絡在幾個時間步內共享相同的權重,不需要分別學習句子每個位置的所有語言規則。
卷積的輸出是一個序列,其中輸出中的每一項是相鄰幾項輸入的函數。參數共享的概念體現在每個時間步中使用的相同卷積核。循環神經網絡以不同的方式共享參數。輸出的每一項是前一項的函數。輸出的每一項對先前的輸出應用相同的更新規則而產生。
1、展開計算圖
考慮動態系統的經典形式:
其中稱為系統的狀態。容易看出,這樣的表達式是循環的。對有限時間步
,
次應用這個定義可以展開這個圖。例如
,我們展開,可以得到:
以這種方式重復應用定義,展開等式,就能得到不涉循環的表達。現在我們可以使用傳統的有向無環計算圖呈現這樣的表達。
作為另一個例子,讓我們考慮由外部信號驅動的動態系統:
可以看到,當前狀態包含了整個過去序列的信息。為了表明狀態是網絡的隱藏單元,我們使用變量代表狀態重寫式:
展開計算圖得到:
當訓練循環網絡根據過去預測未來時,網絡通常要學會使用 作為過去序列(直到
)與任務相關方面的有損摘要。此摘要一般而言一定是有損的,因為其映射任意長度的序列
到一固定長度的向量
。根據不同的訓練準則,摘要可能選擇性地精確保留過去序列的某些方面。
2、循環神經網絡
循環神經網絡中一些重要的設計模式包括以下幾種:
- 每個時間步都有輸出,并且隱藏單元之間有循環連接的循環網絡。
- 每個時間步都產生一個輸出,只有當前時刻的輸出到下個時刻的隱藏單元之間有循環連接的循環網絡。
- 隱藏單元之間存在循環連接,但讀取整個序列后產生單個輸出的循環網絡。
任何圖靈可計算的函數都可以通過這樣一個有限維的循環網絡計算,在這個意義上圖 10.3 的循環神經網絡是萬能的。
現在我們研究圖10.3中RNN的前向傳播公式。這個圖沒有指定隱藏單元的激活函數。我們假設使用雙曲正切激活函數。此外,圖中沒有明確指定何種形式的輸出和損失函數。我們假定輸出是離散的,表示離散變量的常規方式是把輸出作為每個離散變量可能值的非標準化對數概率。然后,我們可以應用softmax函數后續處理后,獲得標準化后概率的輸出向量
。RNN 從特定的初始狀態
開始前向傳播。從
到
的每個時間步,我們應用以下更新方程:
其中的參數的偏置向量和
連同權重矩陣
、
和
,分別對應于輸入到隱藏、隱藏到輸出和隱藏到隱藏的連接。這個循環網絡將一個輸入序列映射到相同長度的輸出序列。
與序列配對的
的總損失就是所有時間步的損失之和。例如,
為
給定后
的負對數似然,則
其中需要讀取模型輸出向量
中對應于
的項。
關于各個參數計算這個損失函數的梯度是計算成本很高的操作。梯度計算涉及執行一次前向傳播(如在圖 10.3 展開圖中從左到右的傳播),接著是由右到左的反向傳播。運行時間是,并且不能通過并行化來降低,因為前向傳播圖是固有循序的。因此隱藏單元之間存在循環的網絡非常強大但訓練代價也很大。應用于展開圖且代價為
的反向傳播算法稱為通過時間反向傳播(back-propagation through time, BPTT)。
2.1、導師驅動過程和輸出循環網絡
僅在一個時間步的輸出和下一個時間步的隱藏單元間存在循環連接的網絡(圖10.4)確實沒有那么強大(因為缺乏隱藏到隱藏的循環連接)。因為輸出單元明確地訓練成匹配訓練集的目標,它們不太能捕獲關于過去輸入歷史的必要信息,除非用戶知道如何描述系統的全部狀態,并將它作為訓練目標的一部分。消除隱藏到隱藏循環的優點在于,任何基于比較時刻的預測和時刻
的訓練目標的損失函數中的所有時間步都解耦了。因此訓練可以并行化,即在各時刻
分別計算梯度。因為訓練集提供輸出的理想值,所以沒有必要先計算前一時刻的輸出。
由輸出反饋到模型而產生循環連接的模型可用導師驅動過程(teacher forcing)進行訓練。訓練模型時,導師驅動過程不再使用最大似然準則,而在時刻接收真實值
作為輸入。我們可以通過檢查兩個時間步的序列得知這一點。條件最大似然準則是:
在這個例子中,同時給定迄今為止的序列和來自訓練集的前一
值,我們可以看到在時刻
時,模型被訓練為最大化
的條件概率。因此最大似然在訓練時指定正確反饋,而不是將自己的輸出反饋到模型。如下圖所示:
2.2、計算循環神經網絡的梯度
這部分花書上的公式亂糟糟的,雖然作者說要給讀者一些“直觀”,但至少我看得很沒有耐心,因為連配圖都沒有……只有一堆公式……所以這部分我選擇放棄花書,通過查閱博客學習。以下來自this website:
首先RNN的一些計算公式如下(和花書表示稍有不同):
以為例,計算其對
的偏導:
這里,
表示外積。
可以看到只取決于當前時間步的值
,但求
的情況則不同:
注意這里是依賴于
的,而
又依賴于
和
。所以求導時我們不能把
當作常數,而要再次利用鏈式法則:
從這里我們就能看出為什么BPTT訓練的代價很大。
2.3、作為有向圖模型的循環網絡
將整個序列的聯合分布分解為一系列單步的概率預測是捕獲關于整個序列完整聯合分布的一種方法。當我們不把過去的
值反饋給下一步作為預測的條件時,那么有向圖模型不包含任何從過去
到當前
的邊。在這種情況下,輸出
與給定的
序列是條件獨立的。當我們反饋真實的
值(不是它們的預測值,而是真正觀測到或生成的值)給網絡時,那么有向圖模型包含所有從過去
到當前
的邊。下圖所示RNN完全圖的解釋基于排除并忽略模型中的隱藏單元
。
舉一個簡單的例子,讓我們考慮對標量隨機變量序列建模的RNN,也沒有額外的輸入
。在時間步
的輸入僅僅是時間步
的輸出。該RNN定義了關于
變量的有向圖模型。我們使用鏈式法則參數化這些觀察值的聯合分布:
因此,根據這樣一個模型,一組值的負對數似然為:
其中:
圖模型中的邊表示哪些變量直接依賴于其他變量。許多圖模型的目標是省略不存在強相互作用的邊以實現統計和計算的效率。例如,我們通常可以作Markov假設,即圖模型應該只包含從到
的邊,而不是包含整個過去歷史的邊。然而,在一些情況下,我們認為整個過去的輸入會對序列的下一個元素有一定影響。當我們認為
的分布可能取決于遙遠過去 (在某種程度) 的
的值,且無法通過
捕獲
的影響時,RNN將會很有用。
更有趣的是,將隱藏單元視為隨機變量,從而產生RNN的圖模型結構。在圖模型中包括隱藏單元預示 RNN 能對觀測的聯合分布提供非常有效的參數化。如下圖所示:
在圖模型中結合節點可以用作過去和未來之間的中間量,從而將它們解耦。遙遠過去的變量
可以通過其對
的影響來影響變量
。該圖的結構表明可以在時間步使用相同的條件概率分布有效地參數化模型,并且當觀察到全部變量時,可以高效地評估聯合分配給所有變量的概率。
在循環網絡中使用的參數共享的前提是相同參數可用于不同時間步的假設。也就是說,假設給定時刻的變量后,時刻
變量的條件概率分布是平穩的(stationary),這意味著之前的時間步與下個時間步之間的關系并不依賴于
。原則上,可以使用
作為每個時間步的額外輸入,并讓學習器在發現任何時間依賴性的同時,在不同時間步之間盡可能多地共享。相比在每個
使用不同的條件概率分布已經好很多了,但網絡將必須在面對新
時進行推斷。
2.4、基于上下文的RNN序列建模
之前,我們已經討論了將的向量
序列作為輸入的RNN。另一種選擇是只使用單個向量
作為輸入。當
是一個固定大小的向量時,我們可以簡單地將其看作產生
序列RNN的額外輸入。將額外輸入提供到RNN的一些常見方法是:
在每個時刻作為一個額外輸入
作為初始狀態
結合兩種方式
第一個也是最常用的方法如下圖所示:
輸入和每個隱藏單元向量
之間的相互作用是通過新引入的權重矩陣
參數化的,這是只包含
序列的模型所沒有的。同樣的乘積
在每個時間步作為隱藏單元的一個額外輸入。我們可以認為
的選擇(確定
值),是有效地用于每個隱藏單元的一個新偏置參數。權重與輸入保持獨立。
RNN還可以接收向量序列作為輸入,而不是僅接收單個向量
作為輸入。我們可以在時刻
的輸出到時刻
的隱藏單元添加連接,該模型就可以代表關于
序列的任意概率分布。
3、雙向RNN
在許多應用中,我們要輸出的的預測可能依賴于整個輸入序列。例如,在語音識別中,由于協同發音,當前聲音作為音素的正確解釋可能取決于未來幾個音素,甚至潛在的可能取決于未來的幾個詞,因為詞與附近的詞之間的存在語義依賴:如果當前的詞有兩種聲學上合理的解釋,我們可能要在更遠的未來(和過去)尋找信息區分它們。這在手寫識別和許多其他序列到序列學習的任務中也是如此。
雙向循環神經網絡(雙向RNN)為滿足這種需要被發明 (Schuster and Paliwal,1997)。他們在需要雙向信息的應用中非常成功 (Graves, 2012)。
顧名思義,雙向RNN結合時間上從序列起點開始移動的RNN和另一個時間上從序列末尾開始移動的RNN。下圖是一個典型的雙向RNN,其中代表通過時間向前移動的子RNN的狀態,
代表通過時間向后移動的子 RNN的狀態。這允許輸出單元
能夠計算同時依賴于過去和未來且對時刻
的輸入值最敏感的表示,而不必指定
周圍固定大小的窗口。
4、基于編碼-解碼的序列到序列架構
上面討論的RNN都是將一個序列映射到另一個等長序列。如何訓練RNN,使其將輸入序列映射到不一定等長的輸出序列呢?這在許多場景中都有應用,如語音識別、機器翻譯,其中訓練集的輸入和輸出序列的長度通常不相同(雖然它們的長度可能相關)。
用于映射可變長度序列到另一可變長度序列最簡單的RNN架構最初由Choet al. (2014a) 提出,之后不久由Sutskever et al. (2014) 獨立開發,并且第一個使用這種方法獲得翻譯的最好結果。前一系統是對另一個機器翻譯系統產生的建議進行評分,而后者使用獨立的循環網絡生成翻譯。這些作者分別將該架構稱為編碼-解碼或序列到序列架構,如下圖所示:
這個想法非常簡單:
(1)編碼器(encoder)或讀取器(reader)或輸入(input)RNN處理輸入序列。編碼器輸出上下文(通常是最終隱藏狀態的簡單函數)。
(2)解碼器(decoder)或寫入器(writer) 或輸出(output)RNN則以固定長度的向量(如圖10.9)為條件產生輸出序列。
這種架構對比本章前幾節提出的架構的創新之處在于長度和
可以彼此不同,而之前的架構約束
。在序列到序列的架構中,兩個RNN共同訓練以最大化
(關于訓練集中所有
和
對的平均)。編碼器RNN的最后一個狀態
通常被當作輸入的表示
并作為解碼器RNN 的輸入。
5、深度循環網絡
大多數RNN中的計算可以分解成三塊參數及其相關的變換:
從輸入到隱藏狀態
從前一隱藏狀態到下一隱藏狀態
從隱藏狀態到輸出
根據圖10.3中的RNN架構,這三個塊都與單個權重矩陣相關聯。換句話說,當網絡被展開時,每個塊對應一個淺的變換。能通過深度MLP內單個層來表示的變換稱為淺變換。通常,這是由學成的仿射變換和一個固定非線性表示組成的變換。
Graves et al. (2013) 第一個展示了將 RNN 的狀態分為多層的顯著好處,如下圖。我們可以認為,在圖10.13 (a)所示層次結構中較低的層起到了將原始輸入轉化為對更高層的隱藏狀態更合適表示的作用ascanu et al. (2014a) 更進一步提出在上述三個塊中各使用一個單獨的 MLP(可能是深度的),如圖10.13 (b)所示。考慮表示容量,我們建議在這三個步中都分配足夠的容量,但增加深度可能會因為優化困難而損害學習效果。
6、遞歸神經網絡
遞歸神經網絡代表循環網絡的另一個擴展,它被構造為深的樹狀結構而不是RNN的鏈狀結構,因此是不同類型的計算圖。遞歸網絡的典型計算圖如圖所示。
遞歸網絡已成功地應用于輸入是數據結構的神經網絡 (Frasconiet al., 1997, 1998),如自然語言處理 (Socher et al., 2011a,c, 2013a) 和計算機視覺(Socher et al., 2011b)。
遞歸網絡的一個明顯優勢是,對于具有相同長度的序列,深度(通過非線性操作的組合數量來衡量)可以急劇地從
減小為
,這可能有助于解決長期依賴。
7、長期依賴的挑戰
學習循環網絡長期依賴的根本問題是,經過許多階段傳播后的梯度傾向于消失(大部分情況)或爆炸(很少,但對優化過程影響很大),即使我們假設循環網絡是參數穩定的(可存儲記憶,且梯度不爆炸),但長期依賴的困難來自比短期相互作用指數小的權重(涉及許多Jacobian相乘)。
循環網絡涉及相同函數的多次組合,每個時間步一次。這些組合可以導致極端非線性行為,如圖所示。
這個問題是針對循環網絡的。在標量情況下,想象多次乘一個權重。該乘積
消失還是爆炸取決于
的幅值。然而,如果每個時刻使用不同權重
非循環網絡,情況就不同了。如果初始狀態給定為1,那么時刻
的狀態可以由
給出。假設
的值是隨機生成的,各自獨立,且有0均值
方差。乘的方差就為
。為了獲得某些期望的方差
,我們可以選擇單個方差為
權重。因此,非常深的前饋網絡通過精心設計的比例可以避免梯度消失和爆炸問題,如 Sussillo (2014) 所主張的。
8、克服長期依賴的方法
花書上接下來的內容主要介紹克服長期依賴問題的方法。這部分內容因為書上也沒有細講,所以這里只是記錄下各模型的大致思想。
8.1、回聲狀態網絡
從到
的循環權重映射以及從
到
的輸入權重映射是循環網絡中最難學習的參數。避免這種困難的方法是設定循環隱藏單元,使其能很好地捕捉過去輸入歷史,并且只學習輸出權重。 回聲狀態網絡(echo state network)獨立地提出了這種想法。
ESN被稱為儲層計算(reservoir computing)(Luko?evi?ius and Jaeger, 2009),因為隱藏單元形成了可能捕獲輸入歷史不同方面的臨時特征池。
儲層計算循環網絡類似于核機器,這是思考它們的一種方式:它們將任意長度的序列(到時刻的輸入歷史)映射為一個長度固定的向量(循環狀態
),之后可以施加一個線性預測算子(通常是一個線性回歸)以解決感興趣的問題。
8.2、滲漏單元和其他多時間尺度的策略
處理長期依賴的一種方法是設計工作在多個時間尺度的模型,使模型的某些部分在細粒度時間尺度上操作并能處理小細節,而其他部分在粗時間尺度上操作并能把遙遠過去的信息更有效地傳遞過來。
增加從遙遠過去的變量到目前變量的直接連接是得到粗時間尺度的一種方法。梯度可能關于時間步數呈指數消失或爆炸。(Linet al., 1996) 引入了延時的循環連接以減輕這個問題。現在導數指數減小的速度與
相關而不是
。既然同時存在延遲和單步連接,梯度仍可能成
指數爆炸。這允許學習算法捕獲更長的依賴性,但不是所有的長期依賴都能在這種方式下良好地表示。
獲得導數乘積接近 1 的另一方式是設置線性自連接單元,并且這些連接的權重接近 1。
我們對某些值應用更新
累積一個滑動平均值
,其中
是一個從
到
線性自連接的例子。當
接近 1 時,滑動平均值能記住過去很長一段時間的信息,而當
接近 0,關于過去的信息被迅速丟棄。線性自連接的隱藏單元可以模擬滑動平均的行為。這種隱藏單元稱為滲漏單元(leaky unit)。
處理長期依賴另一種方法是在多個時間尺度組織RNN狀態的想法 (El Hihi and Bengio, 1996),信息在較慢的時間尺度上更容易長距離流動。這個想法與之前討論的時間維度上的跳躍連接不同,因為它涉及主動刪除長度為一的連接并用更長的連接替換它們。以這種方式修改的單元被迫在長時間尺度上運作。而通過時間跳躍連接是添加邊。收到這種新連接的單元,可以學習在長時間尺度上運作,但也可以選擇專注于自己其他的短期連接。
8.3、長短期記憶和其他門控RNN
實際應用中最有效的序列模型稱為門控RNN(gated RNN)。包括基于長短期記憶(long short-term memory)和基于門控循環單元(gated recurrent unit)的網絡。
引入自循環的巧妙構思,以產生梯度長時間持續流動的路徑是初始長短期記憶(long short-term memory, LSTM)模型的核心貢獻 (Hochreiter and Schmidhuber,1997)。其中一個關鍵擴展是使自循環的權重視上下文而定,而不是固定的 (Gerset al., 2000)。門控此自循環(由另一個隱藏單元控制)的權重,累積的時間尺度可以動態地改變。在這種情況下,即使是具有固定參數的LSTM,累積的時間尺度也可以因輸入序列而改變,因為時間常數是模型本身的輸出。