淺談循環神經網絡(RNN)

1.RNN怎麼來的?

循環神經網絡的應用場景比較多,比如暫時能寫論文,寫程序,寫詩,但是,(總是會有但是的),但是他們現在還不能正常使用,學習出來的東西沒有邏輯,所以要想真正讓它更有用,路還很遠。

這是一般的神經網絡應該有的結構: 
這裏寫圖片描述

既然我們已經有了人工神經網絡和卷積神經網絡,爲什麼還要循環神經網絡? 
原因很簡單,無論是卷積神經網絡,還是人工神經網絡,他們的前提假設都是:元素之間是相互獨立的,輸入與輸出也是獨立的,比如貓和狗。 
但現實世界中,很多元素都是相互連接的,比如股票隨時間的變化,一個人說了:我喜歡旅遊,其中最喜歡的地方是雲南,以後有機會一定要去__________.這裏填空,人應該都知道是填“雲南“。因爲我們是根據上下文的內容推斷出來的,但機會要做到這一步就相當得難了。因此,就有了現在的循環神經網絡,他的本質是:像人一樣擁有記憶的能力。因此,他的輸出就依賴於當前的輸入和記憶。

2.RNN的網絡結構及原理

它的網絡結構如下: 
這裏寫圖片描述
其中每個圓圈可以看作是一個單元,而且每個單元做的事情也是一樣的,因此可以摺疊呈左半圖的樣子。用一句話解釋RNN,就是一個單元結構重複使用

RNN是一個序列到序列的模型,假設xt1,xt,xt+1xt−1,xt,xt+1是一個輸入:“我是中國“,那麼ot1,otot−1,ot就應該對應”是”,”中國”這兩個,預測下一個詞最有可能是什麼?就是ot+1ot+1應該是”人”的概率比較大。

因此,我們可以做這樣的定義:

Xt:tot:tSt:tXt:表示t時刻的輸入,ot:表示t時刻的輸出,St:表示t時刻的記憶
。因爲我們當前時刻的輸出是由記憶和當前時刻的輸出決定的,就像你現在大四,你的知識是由大四學到的知識(當前輸入)和大三以及大三以前學到的東西的(記憶)的結合,RNN在這點上也類似,神經網絡最擅長做的就是通過一系列參數把很多內容整合到一起,然後學習這個參數,因此就定義了RNN的基礎:
St=f(UXt+WSt1)St=f(U∗Xt+W∗St−1)
大家可能會很好奇,爲什麼還要加一個f()f()函數,其實這個函數是神經網絡中的激活函數,但爲什麼要加上它呢? 
舉個例子,假如你在大學學了非常好的解題方法,那你初中那時候的解題方法還要用嗎?顯然是不用了的。RNN的想法也一樣,既然我能記憶了,那我當然是只記重要的信息啦,其他不重要的,就肯定會忘記,是吧。但是在神經網絡中什麼最適合過濾信息呀?肯定是激活函數嘛,因此在這裏就套用一個激活函數,來做一個非線性映射,來過濾信息,這個激活函數可能爲tanh,也可爲其他。

假設你大四快畢業了,要參加考研,請問你參加考研是不是先記住你學過的內容然後去考研,還是直接帶幾本書去參加考研呢?很顯然嘛,那RNN的想法就是預測的時候帶着當前時刻的記憶StSt去預測。假如你要預測“我是中國“的下一個詞出現的概率,這裏已經很顯然了,運用softmax來預測每個詞出現的概率再合適不過了,但預測不能直接帶用一個矩陣來預測呀,所有預測的時候還要帶一個權重矩陣V,用公式表示爲:

ot=softmax(VSt)ot=softmax(VSt)
其中otot就表示時刻t的輸出。

RNN中的結構細節: 
1.可以把StSt當作飲狀態,捕捉了之前時間點上的信息。就像你去考研一樣,考的時候記住了你能記住的所有信息。 
2.otot是由當前時間以及之前所有的記憶得到的。就是你考研之後做的考試卷子,是用你的記憶得到的。 
3.很可惜的是,StSt並不能捕捉之前所有時間點的信息。就像你考研不能記住所有的英語單詞一樣。 
4.和卷積神經網絡一樣,這裏的網絡中每個cell都共享了一組參數(U,V,W),這樣就能極大的降低計算量了。 
5.otot在很多情況下都是不存在的,因爲很多任務,比如文本情感分析,都是隻關注最後的結果的。就像考研之後選擇學校,學校不會管你到底怎麼努力,怎麼心酸的準備考研,而只關注你最後考了多少分。

3.RNN的改進1:雙向RNN

在有些情況,比如有一部電視劇,在第三集的時候纔出現的人物,現在讓預測一下在第三集中出現的人物名字,你用前面兩集的內容是預測不出來的,所以你需要用到第四,第五集的內容來預測第三集的內容,這就是雙向RNN的想法。如圖是雙向RNN的圖解: 
這裏寫圖片描述 

S1t=f(U1Xt+W1St1+b1)從前往後:St1→=f(U1→∗Xt+W1→∗St−1+b1→)
:S2t=f(U2Xt+W2St1+b2)從後往前:St2→=f(U2∗Xt→+W2→∗St−1+b2→)
ot=softmax(V[S1t;S2t])輸出:ot=softmax(V∗[St1→;St2→])
這裏的[S1t;S2t][St1→;St2→]做的是一個拼接,如果他們都是1000X1維的,拼接在一起就是1000X2維的了。

