一、為什麼選擇序列模型
序列模型可以用于很多領域,如語音識别,撰寫文章等等。總之很多優點。。。
二、數學符号
為了後面友善說明,先将會用到的數學符号進行介紹。
以下圖為例,假如我們需要定位一句話中人名出現的位置。
- 紅色框中的為輸入、輸出值。可以看到人名輸出用1表示,反之用0表示;
- 綠色框中的\(x^{<t>},y^{<t>}\)表示對應紅色框中的輸入輸出值的數學表示,注意從1開始。
- 灰色框中的\(T_x,T_y\)分别表示輸入輸出序列的長度,在該例中,\(T_x=9,T_y=9\)
- 黃色框中\(X^{(i)<t>}\)上的表示第i個輸入樣本的第t個輸入值,\(T_x^{(i)}\)則表示第i個輸入樣本的長度。輸出y也同理。
輸入值中每個單詞使用One-shot來表示。即首先會建構一個字典(Dictionary),假設該例中的字典次元是10000*1(如圖示)。第一個單詞"Harry"的數學表示形式即為[0,0,0,……,1 (在第4075位) ,0,……,0],其他單詞同理。
但是如果某一個單詞并沒有被包含在字典中怎麼辦呢?此時我們可以添加一個新的标記,也就是一個叫做Unknown Word的僞造單詞,用 <UNK> 表示。具體的細節會在後面介紹。
三、循環神經網絡模型
1.為什麼不用标準網絡
在介紹RNN之前,首先解釋一下為什麼之前的标準網絡不再适用了。因為它有兩個缺點:
- 輸入和輸出的長度不盡相同
- 無法共享從其他位置學來的特征。例如上一節中的Harry這個詞是用\(x^{<1>}\)表示的,網絡從該位置學習了它是一個人名。但是我們希望無論Harry在哪個位置出現網絡都能識别出這是一個人名的一部分,而标準網絡無法做到這一點。
2.RNN結構
還是以識别人名為例,第一個單詞\(x^{<1>}\)輸入神經網絡得到輸出\(y^{<1>}\)
同理由\(x^{<2>}\)将得到\(y^{<2>}\),以此類推。但是這就是傳統網絡存在的問題,即單詞之間沒有聯系
為了将單詞之間關聯起來,是以将前一層的結果也作為下一層的輸入資料。如下圖示
整體的RNN結構有兩種表示形式,如下圖示
左邊是完整的表達形式,注意第一層的\(a^{<0>}\)一般設定為0向量。
右邊的示意圖是RNN的簡寫示意圖。
介紹完結構之後,我們還需要知道網絡中參數的表達方式及其含義。如下圖示,\(x^{<i>}\)到網絡的參數用\(W_{ax}\)表示,\(a^{<i>}\)到網絡的參數用\(W_{aa}\)表示,\(y^{<i>}\)到網絡的參數用\(W_{ya}\)表示,具體含義将在下面進行說明。
如下圖示,\(x^{<1>}\)通過網絡可以傳遞到\(y^{<3>}\),但是這存在一個問題,即每個輸出隻與前面的輸入有關,而與後面的無關。這個問題會在後續内容中進行改進。
3.RNN前向傳播
如圖示,\(a^{<0>}=\vec{0}\)
激活函數:\(g_1\)一般為tanh函數或者是Relu函數,\(g_2\)一般是Sigmod函數。
- \(a^{<1>}=g_1(W_{aa}a^{<0>}+W_{ax}x^{<1>}+b_a)\)
- \(y^{<1>}=g_2(W_{ya}a^{<1>}+b_y)\)
- \(a^{<t>}=g_1(W_{aa}a^{<t-1>}+W_{ax}x^{<t>}+b_a)\)
- \(y^{<t>}=g_2(W_{ya}a^{<t>}+b_y)\)
注意參數的下标是有順序含義的,如\(W_{ax}\)下标的第一個參數表示要計算的量的類型,即要計算\(a\)矢量,第二個參數表示要進行乘法運算的資料類型,即需要與\(x\)矢量做運算。如 \(W_{ax} x^{t}\rightarrow{a}\)
4.簡化RNN公式
下面将對如下公式進行化簡:
- 1. 簡化\(a^{<t>}\)
\[\begin{align}
a^{<t>}&= g(W_{aa}a^{<t-1>}+W_{ax}x^{<t>}+b_a) \notag \\
&= g(W_a [a^{<t-1>},x^{<t>}]^{T}+b_a) \notag
\end{align}\]
注意,公式中使用了兩個矩陣進行化簡,分别是 \(W_a\)和\([a^{<t-1>},x^{<t>}]^T\)(使用轉置符号更易了解),下面分别進行說明:
- \(W_a = [ W_{aa}, W_{ax}]\),假設\(W_{aa}\)是(100,100)的矩陣,\(W_{ax}\)是(100,10000)的矩陣,那麼\(W\)則是(100,10100)的矩陣。
- \([a^{<t-1>},x^{<t>}]^T\)是下圖示意。
故\(W_a [a^{<t-1>},x^{<t>}]^{T}\)矩陣計算如下圖示
- 2.簡化\(y^{<t>}\)
該節PPT内容:
四、通過時間的反向傳播
下面将會對反向傳播進行灰常灰常詳細的介紹,跟着下面一張一張的圖檔走起來~
1.整體感受
- 首先再回顧一下RNN的整體結構
- 要進行反向傳播,首先需要前向傳播,傳播方向如藍色箭頭所示,其次再按照紅色箭頭進行反向傳播。
2.前向傳播
- 首先給出所有輸入資料,即從\(x^{<1>}\)到\(x^{<T_x>}\),\(T_x\)表示輸入資料的數量。
- 初始化參數\(W_a,b_a\),将輸入資料輸入網絡得到對應的\(a^{<t>}\)
- 再通過與初始化參數\(W_y,b_y\)得到\(y^{<t>}\)
3.損失函數定義
要進行反向傳播,必須得有損失函數嘛,是以我們将損失函數定義如下:
- 每個節點的損失函數
\(L^{<t>}(\hat{y}^{<t>},y^{<t>})=y^{<t>}log(y^{<t>})-(1-y^{<t>})log(1-\hat{y}^{<t>})\)
- 整個網絡的損失函數
\(L(\hat{y}^{<t>},y^{<t>)}) = \sum_{t=1}^{T_y}L^{<t>}(\hat{y}^{<t>},y^{<t>})\)
4.反向傳播
計算出損失值後再通過梯度下降進行反向傳播
5.整個流程圖
五、不同類型的循環神經網絡
本節主要介紹了其他更多類型的RNN結構,下圖參考大資料文摘
六、語言模型和序列生成
1.什麼是語言模型
凡事開頭舉個栗子,一切都好說:
假設一個語音識别系統聽一句話得到了如下兩種選擇,作為正常人肯定會選擇第二種。但是機器才如何做判斷呢?
此時就需要通過語言模型來預測每句話的機率:
2.如何使用RNN建構語言模型
- 首先我們需要一個很大的語料庫(Corpus)
- 将每個單詞字元化(Tokenize,即使用One-shot編碼)得到詞典,,假設有10000個單詞
- 還需要添加兩個特殊的單詞
- : end of sentence. 終止符,表示句子結束.
- : UNknown, 之前的筆記已介紹過.
3.建構語言模型示例
假設要對這句話進行模組化:Cats average 15 hours of sleep a day. <EOS>
- 1.初始化
這一步比較特殊,即\(x^{<1>}\)和\(a^{<0>}\)都需要初始化為\(\vec{0}\)。
此時\(\hat{y}^{<1>}\)将會對第一個字可能出現的每一個可能進行機率的判斷,即\(\hat{y}^{<1>}=[p(a),…,p(cats),…]\)。
當然在最開始的時候沒有任何的依據,可能得到的是完全不相幹的字,因為隻是根據初始的值和激活函數做出的取樣。
- 2.将真實值作為輸入值
之是以将真實值作為輸入值很好了解,如果我們一直傳錯誤的值,将永遠也無法得到字與字之間的關系。
如下圖示,将\(y^{<1>}\)所表示的真實值Cats作為輸入,即\(x^{<2>}=y^{<1>}\)得到\(\hat{y}^{<2>}\)。
此時的\(\hat{y}^{<2>}=[p(a|cats),…,p(average|cats),…]\)。
同理有\(\hat{y}^{<3>}=[p(a|cats\, average),…,p(average|cats\,average),…]\)
另外輸入值滿足: \(x^{<t>}=y^{<t-1>}\)
- 3.計算出損失值
下圖給出了構模組化型的過程以及損失值計算公式。
七、對新序列采樣
當我們訓練得到了一個模型之後,如果我們想知道這個模型學到了些什麼,一個非正式的方法就是對新序列進行采樣。具體方法如下:
在每一步輸出\(\hat{y}\)時,通常使用 softmax 作為激活函數,然後根據輸出的分布,随機選擇一個值,也就是對應的一個字或者英文單詞。
然後将這個值作為下一個單元的x輸入進去(即\(x^{<t>}=\hat{y}^{<t-1>}\)), 直到我們輸出了終結符,或者輸出長度超過了提前的預設值n才停止采樣。.
上述步驟具體如圖示:
下圖給出了采樣之後得到的效果:
左邊是對訓練得到新聞資訊模型進行采樣得到的内容;
右邊是莎士比亞模型采樣得到的内容。
八、帶有神經網絡的梯度消失
1.RNN的梯度消失、爆炸問題
梯度值在RNN中也可能因為反向傳播的層次太多導緻過小或者過大。
- 當梯度值過小的時候,神經網絡将無法有效地調整自己的權重矩陣導緻訓練效果不佳,稱之為“梯度消失問題”(gradient vanishing problem);
- 過大時可能直接影響到程式的運作因為程式已經無法存儲那麼大的值,直接傳回 NaN ,稱之為“梯度爆炸問題”(gradient exploding problem)。
當梯度值過大的時候有一個比較簡便的解決方法,每次将傳回的梯度值進行檢查,如果超出了預定的範圍,則手動設定為範圍的邊界值。
if (gradient > max) {
gradient = max
}
但梯度值過小的解決方案要稍微複雜一點,比如下面兩句話:
“The cat,which already ate apple,yogurt,banana,..., was full.”
“The cats,which already ate apple,yogurt,banana,..., were full.”
重點标出的 cat(s)和be動詞(was,were) 是有很重要的關聯的,但是中間隔了一個which引導的定語從句,對于前面所介紹的基礎的RNN網絡很難學習到這個資訊,尤其是當出現梯度消失時,而且這種情況很容易發生。
我們知道一旦神經網絡層次很多時,反向傳播很難影響前面層次的參數。是以為了解決梯度消失問題,提出了GRU單元,下面一節具體介紹。
九、GRU單元
GRU(Gated Recurrent Unit)是一種用來解決梯度值過小的方法,首先來看下在一個時刻下的RNN單元,激活函數為 tanh
1.首先回顧一下普通RNN單元的結構示意圖
如圖示,輸入資料為\(a^{<t-1>}\)和\(x^{<t>}\),與參數\(W_a\)進行線性運算後再使用tanh函數轉化得到\(a^{<t>}\). 當然再使用softmax函數處理可以得到預測值。
2.GRU結構
- 記憶細胞
在GRU中會用到 “記憶細胞(Memory cell)” 這個概念,我們用變量
\(c\)表示。這個記憶細胞提供了記憶功能,例如它能夠幫助記住 cat對應was,cats對應were。
而在t時刻,記憶細胞所包含的值其實就是激活函數值,即\(c^{<t>}=a^{<t>}\)。
注意:在這裡兩個變量的值雖然一樣,但是含義不同。另外在下節将介紹的LSTM中,二者值的大小有可能是不一樣的,是以有必要使用這兩種變量進行區分。
為了更新記憶細胞的值,我們引入
\(\tilde{c}\)來作為候選值進而來更新\(c^{<t>}\),其公式為:
\[\tilde{c}=tanh(W_c [c^{<t-1>}, x^{<t>}]+b_c)
\]
- 更新門(update gate)
更新門是GRU的核心概念,它的作用是用于判斷是否需要進行更新。
更新門用\(\Gamma_u\)表示,其公式為:
\[\Gamma_u=σ(W_u [c^{<t-1>}, x^{<t>}]+b_u)
如上圖示,\(\Gamma_u\)值的大小大多分布在0或者1,是以可以将其值的大小粗略的視為0或者1。這就是為什麼我們就可以将其了解為一扇門,如果\(\Gamma_u=1\),就表示此時需要更新值,反之不用。
- t時刻記憶細胞
有了更新門公式後,我們則可以給出t時刻記憶細胞的值的計算公式了:
\[c^{<t>}=\Gamma_u*\tilde{c}+(1-\Gamma_u)*c^{<t-1>}
注意:上面公式中的 * 表示元素之間進行乘法運算,而其他公式是矩陣運算。
公式很好了解,如果\(\Gamma_u=1\),那麼t時刻記憶細胞的值就等于候選值\(\tilde{c}\),反之等于前一時刻記憶細胞的值。
下圖給出了該公式很直覺的解釋:
在讀到“cat”的時候 ,其他時候一直為0,知道要輸出“was”的時刻我們仍然知道“cat”的存在,也就知道它為單數了。
- GRU結構示意圖
3.完整版GRU
上述是簡化了的GRU,在完整版中還存在另一個符号 ,這個符号的意義是控制\(\tilde{c}\)和\(c^{<t-1>}\)之間的聯系強弱,完整版公式如下:
注意,完整公式中多出了一個\(\Gamma_r\),這個符号的作用是控制\(\tilde{c}^{<t>}\)與\(c^{<t>}\)之間聯系的強弱。
十、長短期記憶
介紹完GRU後,再介紹LSTM會更加容易了解。下圖是二者公式對比:
GRU隻有兩個門,而LSTM有三個門,分别是更新門\(\Gamma_u\),遺忘門\(\Gamma_f\),輸出門\(\Gamma_o\)
雖然LSTM比GRU更複雜,但是它比GRU更早提出哦。另外一般而言LSTM的表現要更好,但是計算量更大,畢竟多了一個門嘛。而GRU實際上是對LSTM的簡化,它的表現也不錯,能夠更好地擴充到深層網絡。是以二者各有優勢。
下圖是LSTM的結構示意圖:
十一、雙向遞歸神經網絡
前面介紹的都是單向的RNN結構,在處理某些問題上得到的效果不盡人意
如下面兩句話,我們要從中标出人名:
He said, "Teddy Roosevelt was a great President".
He said, "Teddy bears are on sale".
第一句中的Teddy Roosevelt是人名,但第二句中的Teddy bears是泰迪熊,同樣都是單詞Teddy對應的輸出在第一句中應該是1,第二句中應該是0。
像這樣的例子如果想讓我們的序列模型明白就需要借助不同的結構比如 - 雙向遞歸神經網絡(Bidirectional RNN)。該神經網絡首先從正面了解一遍這句話,再從反方向了解一遍。
雙向遞歸神經網絡結構如下:
下圖摘自大資料文摘整理
十二、深層循環神經網絡
深層,顧名思義就是層次增加。如下圖是深層循環神經網絡的示意圖
橫向表示時間展開,縱向則是層次展開。
注意激活值的表達形式有所改變,以\(a^{[1]<0>}\)為例進行解釋:
- [1]表示第一層
- <0>表示第一個激活值
另外各個激活值的計算公式也略有不同,以\(a^{[2]<3>}\)為例,其計算公式如下:
微信公衆号:AutoML機器學習 MARSGGBO ♥原創
如有意合作或學術讨論歡迎私戳聯系~
2018-1-17