十 | 門控迴圈神經網路LSTM與GRU(附python演練)

磐創AI發表於2018-11-23

十 | 門控迴圈神經網路LSTM與GRU(附python演練)

編輯 | 安可

出品 | 磐創AI技術團隊

目錄:

  • 門控迴圈神經網路簡介

  • 長短期記憶網路(LSTM)

  • 門控制迴圈單元(GRU)

  • TensorFlow實現LSTM和GRU

  • 參考文獻

一、 門控迴圈神經網路

門控迴圈神經網路在簡單迴圈神經網路的基礎上對網路的結構做了調整,加入了門控機制,用來控制神經網路中資訊的傳遞。門控機制可以用來控制記憶單元中的資訊有多少需要保留,有多少需要丟棄,新的狀態資訊又有多少需要儲存到記憶單元中等。這使得門控迴圈神經網路可以學習跨度相對較長的依賴關係,而不會出現梯度消失和梯度爆炸的問題。如果從數學的角度來理解,一般結構的迴圈神經網路中,網路的狀態十 | 門控迴圈神經網路LSTM與GRU(附python演練)十 | 門控迴圈神經網路LSTM與GRU(附python演練)之間是非線性的關係,並且引數W在每個時間步共享,這是導致梯度爆炸和梯度消失的根本原因。門控迴圈神經網路解決問題的方法就是在狀態十 | 門控迴圈神經網路LSTM與GRU(附python演練)十 | 門控迴圈神經網路LSTM與GRU(附python演練)之間新增一個線性的依賴關係,從而避免梯度消失或梯度爆炸的問題。

二、 長短期記憶網路(LSTM)

長短期記憶網路(Long Short-term Memory,簡稱LSTM)的結構如圖1所示,LSTM[1]的網路結構看上去很複雜,但實際上如果將每一部分拆開來看,其實也很簡單。在一般的迴圈神經網路中,記憶單元沒有衡量資訊的價值量的能力,因此,記憶單元對於每個時刻的狀態資訊等同視之,這就導致了記憶單元中往往儲存了一些無用的資訊,而真正有用的資訊卻被這些無用的資訊擠了出去。LSTM正是從這一點出發做了相應改進,和一般結構的迴圈神經網路只有一種網路狀態不同,LSTM中將網路的狀態分為內部狀態和外部狀態兩種。LSTM的外部狀態類似於一般結構的迴圈神經網路中的狀態,即該狀態既是當前時刻隱藏層的輸出,也是下一時刻隱藏層的輸入。這裡的內部狀態則是LSTM特有的。

在LSTM中有三個稱之為“門”的控制單元,分別是輸入門(input gate)、輸出門(output gate)和遺忘門(forget gate),其中輸入門和遺忘門是LSTM能夠記憶長期依賴的關鍵。輸入門決定了當前時刻網路的狀態有多少資訊需要儲存到內部狀態中,而遺忘門則決定了過去的狀態資訊有多少需要丟棄。最後,由輸出門決定當前時刻的內部狀態有多少資訊需要輸出給外部狀態。

十 | 門控迴圈神經網路LSTM與GRU(附python演練)

圖1 單個時間步的LSTM網路結構示意圖

從上圖我們可以看到,一個LSTM單元在每個時間步都會接收三個輸入,當前時刻的輸入,來自上一時刻的內部狀態十 | 門控迴圈神經網路LSTM與GRU(附python演練)以及上一時刻的外部狀態十 | 門控迴圈神經網路LSTM與GRU(附python演練)。其中,十 | 門控迴圈神經網路LSTM與GRU(附python演練)十 | 門控迴圈神經網路LSTM與GRU(附python演練)同時作為三個“門”的輸入。十 | 門控迴圈神經網路LSTM與GRU(附python演練)為Logistic函式。

接下來我們將分別介紹LSTM中的幾個“門”結構。首先看一下輸入門,如圖2所示:

十 | 門控迴圈神經網路LSTM與GRU(附python演練)

圖2 LSTM的輸入門結構示意圖

LSTM中也有類似於RNN(這裡特指前面介紹過的簡單結構的迴圈神經網路)的前向計算過程,如圖2,如果去掉輸入門部分,剩下的部分其實就是RNN中輸入層到隱藏層的結構,“tanh”可以看作是隱藏層的啟用函式,從“tanh”節點輸出的值為:

十 | 門控迴圈神經網路LSTM與GRU(附python演練)

式1

上式中,引數的下標“c”代表這是“tanh”節點的引數,同理,輸入門引數的下標為“i”,輸出門引數的下標為“o”,遺忘門引數的下標為“f”。上式與簡單結構迴圈神經網路中隱藏層的計算公式一樣。在LSTM中,我們將“tanh”節點的輸出稱為候選狀態十 | 門控迴圈神經網路LSTM與GRU(附python演練)