雙向RNN需要的內存是單向RNN的兩倍,因爲在同一時間點,雙向RNN需要保存兩個方向上的權重參數,在分類的時候,需要同時輸入兩個隱藏層輸出的信息。

4.RNN的改進2:深層雙向RNN

深層雙向RNN 與雙向RNN相比,多了幾個隱藏層,因爲他的想法是很多信息記一次記不下來,比如你去考研,複習考研英語的時候,背英語單詞一定不會就看一次就記住了所有要考的考研單詞吧,你應該也是帶着先前幾次背過的單詞,然後選擇那些背過,但不熟的內容,或者沒背過的單詞來背吧。

深層雙向RNN就是基於這麼一個想法,他的輸入有兩方面,第一就是前一時刻的隱藏層傳過來的信息h(i)t1h→t−1(i),和當前時刻上一隱藏層傳過來的信息h(i1)t=[h(i1)t;h(i1)t]ht(i−1)=[h→t(i−1);h←t(i−1)],包括前向和後向的。 
這裏寫圖片描述

我們用公式來表示是這樣的: 
這裏寫圖片描述 
然後再利用最後一層來進行分類,分類公式如下: 
這裏寫圖片描述

5.RNN的訓練-BPTT

如前面我們講的,如果要預測t時刻的輸出,我們必須先利用上一時刻(t-1)的記憶和當前時刻的輸入,得到t時刻的記憶:

st=tanh(Uxt+Wst1)st=tanh(Uxt+Wst−1)
然後利用當前時刻的記憶,通過softmax分類器輸出每個詞出現的概率:
y^t=softmax(Vst)y^t=softmax(Vst)
爲了找出模型最好的參數,U,W,V,我們就要知道當前參數得到的結果怎麼樣,因此就要定義我們的損失函數,用交叉熵損失函數:
tEt(yt,y^t)=ytlogy^tt時刻的損失:Et(yt,y^t)=−ytlogy^t
其中ytytt時刻的標準答案,是一個只有一個是1,其他都是0的向量;y^ty^t是我們預測出來的結果,與ytyt的維度一樣,但它是一個概率向量,裏面是每個詞出現的概率。因爲對結果的影響,肯定不止一個時刻,因此需要把所有時刻的造成的損失都加起來:
E(yt,y^t)=tEt(yt,y^t)=tytlogy^tE(yt,y^t)=∑tEt(yt,y^t)=−∑tytlogy^t

如圖所示,你會發現每個cell都會有一個損失,我們已經定義好了損失函數,接下來就是熟悉的一步了,那就是根據損失函數利用SGD來求解最優參數,在CNN中使用反向傳播BP算法來求解最優參數,但在RNN就要用到BPTT,它和BP算法的本質區別,也是CNN和RNN的本質區別:CNN沒有記憶功能,它的輸出僅依賴與輸入,但RNN有記憶功能,它的輸出不僅依賴與當前輸入,還依賴與當前的記憶。這個記憶是序列到序列的,也就是當前時刻收到上一時刻的影響,比如股市的變化。

因此,在對參數求偏導的時候,對當前時刻求偏導,一定會涉及前一時刻,我們用例子看一下:

假設我們對E3E3的W求偏導:它的損失首先來源於預測的輸出y^3y^3,預測的輸出又是來源於當前時刻的記憶s3s3,當前的記憶又是來源於當前的輸出和截止到上一時刻的記憶:s3=tanh(Ux3+Ws2)s3=tanh(Ux3+Ws2) 
因此,根據鏈式法則可以有:

E3W=E3y^3y^3s3s3W∂E3∂W=∂E3∂y^3∂y^3∂s3∂s3∂W
但是,你會發現,s2=tanh(Ux2+Ws1)s2=tanh(Ux2+Ws1),也就是s2s2裏面的函數還包含了W,因此,這個鏈式法則還沒到底,就像圖上畫的那樣,所以真正的鏈式法則是這樣的: 
這裏寫圖片描述 
我們要把當前時刻造成的損失,和以往每個時刻造成的損失加起來,因爲我們每一個時刻都用到了權重參數W。和以往的網絡不同,一般的網絡,比如人工神經網絡,參數是不同享的,但在循環神經網絡,和CNN一樣,設立了參數共享機制,來降低模型的計算量。

6.RNN與CNN的結合應用:看圖說話

在圖像處理中,目前做的最好的是CNN,而自然語言處理中,表現比較好的是RNN,因此,我們能否把他們結合起來,一起用呢?那就是看圖說話了,這個原理也比較簡單,舉個小栗子:假設我們有CNN的模型訓練了一個網絡結構,比如是這個

最後我們不是要分類嘛,那在分類前,是不是已經拿到了圖像的特徵呀,那我們能不能把圖像的特徵拿出來,放到RNN的輸入裏,讓他學習呢?

之前的RNN是這樣的:

St=tanh(UXt+WSt1)St=tanh(U∗Xt+W∗St−1)
我們把圖像的特徵加在裏面,可以得到:
St=tanh(UXt+WSt1+VX)St=tanh(U∗Xt+W∗St−1+V∗X)
其中的X就是圖像的特徵。如果用的是上面的CNN網絡,X應該是一個4096X1的向量。

注:這個公式只在第一步做,後面每次更新就沒有V了,因爲給RNN數據只在第一次迭代的時候給。

7.RNN項目練手

RNN可以寫歌詞,寫詩等,這有個項目可以玩玩,還不錯。 
Tensorflow實現RNN    https://github.com/hzy46/Char-RNN-TensorFlow

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