1. 程式人生 > >雙向長短記憶網路(BiLSTM)

雙向長短記憶網路(BiLSTM)

關於理解LSTM的一篇英文部落格非常經典,可以去這裡閱讀,本文也參考了該博文。

迴圈神經網路(RNN)

BiLSTM是RNN的一種延伸,因此,要理解BiLSRM就必須首先弄明白什麼是RNN。

普通神經網路的侷限

假設我們對於普通的神經網路模型已經比較熟悉,那麼不難理解,在神經網路的某一固定層中,該網路的各個輸入之間是沒有運算連線的。造成的一個直觀的影響就是,該模型無法表示輸入的“上下文”之間的關係。我們在讀一篇文章時,有時需要返回頭再看前文的內容,這樣便於我們去理解文章真正想表達的含義。既然傳統的神經網路無法解決這個問題,那麼,一種新的、可以考慮上下文內容的模型——迴圈神經網路(Recurrent neural network)就誕生了。

RNN的執行機制

RNN的執行原理其實非常的簡單,如下圖:
RNN計算流程圖
上圖中,粉色的部分為一個神經元,對輸入進行運算。從圖中可以看出,與普通神經網路不同的一點在於,神經元接受兩個值:一個是當前時刻的輸入 x t x_t ,另一個是前一個神經元的輸出 a

t 1 a_{t-1} 。其蘊含的意義也是不難理解的:通過將前一時刻的運算結果新增到當前的運算中,從而實現了“考慮上文資訊”的功能。

下面給出線上性計算過程中各個變數的維度情況。

假定我們的輸入是一段文字,首先要做的是將文字轉為詞向量,因為神經網路只能進行數值運算。假定轉換後的詞向量維度為50,即每個詞可以用一個長度為50的列向量進行表示。如果沒有 a

a 項,即在普通的神經網路中,要得到維度為10的輸出,那麼所作的線性運算部分為 W x x W_x*x (為簡單起見,省去了偏置項 b b ),這裡, W x W_x 是10×50的矩陣, x x 是50×1的向量。

添加了 a a 項之後,與之對應的有一個權重矩陣 W a W_a ,在具體的計算時,實際上是將 x t x_t a t 1 a_{t-1} 做了簡單的“堆疊”: [ a t 1 ; x t ] [a_{t-1};x_t] 是一個60×1的向量,那麼 [ W a ; W x ] [W_a;W_x] 就是一個10×60的矩陣,這樣在做線性運算之後,得到的輸出( a t a_t o t o_t )仍是10×1的向量。

BiRNN

由上一部分可以知道,RNN可以考慮上文的資訊,那麼如何將下文的資訊也新增進去呢?這就是BiRNN要做的事情。

具體運算如下圖:
BiRNN計算流程圖
與RNN計算流程類似,BiRNN在其基礎上添加了反向的運算。可以理解為把輸入的序列反轉,重新按照RNN的方式計算一遍輸出,最終的結果為正向RNN的結果與反向RNN的結果的簡單堆疊。這樣,模型就可以實現考慮上下文資訊了,所以這種RNN叫做Bidirectional recurrent neural network。

注意,這裡只是對RNN類神經網路的前向傳播過程進行了說明,該類神經網路也可以通過梯度下降法進行後向傳播,從而實現訓練模型的功能。

RNN存在的問題

由上文可知,理論上BiRNN可以考慮到上下文的資訊,因為每一個傳遞給後面神經元的 a a 的值都包含了前面所有時刻的輸入資訊。但是直覺告訴我們,如果僅僅依靠這一條線來記錄所有輸入的資訊,工作效果很可能並不理想,實際也的確如此:人們已經證實,RNN很難完美地處理具有長期依賴的資訊。一個比較容易理解的英文例子是:當句子很長時,RNN無法記住主語的單複數形式從而在後面選擇合適的謂詞。

既然僅僅依靠一條線連線後面的神經元不足以解決問題,那麼就再加一條線好了,這就是LSTM。研究表明,與RNN相比,LSTM可以很好的表達輸入中的長期依賴的資訊。

長短記憶網路(LSTM)

LSTM中一個重要的概念就是“門”,它控制資訊通過的量,實質上就是一個 σ \sigma 函式。

門(gate)函式