輸入門是如何實現其控制功能的?輸入門的計算公式如下:

十 | 門控迴圈神經網路LSTM與GRU(附python演練)

式2

由於十 | 門控迴圈神經網路LSTM與GRU(附python演練)為Logistic函式,其值域為(0,1),因此輸入門的值就屬於(0,1)。LSTM將“tanh”節點的輸出(即候選狀態十 | 門控迴圈神經網路LSTM與GRU(附python演練))乘上輸入門的值後再用來更新內部狀態。如果的值趨向於0的話,那麼候選狀態十 | 門控迴圈神經網路LSTM與GRU(附python演練)就只有極少量的資訊會儲存到內部狀態中,相反的,如果的值十 | 門控迴圈神經網路LSTM與GRU(附python演練)趨近於1,那麼候選狀態十 | 門控迴圈神經網路LSTM與GRU(附python演練)就會有更多的資訊被儲存。輸入門就是通過這種方法來決定儲存多少中的資訊,十 | 門控迴圈神經網路LSTM與GRU(附python演練)值的大小就代表了新資訊的重要性,不重要的資訊就不會被儲存到內部狀態中.

再來看遺忘門,如圖3所示:

十 | 門控迴圈神經網路LSTM與GRU(附python演練)

圖3 LSTM的遺忘門結構示意圖

遺忘門的計算公式如下:

十 | 門控迴圈神經網路LSTM與GRU(附python演練)

式3

和輸入門是同樣的方法,通過的值來控制上一時刻的內部狀態有多少資訊需要“遺忘”。當十 | 門控迴圈神經網路LSTM與GRU(附python演練)的值越趨近於0,被遺忘的資訊越多。同樣的原理,我們來看“輸出門”,如圖4所示。輸出門的計算公式如下:

十 | 門控迴圈神經網路LSTM與GRU(附python演練)

式4

十 | 門控迴圈神經網路LSTM與GRU(附python演練)的值月接近於1,則當前時刻的內部狀態十 | 門控迴圈神經網路LSTM與GRU(附python演練)就會有更多的資訊輸出給當前時刻的外部狀態十 | 門控迴圈神經網路LSTM與GRU(附python演練)

十 | 門控迴圈神經網路LSTM與GRU(附python演練)

圖4 LSTM的輸出門結構示意圖

以上就是LSTM的整個網路結構以及各個“門”的計算公式。通過選擇性的記憶和遺忘狀態資訊,使的LSTM要比一般的迴圈神經網路能夠學習更長時間間隔的依賴關係。根據不同的需求,LSTM還有著很多不同的變體版本,這些版本的網路結構大同小異,但都在其特定的應用中表現出色。

三、 門控制迴圈單元(GRU)

門控制迴圈單元(gated recurrent unit,GRU)網路是另一種基於門控制的迴圈神經網路,GRU[2]的網路結構相比LSTM要簡單一些。GRU將LSTM中的輸入門和遺忘門合併成了一個門,稱為更新門(update gate)。在GRU網路中,沒有LSTM網路中的內部狀態和外部狀態的劃分,而是通過直接在當前網路的狀態十 | 門控迴圈神經網路LSTM與GRU(附python演練)和上一時刻網路的狀態十 | 門控迴圈神經網路LSTM與GRU(附python演練)之間新增一個線性的依賴關係,來解決梯度消失和梯度爆炸的問題。

十 | 門控迴圈神經網路LSTM與GRU(附python演練)

圖5 單個時間步的GRU網路結構示意圖

在GRU網路中,更新門用來控制當前時刻輸出的狀態十 | 門控迴圈神經網路LSTM與GRU(附python演練)中要保留多少歷史狀態十 | 門控迴圈神經網路LSTM與GRU(附python演練),以及保留多少當前時刻的候選狀態十 | 門控迴圈神經網路LSTM與GRU(附python演練)。更新門的計算公式如下:

十 | 門控迴圈神經網路LSTM與GRU(附python演練)

式5

如圖5所示,更新門的輸出分別和歷史狀態十 | 門控迴圈神經網路LSTM與GRU(附python演練)以及候選狀態十 | 門控迴圈神經網路LSTM與GRU(附python演練)進行了乘操作,其中和十 | 門控迴圈神經網路LSTM與GRU(附python演練)相乘的是十 | 門控迴圈神經網路LSTM與GRU(附python演練)。最終當前時刻網路的輸出為:

十 | 門控迴圈神經網路LSTM與GRU(附python演練)

式6

重置門的作用是決定當前時刻的候選狀態是否需要依賴上一時刻的網路狀態以及需要依賴多少。從圖5可以看到,上一時刻的網路狀態十 | 門控迴圈神經網路LSTM與GRU(附python演練)先和重置門的輸出相乘之後,再作為引數用於計算當前時刻的候選狀態。重置門的計算公式如下:

