RNN(循環神經網絡)

參考:

  1. 史上最詳細循環神經網絡講解(RNN/LSTM/GRU
  2. RNN
  3. 李宏毅,Structured Learning: Recurrent Neural Network, http://speech.ee.ntu.edu.tw/~tlkagk/courses_ML16.html 
    1. (機器學習2019B站視頻)(2016B站RNN)
  4.  

 

一、RNN(循環神經網絡)

參考鏈接

一文搞懂RNN(循環神經網絡)基礎篇

1、神經網絡基礎

神經網絡可以當做是能夠擬合任意函數的黑盒子,只要訓練數據足夠,給定特定的x,就能得到希望的y,結構圖如下:

將神經網絡模型訓練好之後,在輸入層給定一個x,通過網絡之後就能夠在輸出層得到特定的y,那麼既然有了這麼強大的模型,爲什麼還需要RNN(循環神經網絡)呢?

2、爲什麼需要RNN(循環神經網絡)

他們都只能單獨的取處理一個個的輸入,前一個輸入和後一個輸入是完全沒有關係的。但是,某些任務需要能夠更好的處理序列的信息,即前面的輸入和後面的輸入是有關係的。

比如,當我們在理解一句話意思時,孤立的理解這句話的每個詞是不夠的,我們需要處理這些詞連接起來的整個序列; 當我們處理視頻的時候,我們也不能只單獨的去分析每一幀,而要分析這些幀連接起來的整個序列。

以nlp的一個最簡單詞性標註任務來說,將我 吃 蘋果 三個單詞標註詞性爲 我/nn 吃/v 蘋果/nn。

那麼這個任務的輸入就是:

我 吃 蘋果 (已經分詞好的句子)

這個任務的輸出是:

我/nn 吃/v 蘋果/nn(詞性標註好的句子)

對於這個任務來說,我們當然可以直接用普通的神經網絡來做,給網絡的訓練數據格式了就是我-> 我/nn 這樣的多個單獨的單詞->詞性標註好的單詞。

但是很明顯,一個句子中,前一個單詞其實對於當前單詞的詞性預測是有很大影響的,比如預測蘋果的時候,由於前面的吃是一個動詞,那麼很顯然蘋果作爲名詞的概率就會遠大於動詞的概率,因爲動詞後面接名詞很常見,而動詞後面接動詞很少見。

所以爲了解決一些這樣類似的問題,能夠更好的處理序列的信息,RNN就誕生了。

3、RNN結構

首先看一個簡單的循環神經網絡如,它由輸入層、一個隱藏層和一個輸出層組成:

不知道初學的同學能夠理解這個圖嗎,反正我剛開始學習的時候是懵逼的,每個結點到底代表的是一個值的輸入,還是說一層的向量結點集合,如何隱藏層又可以連接到自己,等等這些疑惑~這個圖是一個比較抽象的圖。

我們現在這樣來理解,如果把上面有W的那個帶箭頭的圈去掉,它就變成了最普通的全連接神經網絡。x是一個向量,它表示輸入層的值(這裏面沒有畫出來表示神經元節點的圓圈);s是一個向量,它表示隱藏層的值(這裏隱藏層面畫了一個節點,你也可以想象這一層其實是多個節點,節點數與向量s的維度相同);

U是輸入層到隱藏層的權重矩陣,o也是一個向量,它表示輸出層的值;V是隱藏層到輸出層的權重矩陣

那麼,現在我們來看看W是什麼。循環神經網絡隱藏層的值s不僅僅取決於當前這次的輸入x,還取決於上一次隱藏層的值s。權重矩陣 W就是隱藏層上一次的值作爲這一次的輸入的權重。

我們給出這個抽象圖對應的具體圖:

我們從上圖就能夠很清楚的看到,上一時刻的隱藏層是如何影響當前時刻的隱藏層的。

如果我們把上面的圖展開,循環神經網絡也可以畫成下面這個樣子:

RNN時間線展開圖

現在看上去就比較清楚了,這個網絡在t時刻接收到輸入x_t 之後,隱藏層的值是s_t,輸出值是o_t。關鍵一點是, s_t的值不僅僅取決於x_t,還取決於x_{t-1} 。我們可以用下面的公式來表示循環神經網絡的計算方法:

用公式表示如下:

RNN公式

4、總結

好了,到這裏大概講解了RNN最基本的幾個知識點,能夠幫助大家直觀的感受RNN和了解爲什麼需要RNN,後續總結它的反向求導知識點。

最後給出RNN的總括圖:

注意:爲了簡單說明問題,偏置都沒有包含在公式裏面。

致謝:夏沖和實驗室的小夥伴們 參考:零基礎入門深度學習(5) - 循環神經網絡(多謝這麼好的資料)

 

二、LSTM

參考https://zhuanlan.zhihu.com/p/30844905

1. 普通RNN

先簡單介紹一下一般的RNN。

其主要形式如下圖所示(圖片均來自臺大李宏毅教授的PPT):

這裏:

 x爲當前狀態下數據的輸入, h表示接收到的上一個節點的輸入。

y爲當前節點狀態下的輸出,而h'爲傳遞到下一個節點的輸出。

 

通過上圖的公式可以看到,輸出 h' 與 x 和 h 的值都相關。

而 y 則常常使用 h' 投入到一個線性層(主要是進行維度映射)然後使用softmax進行分類得到需要的數據。

對這裏的y如何通過 h' 計算得到往往看具體模型的使用方式。

 

通過序列形式的輸入,我們能夠得到如下形式的RNN。


2. LSTM

2.1 什麼是LSTM

長短期記憶(Long short-term memory, LSTM)是一種特殊的RNN,主要是爲了解決長序列訓練過程中的梯度消失和梯度爆炸問題。簡單來說,就是相比普通的RNN,LSTM能夠在更長的序列中有更好的表現。

 

LSTM結構(圖右)和普通RNN的主要輸入輸出區別如下所示。

相比RNN只有一個傳遞狀態 h^{t} ,LSTM有兩個傳輸狀態,一個c^{t}(cell state),和一個h^{t} (hidden state)。(Tips:RNN中的 h^{t}  對於LSTM中的  c^{t}

其中對於傳遞下去的c^{t}  改變得很慢,通常輸出的 c^{t} 是上一個狀態傳過來的 c^{t-1} 加上一些數值。

而 h^{t} 則在不同節點下往往會有很大的區別。

 

2.2 深入LSTM結構

下面具體對LSTM的內部結構來進行剖析。

首先使用LSTM的當前輸入x^{t} 和上一個狀態傳遞下來的h^{t-1} 拼接訓練得到四個狀態。

 

 

其中,z^{f}z^{i}z^{o} 是由拼接向量乘以權重矩陣之後,再通過一個sigmoid激活函數轉換成0到1之間的數值,來作爲一種門控狀態。而 z則是將結果通過一個tanh激活函數將轉換成-1到1之間的值(這裏使用 tanh 是因爲這裏是將其做爲輸入數據,而不是門控信號)。

下面開始進一步介紹這四個狀態在LSTM內部的使用。(敲黑板)

⊙是Hadamard Product,也就是操作矩陣中對應的元素相乘,因此要求兩個相乘矩陣是同型的。  ⊕則代表進行矩陣加法。

 

LSTM內部主要有三個階段:

1. 忘記階段。這個階段主要是對上一個節點傳進來的輸入進行選擇性忘記。簡單來說就是會 “忘記不重要的,記住重要的”。

具體來說是通過計算得到的z^{f}(f表示forget)來作爲忘記門控,來控制上一個狀態的  c^{t-1}哪些需要留哪些需要忘。

2. 選擇記憶階段。這個階段將這個階段的輸入有選擇性地進行“記憶”。主要是會對輸入 ​​​​​​​x^{t} 進行選擇記憶。哪些重要則着重記錄下來,哪些不重要,則少記一些。當前的輸入內容由前面計算得到的z表示。而選擇的門控信號則是由 z^{i}(i代表information)來進行控制。

將上面兩步得到的結果相加,即可得到傳輸給下一個狀態的 c^{t}。也就是上圖中的第一個公式。

3. 輸出階段。這個階段將決定哪些將會被當成當前狀態的輸出。主要是通過 z^{o}來進行控制的。並且還對上一階段得到的 c^{0} 進行了放縮(通過一個tanh激活函數進行變化)。

與普通RNN類似,輸出y^{t}往往最終也是通過 h^{t}變化得到。


3. 總結

以上,就是LSTM的內部結構。通過門控狀態來控制傳輸狀態,記住需要長時間記憶的,忘記不重要的信息;而不像普通的RNN那樣只能夠“呆萌”地僅有一種記憶疊加方式。對很多需要“長期記憶”的任務來說,尤其好用。

但也因爲引入了很多內容,導致參數變多,也使得訓練難度加大了很多。因此很多時候我們往往會使用效果和LSTM相當但參數更少的GRU來構建大訓練量的模型。

三、GRU

參考:陳誠:人人都能看懂的GRU​zhuanlan.zhihu.com

1. 什麼是GRU

GRU(Gate Recurrent Unit)是循環神經網絡(Recurrent Neural Network, RNN)的一種。和LSTM(Long-Short Term Memory)一樣,也是爲了解決長期記憶和反向傳播中的梯度等問題而提出來的。

GRU和LSTM在很多情況下實際表現上相差無幾,那麼爲什麼我們要使用新人GRU(2014年提出)而不是相對經受了更多考驗的LSTM(1997提出)呢。

下圖1-1引用論文中的一段話來說明GRU的優勢所在。

圖1-1 R-NET: MACHINE READING COMPREHENSION WITH SELF-MATCHING NETWORKS(2017)

簡單譯文:我們在我們的實驗中選擇GRU是因爲它的實驗效果與LSTM相似,但是更易於計算。

簡單來說就是貧窮限制了我們的計算能力...

相比LSTM,使用GRU能夠達到相當的效果,並且相比之下更容易進行訓練,能夠很大程度上提高訓練效率,因此很多時候會更傾向於使用GRU。

OK,那麼爲什麼說GRU更容易進行訓練呢,下面開始介紹一下GRU的內部結構。


2. GRU淺析

 

2.1 GRU的輸入輸出結構

GRU的輸入輸出結構與普通的RNN是一樣的。

有一個當前的輸入 x^{t},和上一個節點傳遞下來的隱狀態(hidden state) h^{t-1},這個隱狀態包含了之前節點的相關信息。

結合 x^{t}h^{t-1},GRU會得到當前隱藏節點的輸出 y^{t} 和傳遞給下一個節點的隱狀態 h^{t}

圖2-1 GRU的輸入輸出結構

那麼,GRU到底有什麼特別之處呢?下面來對它的內部結構進行分析!


2.2 GRU的內部結構

首先,我們先通過上一個傳輸下來的狀態 h^{t-1} 和當前節點的輸入x^{t}來獲取兩個門控狀態。如下圖2-2所示,其中 r控制重置的門控(reset gate), z爲控制更新的門控(update gate)。

Tips: \sigma 爲sigmoid函數,通過這個函數可以將數據變換爲0-1範圍內的數值,從而來充當門控信號。

 

圖2-2 r,z門控

與LSTM分明的層次結構不同,下面將對GRU進行一氣呵成的介紹~~~ 請大家屏住呼吸,不要眨眼。

得到門控信號之後,首先使用重置門控來得到“重置”之後的數據​​​​​​​h^{t-1'}=h^{t-1}\bigodot r  ,再將 h^{t-1'} 與輸入 x^{t}進行拼接,再通過一個tanh激活函數來將數據放縮到-1~1的範圍內。即得到如下圖2-3所示的h^{'}

圖2-3 包含當前輸入數據的h'

這裏的 h^{'} 主要是包含了當前輸入的 x^{t} 數據。有針對性地對 h^{'} 添加到當前的隱藏狀態,相當於”記憶了當前時刻的狀態“。類似於LSTM的選擇記憶階段(參照我的上一篇文章)。

圖2-3 GRU的內部結構

圖2-3中的 \bigodot是Hadamard Product,也就是操作矩陣中對應的元素相乘,因此要求兩個相乘矩陣是同型的。\bigoplus則代表進行矩陣加法操作。

最後介紹GRU最關鍵的一個步驟,我們可以稱之爲”更新記憶“階段。

在這個階段,我們同時進行了遺忘了記憶兩個步驟。我們使用了先前得到的更新門控 z (update gate)。

更新表達式: h^{t}=z \bigodot h^{t-1}+(1-z)\bigodot h^{'}

首先再次強調一下,門控信號(這裏的 z )的範圍爲0~1。門控信號越接近1,代表”記憶“下來的數據越多;而越接近0則代表”遺忘“的越多。

 

GRU很聰明的一點就在於,我們使用了同一個門控 z就同時可以進行遺忘和選擇記憶(LSTM則要使用多個門控)

  • z \bigodot h^{t-1}:表示對原本隱藏狀態的選擇性“遺忘”。這裏的 z 可以想象成遺忘門(forget gate),忘記h^{t-1}  維度中一些不重要的信息
  • (1-z)\bigodot h^{'} : 表示對包含當前節點信息的 h^{'} 進行選擇性”記憶“。與上面類似,這裏的 (1-z) 同理會忘記 h^{'} 維度中的一些不重要的信息。或者,這裏我們更應當看做是對 h^{'} 維度中的某些信息進行選擇。
  • h^{t}=z \bigodot h^{t-1}+(1-z)\bigodot h^{'} :結合上述,這一步的操作就是忘記傳遞下來的 h^{t-1} 中的某些維度信息,並加入當前節點輸入的某些維度信息。
可以看到,這裏的遺忘 z 和選擇 (1-z) 是聯動的。也就是說,對於傳遞進來的維度信息,我們會進行選擇性遺忘,則遺忘了多少權重 (z ),我們就會使用包含當前輸入的h^{'}  中所對應的權重進行彌補 (1-z) 。以保持一種”恆定“狀態。

3. LSTM與GRU的關係

GRU是在2014年提出來的,而LSTM是1997年。他們的提出都是爲了解決相似的問題,那麼GRU難免會參考LSTM的內部結構。那麼他們之間的關係大概是怎麼樣的呢?這裏簡單介紹一下。

大家看到 r (reset gate)實際上與他的名字有點不符。我們僅僅使用它來獲得了 h^{'} 。

那麼這裏的 h^{'} 實際上可以看成對應於LSTM中的hidden state;上一個節點傳下來的 h^{t-1} 則對應於LSTM中的cell state。z對應的則是LSTM中的 z^{f} forget gate,那麼 (1-z) 我們似乎就可以看成是選擇門 z^{i} 了。大家可以結合我的兩篇文章來進行觀察,這是非常有趣的。

 

4. 總結

GRU輸入輸出的結構與普通的RNN相似,其中的內部思想與LSTM相似。

與LSTM相比,GRU內部少了一個”門控“,參數比LSTM少,但是卻也能夠達到與LSTM相當的功能。考慮到硬件的計算能力時間成本,因而很多時候我們也就會選擇更加”實用“的GRU啦。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章