對於接觸深度學習的人而言,一定不會對 σ \sigma 函式感到陌生,它的表示式為 σ ( t ) = 1 1 + e t \sigma\left(t\right)=\frac{1}{1+e^{-t}} 。該函式最重要的一個特徵是,它可以把實數軸上的值對映到 ( 0 , 1 ) \left( 0,1\right) 上,而且,絕大部分的值都是非常接近0或者1的。

這樣的特性就彷彿是一個門結構,根據函式的取值可以決定讓多少資訊通過這個門。

在LSTM中,一共有3種門結構,分別是遺忘門(forget gate)、輸入門(input gate)與輸出門(output gate)。下面結合一個神經元內部的結構圖分析其運算情況。

LSTM的神經元及執行機制

一個LSTM的cell

上圖是一個LSTM“神經元”(即英文‘cell’)的內部情況。

首先,忽略其內部細節,單看輸入與輸出可以發現,每個神經元都有三個輸入與三個輸出。根據上文,不難想到, X t X_t 是該時刻新加入的資訊, a t 1 a_{t-1} C t 1 C_{t-1} 是上文資訊的表示。

其次,在該神經元內部:

  • 黃色的部分表示“逐元素運算”,一共有兩種,分別是乘運算和加運算。也就是說,兩個相同維度的向量經過黃色運算框之後對應元素進行相乘或相加。
  • 棕色部分表示“啟用運算”,也有兩種,分別是 σ \sigma 函式和 t a n h tanh 函式。
  • 兩條線按箭頭方向融合,則是上文說的簡單堆疊;一條線分成兩條,則是複製為相同的兩份。

那麼它的執行機制是什麼樣的呢?

假設沒有三個門函式,不難發現, a t 1 a_{t-1} X t X_t 堆疊之後乘以權重 W W 然後經過 t a n h tanh 啟用函式後輸出,這與RNN的運算是一模一樣的。

現在, a t 1 a_{t-1} X t X_t 堆疊之後的值被複製成了四份:
第一份乘以遺忘門的權重 W f W_f 然後用 σ \sigma 啟用,得到的值可以稱之為“遺忘權重”。
第二份乘以輸入門的權重 W i W_i 然後用 σ \sigma 啟用,得到的值可以稱之為“輸入權重”。
第三份則是進行了RNN中的運算。
第四份乘以輸出門的權重 W o W_o 然後用 σ \sigma 啟用,得到的值可以稱之為“輸出權重”。

應該時刻注意的是,上述“某某權重”其實是一個與 a t 1 a_{t-1} X t X_t 堆疊後的向量同維度的向量,向量中所有的值都在 ( 0 , 1 ) (0,1) 之間,而且大部分都是非常接近0或者1的。

接下來看神經元內最上方的 C t 1 C_{t-1} 。與 a t 1 a_{t-1} 類似, C t 1 C_{t-1} 也攜帶著上文的資訊。進入神經元后, C t 1 C_{t-1} 首先會與遺忘權重逐元素相乘,可以想見,由於遺忘權重中值得特點,因此與該權重相乘之後 C t 1 C_{t-1} 中絕大部分的值會變的非常接近0或者非常接近該位置上原來的值。這非常像一扇門,它會決定讓哪些 C t 1 C_{t-1} 的元素通過以及通過的比例有多大。反映到實際中,就是對 C t 1 C_{t-1} 中攜帶的資訊進行選擇性的遺忘(乘以非常接近0的數)和通過(乘以非常接近1的數),亦即乘以一個權重。

理解了遺忘門的作用之後,其他兩個門也就比較好理解了。輸入門則是對輸入資訊進行限制,而輸入資訊就是RNN中的前向運算的結果。經過輸入門處理後的資訊就可以新增到經過遺忘門處理的上文資訊中去,這就是神經元內唯一一個逐元素相加的工作。

按照一般的理解,上文的資訊根據當前的輸入遺忘了舊的資訊,並添加了新的資訊,那麼整體的更新操作就已經完成,即 C t C_{t} 已經生成。但是 C t C_{t} 實際扮演的角色是攜帶上文的資訊,因此,如果當前神經元要輸出內容,那麼還要有一個輸出門進行限制。 C t C_t 再乘以一個 t a n h tanh