十 | 門控迴圈神經網路LSTM與GRU(附python演練)

式7

十 | 門控迴圈神經網路LSTM與GRU(附python演練)的值決定了候選狀態十 | 門控迴圈神經網路LSTM與GRU(附python演練)對上一時刻的狀態十 | 門控迴圈神經網路LSTM與GRU(附python演練)的依賴程度,候選狀態十 | 門控迴圈神經網路LSTM與GRU(附python演練)的計算公式如下:

十 | 門控迴圈神經網路LSTM與GRU(附python演練)

式8

其實當十 | 門控迴圈神經網路LSTM與GRU(附python演練)的值為0且十 | 門控迴圈神經網路LSTM與GRU(附python演練)的值為1時,GRU網路中的更新門和重置門就不再發揮作用了,而此時的GRU網路就退化成了簡單迴圈神經網路,因為此時有:

十 | 門控迴圈神經網路LSTM與GRU(附python演練)

式9

四、 TensorFlow實現LSTM和GRU

前面介紹了LSTM和GRU的理論知識,這一小節裡我們使用TensorFlow來實現一個LSTM模型。為了方便,這裡我們使用前面介紹過的mnist資料集。可能讀者對於在迴圈神經網路中使用影像資料會有一點疑惑,因為通常情況下影像資料一般都是使用卷積神經網路來訓練。事實的確是這樣,由於卷積神經網路和迴圈神經網路的結構不同,也就使得它們各自有不同的適用場景,但這不代表卷積神經網路只能用來處理時序資料,同樣也不能認為迴圈神經網路不能用來處理影像資料,只要在輸入資料的格式上稍作調整即可,就像上一章中我們使用卷積神經網路網路來處理文字資料一樣。

mnist資料集我們在第三章中就已經使用過,這裡就不再多做介紹了,直接上程式碼:

十 | 門控迴圈神經網路LSTM與GRU(附python演練)

我們首先匯入需要的包,然後定義了神經網路中的一些相關引數。其中第6行程式碼定義了LSTM中的時間步的長度,由於我們mnist資料集的影像大小為28X28,所以我們將一行畫素作為一個輸入,這樣我們就需要有28個時間步。第7行程式碼定義了每個時間步輸入資料的長度(每個時間步的輸入是一個向量),即一行畫素的長度。

十 | 門控迴圈神經網路LSTM與GRU(附python演練)

第10行程式碼用來載入mnist資料集,並通過引數“validation_size”指定了驗證集的大小。第16行程式碼用來將mnist資料集的格式轉換成“dynamic_rnn”函式接受的資料格式“[batch_size, max_time,data_length]”。

十 | 門控迴圈神經網路LSTM與GRU(附python演練)

在上面的程式碼中,我們定義了一個兩層的LSTM網路結構,並使用了交叉熵損失函式和“Adam”優化器。LSTM多層網路結構的定義和我們前面使用過的多層神經網路的定義方法一樣,只是將“BasicRNNCell”類換成了“BasicLSTMCel”類。

十 | 門控迴圈神經網路LSTM與GRU(附python演練)

在上面的整個程式碼中,我們使用的引數都是比較隨意的進行選擇的,沒有進行任何的優化,最終在測試集上的結果能達到96%左右,當然這肯定不是LSTM網路處理mnist資料集所能達到的最好的效果,有興趣的讀者可以試著去調整網路的結構和引數,看是否能達到更高的準確率。

TensorFlow中實現LSTM和GRU的切換非常簡單,在上面的程式碼中,將第22和26行程式碼註釋掉,然後取消第24和27行程式碼的註釋,實現的就是GRU。

本文介紹了門控迴圈神經網路LSTM以及GRU的原理及其tensorflow程式碼實現,希望能讓大家對常用到的LSTM及GRU能夠有更好的理解。下一篇,我們將介紹RNN迴圈神經網路的應用部分,分析RNN迴圈神經網路是怎樣用在文字分類,序列標註以及機器翻譯上的,以及其存在的不足與改進方法。

五、 參考文獻

[1]Sepp Hochreiter: Long Short-term Memory .1997

[2]Kazuki Irie, Zoltán Tüske, TamerAlkhouli, Ralf Schlüter, Hermann Ney:

LSTM, GRU, Highway and a Bit of Attention:AnEmpirical Overview for Language Modeling in Speech Recognition.INTERSPEECH2016: 3519-3523

原文連結:https://mp.weixin.qq.com/s/sYkiHgqyRHRn2HAdBKDtPw

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31555081/viewspace-2221434/,如需轉載,請註明出處,否則將追究法律責任。

相關文章