你已經了解了基礎的RNN模型的運行機制,在本節中你将會學習門控循環單元,它改變了RNN的隐藏層,使其可以更好地捕捉深層連接,并改善了梯度消失問題,讓我們看一看。
你已經見過了這個公式,
a^(<t>)=g(W_a [a^(<t-1>),x^(<t>) ] b_a),在RNN的時間t處,計算激活值。
我把這個畫個圖,把RNN的單元畫個圖,畫一個方框,輸入a^(<t-1>)(上圖編号1所示),即上一個時間步的激活值,再輸入x^(<t>)(上圖編号2所示),再把這兩個并起來,然後乘上權重項,在這個線性計算之後(上圖編号3所示),如果g是一個tanh激活函數,再經過tanh計算之後,它會計算出激活值a^(<t>)。
然後激活值a^(<t>)将會傳softmax單元(上圖編号4所示),或者其他用于産生輸出y^(<t>)的東西。就這張圖而言,這就是RNN隐藏層的單元的可視化呈現。我向展示這張圖,因為我們将使用相似的圖來講解門控循環單元。
許多GRU的想法都來分别自于Yu Young Chang, Kagawa,Gaza Hera, Chang Hung Chu和 Jose Banjo的兩篇論文。
我再引用上個筆記中你已經見過的這個句子,“The cat, which already ate……, was full.”,你需要記得貓是單數的,為了确保你已經理解了為什麼這裡是was而不是were,“The cat was full.”或者是“The cats were full”。
當我們從左到右讀這個句子,GRU單元将會有個新的變量稱為c,代表細胞(cell),即記憶細胞(下圖編号1所示)。記憶細胞的作用是提供了記憶的能力,比如說一隻貓是單數還是複數,所以當它看到之後的句子的時候,它仍能夠判斷句子的主語是單數還是複數。于是在時間t處,有記憶細胞c^(<t>),然後我們看的是,GRU實際上輸出了激活值a^(<t>),c^(<t>)=a^(<t>)(下圖編号2所示)。
于是我們想要使用不同的符号c和a來表示記憶細胞的值和輸出的激活值,即使它們是一樣的。我現在使用這個标記是因為當我們等會說到LSTMs的時候,這兩個會是不同的值,但是現在對于GRU,c^(<t>)的值等于a^(<t>)的激活值。
所以這些等式表示了GRU單元的計算,在每個時間步,我們将用一個候選值重寫記憶細胞,即̃c^(<t>)的值,所以它就是個候選值,替代了c^(<t>)的值。然後我們用tanh激活函數來計算,̃c^(<t>)=tanh(W_c [c^(<t-1>),x^(<t>) ] b_c),所以̃c^(<t>)的值就是個替代值,代替表示c^(<t>)的值(下圖編号3所示)。
重點來了,在GRU中真正重要的思想是我們有一個門,我先把這個門叫做Γ_u(上圖編号4所示),這是個下标為u的大寫希臘字母Γ,u代表更新門,這是一個0到1之間的值。
為了讓你直觀思考GRU的工作機制,先思考Γ_u,這個一直在0到1之間的門值,實際上這個值是把這個式子帶入sigmoid函數得到的,Γ_u=σ(W_u [c^(<t-1>),x^(<t>) ] b_u)。
我們還記得sigmoid函數是上圖編号5所示這樣的,它的輸出值總是在0到1之間,對于大多數可能的輸入,sigmoid函數的輸出總是非常接近0或者非常接近1。
在這樣的直覺下,可以想到Γ_u在大多數的情況下非常接近0或1。然後這個字母u表示“update”,我選了字母Γ是因為它看起來像門。還有希臘字母G,G是門的首字母,所以G表示門。
然後GRU的關鍵部分就是上圖編号3所示的等式,我們剛才寫出來的用̃c更新c的等式。然後門決定是否要真的更新它。于是我們這麼看待它,記憶細胞c^(<t>)将被設定為0或者1,這取決于你考慮的單詞在句子中是單數還是複數,因為這裡是單數情況,所以我們先假定它被設為了1,或者如果是複數的情況我們就把它設為0。然後GRU單元将會一直記住c^(<t>)的值,直到上圖編号7所示的位置,c^(<t>)的值還是1,這就告訴它,噢,這是單數,所以我們用was。于是門Γ_u的作用就是決定什麼時候你會更新這個值,特别是當你看到詞組the cat,即句子的主語貓,這就是一個好時機去更新這個值。然後當你使用完它的時候,“The cat, which already ate……, was full.”,然後你就知道,我不需要記住它了,我可以忘記它了。
所以我們接下來要給GRU用的式子就是c^(<t>)=Γ_u*̃c^(<t>) (1-Γ_u )*c^(<t-1>)(上圖編号1所示)。你應該注意到了,如果這個更新值Γ_u=1,也就是說把這個新值,即c^(<t>)設為候選值(Γ_u=1時簡化上式,c^(<t>)=̃c^(<t>))。将門值設為1(上圖編号2所示),然後往前再更新這個值。
對于所有在這中間的值,你應該把門的值設為0,即Γ_u=0,意思就是說不更新它,就用舊的值。因為如果Γ_u=0,則c^(<t>)=c^(<t-1>),c^(<t>)等于舊的值。甚至你從左到右掃描這個句子,當門值為0的時候(上圖編号3所示,中間Γ_u=0一直為0,表示一直不更新),就是說不更新它的時候,不要更新它,就用舊的值,也不要忘記這個值是什麼,這樣即使你一直處理句子到上圖編号4所示,c^(<t>)應該會一直等c^(<t-1>),于是它仍然記得貓是單數的。
讓我再畫個圖來(下圖所示)解釋一下GRU單元,順便說一下,當你在看網絡上的博客或者教科書或者教程之類的,這些圖對于解釋GRU和我們稍後會講的LSTM是相當流行的,我個人感覺式子在圖片中比較容易理解,那麼即使看不懂圖片也沒關系,我就畫畫,萬一能幫得上忙就最好了。
GRU單元輸入c^(<t-1>)(下圖編号1所示),對于上一個時間步,先假設它正好等于a^(<t-1>),所以把這個作為輸入。然後x^(<t>)也作為輸入(下圖編号2所示),然後把這兩個用合适權重結合在一起,再用tanh計算,算出̃c^(<t>),̃c^(<t>)=tanh(W_c [c^(<t-1>),x^(<t>) ] b_c),即c^(<t>)的替代值。
再用一個不同的參數集,通過sigmoid激活函數算出Γ_u,Γ_u=σ(W_u [c^(<t-1>),x^(<t>) ] b_u),即更新門。最後所有的值通過另一個運算符結合,我并不會寫出公式,但是我用紫色陰影标注的這個方框(下圖編号5所示,其所代表的運算過程即下圖編号13所示的等式),代表了這個式子。所以這就是紫色運算符所表示的是,它輸入一個門值(下圖編号6所示),新的候選值(下圖編号7所示),這再有一個門值(下圖編号8所示)和c^(<t>)的舊值(下圖編号9所示),所以它把這個(下圖編号1所示)、這個(下圖編号3所示)和這個(下圖編号4所示)作為輸入一起産生記憶細胞的新值c^(<t>),所以c^(<t>)等于a^(<t>)。如果你想,你也可以也把這個帶入softmax或者其他預測y^(<t>)的東西。
這就是GRU單元或者說是一個簡化過的GRU單元,它的優點就是通過門決定,當你從左(上圖編号10所示)到右掃描一個句子的時候,這個時機是要更新某個記憶細胞,還是不更新,不更新(上圖編号11所示,中間Γ_u=0一直為0,表示一直不更新)直到你到你真的需要使用記憶細胞的時候(上圖編号12所示),這可能在句子之前就決定了。
因為sigmoid的值,現在因為門很容易取到0值,隻要這個值是一個很大的負數,再由于數值上的四舍五入,上面這些門大體上就是0,或者說非常非常非常接近0。
所以在這樣的情況下,這個更新式子(上圖編号13所示的等式)就會變成c^(<t>)=c^(<t-1>),這非常有利于維持細胞的值。因為Γ_u很接近0,可能是0.000001或者更小,這就不會有梯度消失的問題了。因為Γ_u很接近0,這就是說c^(<t>)幾乎就等于c^(<t-1>),而且c^(<t>)的值也很好地被維持了,即使經過很多很多的時間步(上圖編号14所示)。這就是緩解梯度消失問題的關鍵,因此允許神經網絡運行在非常龐大的依賴詞上,比如說cat和was單詞即使被中間的很多單詞分割開。
現在我想說下一些實現的細節,在這個我寫下的式子中c^(<t>)可以是一個向量(上圖編号1所示),如果你有100維的隐藏的激活值,那麼c^(<t>)也是100維的,̃c^(<t>)也是相同的維度(̃c^(<t>)=tanh(W_c [c^(<t-1>),x^(<t>) ] b_c)),Γ_u也是相同的維度(Γ_u=σ(W_u [c^(<t-1>),x^(<t>) ] b_u)),還有畫在框中的其他值。這樣的話“*”實際上就是元素對應的乘積(c^(<t>)=Γ_u*̃c^(<t>) (1-Γ_u )*c^(<t-1>)),所以這裡的Γ_u:(Γ_u=σ(W_u [c^(<t-1>),x^(<t>) ] b_u)),即如果門是一個100維的向量,Γ_u也就100維的向量,裡面的值幾乎都是0或者1,就是說這100維的記憶細胞c^(<t>)(c^(<t>)=a^(<t>)上圖編号1所示)就是你要更新的比特。
當然在實際應用中Γ_u不會真的等于0或者1,有時候它是0到1的一個中間值(上圖編号5所示),但是這對于直觀思考是很方便的,就把它當成确切的0,完全确切的0或者就是确切的1。元素對應的乘積做的就是告訴GRU單元哪個記憶細胞的向量維度在每個時間步要做更新,所以你可以選擇保存一些比特不變,而去更新其他的比特。比如說你可能需要一個比特來記憶貓是單數還是複數,其他比特來理解你正在談論食物,因為你在談論吃飯或者食物,然後你稍後可能就會談論“The cat was full.”,你可以每個時間點隻改變一些比特。
你現在已經理解GRU最重要的思想了,幻燈片中展示的實際上隻是簡化過的GRU單元,現在來描述一下完整的GRU單元。
對于完整的GRU單元我要做的一個改變就是在我們計算的第一個式子中給記憶細胞的新候選值加上一個新的項,我要添加一個門Γ_r(下圖編号1所示),你可以認為r代表相關性(relevance)。這個Γ_r門告訴你計算出的下一個c^(<t>)的候選值̃c^(<t>)跟c^(<t-1>)有多大的相關性。計算這個門Γ_r需要參數,正如你看到的這個,一個新的參數矩陣W_r,Γ_r=σ(W_r [c^(<t-1>),x^(<t>) ] b_r)。
正如你所見,有很多方法可以來設計這些類型的神經網絡,然後我們為什麼有Γ_r?為什麼不用上一張幻燈片裡的簡單的版本?這是因為多年來研究者們試驗過很多很多不同可能的方法來設計這些單元,去嘗試讓神經網絡有更深層的連接,去嘗試産生更大範圍的影響,還有解決梯度消失的問題,GRU就是其中一個研究者們最常使用的版本,也被發現在很多不同的問題上也是非常健壯和實用的。你可以嘗試發明新版本的單元,隻要你願意。但是GRU是一個标準版本,也就是最常使用的。你可以想象到研究者們也嘗試了很多其他版本,類似這樣的但不完全是,比如我這裡寫的這個。然後另一個常用的版本被稱為LSTM,表示長短時記憶網絡,這個我們會在下節中講到,但是GRU和LSTM是在神經網絡結構中最常用的兩個具體實例。
還有在符号上的一點,我嘗試去定義固定的符号讓這些概念容易理解,如果你看學術文章的話,你有的時候會看到有些人使用另一種符号̃x,u,r和h表示這些量。但我試着在GRU和LSTM之間用一種更固定的符号,比如使用更固定的符号Γ來表示門,所以希望這能讓這些概念更好理解。
所以這就是GRU,即門控循環單元,這是RNN的其中之一。
這個結構可以更好捕捉非常長範圍的依賴,讓RNN更加有效。然後我簡單提一下其他常用的神經網絡,比較經典的是這個叫做LSTM,即長短時記憶網絡,我們在下節中講解。
(Chung J, Gulcehre C, Cho K H, et al. Empirical Evaluation of Gated Recurrent Neural Networks on Sequence Modeling[J]. Eprint Arxiv, 2014. Cho K, Merrienboer B V, Bahdanau D, et al. On the Properties of Neural Machine Translation: Encoder-Decoder Approaches[J]. Computer Science, 2014.)
,更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!