MLK | 一文理清深度學習循環神經網路
- 2019 年 10 月 30 日
- 筆記
MLK,即Machine Learning Knowledge,本專欄在於對機器學習的重點知識做一次梳理,便於日後溫習,內容主要來自於《百面機器學習》一書,結合自己的經驗與思考做的一些總結與歸納。本次主要講解的深度學習循環神經網路方面的知識。
導讀
在開始講循環神經網路之前,我們可以簡單來回顧一下前向神經網路的知識點,因為這一塊的知識是有一些互通的呢(請戳《一文理清 深度學習前饋神經網路》)。
簡單來說吧,循環神經網路(Recurrent Neural Network)也就是我們常見的RNN了,它是用來構建序列化模型的一種主流深度學習模型,我們傳統的前饋神經網路一般的輸入都是定長的向量,無法處理會變長的序列資訊,有些同學會說我把它轉換成定長向量不就好了嗎?但其實不然,即便轉換了,模型也很難去捕捉到序列中的長距離依賴關係。
因此,這裡就提出了RNN的方法,RNN通過將神經元串列起來處理序列化的數據,由於每個神經元能用它的內部變數保存之前輸入的序列資訊,因此整個序列就可以被進行抽象表示,並據此進行分類or生成新序列。所以這個RNN也經常會被應用在機器翻譯、序列標註、影像描述、推薦系統、AI機器人等等。
Index
- RNN與CNN的區別與聯繫
- RNN存在梯度消失or梯度爆炸?
- 重點深入了解下LSTM
- 重點深入了解下Seq2Seq
RNN與CNN的區別與聯繫
在我們處理文本數據的時候,通過會做的操作就是把語料所對應的的TF-IDF向量作為輸入,其中TF-IDF向量的維度是辭彙表的大小。
TF-IDF: 一種統計方法,用以評估一字詞對於一個文件集或一個語料庫中的其中一份文件的重要程度。字詞的重要性隨著它在文件中出現的次數成正比增加,但同時會隨著它在語料庫中出現的頻率成反比下降。
傳統做法,就是使用CNN接收TF-IDF向量作為特徵輸入,然後通過滑動窗口加池化的方法將原先的輸入轉換成一個固定長度的向量表示,雖然這樣子也會捕捉到局部的特徵,但長距離單詞之間的依賴資訊就會丟失了。
卷積神經網路(Convolutional Neural Network,CNN),它也是屬於前饋神經網路的一種,其特點是每層的神經元節點只響應前一層局部區域範圍內的神經元(全連接網路中每個神經元節點則是響應前一層的全部節點)。
RNN就可以避免這種情況,它可以很好地處理文本數據變長並且有序的輸入序列,簡單來說它是模擬了一個人在閱讀文章的情景,從開始讀到最後讀完,並且擁有」記憶「能力(把前面閱讀到的有用資訊編碼到狀態變數里去)。
RNN存在梯度消失or梯度爆炸?
梯度消失(Gradient Vanishing),也就是梯度的反向傳播過程中,後層的梯度以連乘方式疊加到前層,而一般我們的神經網路的激活函數都是用的Sigmoid函數,它具有飽和特徵,即在輸入達到一定值的時候,輸出就幾乎不會發生明顯改變了,而後層的誤差梯度反傳回前層的時候,幾乎就會衰減為0,因此前層的參數無法得到有效的學習。
梯度爆炸則是相反,大於1的值不斷連乘帶來一個很大的誤差返回。
Sigmoid函數就是Logistic函數,其數學表達式、對應函數影像、導函數和導函數影像為:

可以看出,Sigmoid激活函數在定義域上是單調遞增的,越靠近兩端變化越平緩,從導數影像可以看出,Sigmoid函數的導數取值範圍在0-0.25之間,如果我們初始化的網路權值∣w∣小於1(一般也是這麼操作),隨著層數不斷增多,每次連乘後逐漸變小,梯度就逐漸消失了。
同理,梯度爆炸也是類似,當我們的初始化的網路權值過大,導致 ∣σ′(z)w∣>1,不斷連乘後就會得到一個很大的值了。
梯度消失和爆炸會帶來什麼影響?
最直觀的解釋就是,當在模型訓練過程中出現了梯度消失,接近輸出層的隱含層的梯度是正常的,所以權值更新的值也是正常的,但是越往回傳遞,出現了梯度消失的問題,這個時候輸入層附近的隱含層的權值更新就會緩慢甚至停滯,所以就相當於前面的幾個隱含層是」形同虛設「,深度網路其實就不再」深度「了,而可能只是後面幾個隱含層構成的淺層網路。
解決方法:
對於這種常見的問題,當然解決辦法也是很常見的了,下面羅列幾條:
1)更換激活函數
比如幾種常見的激活函數,對於避免上述的問題很有效。
ReLU:使得我們的激活函數導數為1
LeakyReLU:ReLU的優化,同時解決了ReLu中0區間帶來的影響
2)使用ResNet殘差結構
其實為了解決梯度消失和爆炸問題,BN(Batch Normalization)結構也可以順利解決,BN層對每層的輸出做歸一化,這樣梯度在反向層層傳遞後仍可以保持大小穩定,不會出現過小或過大的問題,但BN在深度不斷增大後會出現一個問題:Degradation Problem(準確率下降問題)。這個問題在我們的網路層級達到一定深度的時候就會出現,準確率飽和,然後迅速下降,這個問題不是由於過擬合或是梯度問題導致的,而是由於網路結構太過於複雜導致的,換句話說就是如果不加約束的放羊式訓練很難達到理想的準確率的。
ResNet的提出就是為了解決這個問題的。
3)預訓練加微調
Step1:pre-training(預訓練)
此方法來自Hinton在2006年發表的一篇論文,Hinton為了解決梯度的問題,提出採取無監督逐層訓練方法,其基本思想是每次訓練一層隱節點,訓練時將上一層隱節點的輸出作為輸入,而本層隱節點的輸出作為下一層隱節點的輸入,此過程就是逐層「預訓練」(pre-training);
Step2:fine-tunning(微調)
在預訓練完成後,再對整個網路進行「微調」(fine-tunning)。Hinton在訓練深度信念網路(Deep Belief Networks中,使用了這個方法,在各層預訓練完成後,再利用BP演算法對整個網路進行訓練。此思想相當於是先尋找局部最優,然後整合起來尋找全局最優。
4)梯度剪切、權重正則化
梯度剪切這個主要是針對梯度爆炸而設計的解決方案,其核心思想就是設置一個梯度剪切的閾值,在更新梯度的時候對超出閾值的限制為該閾值,防止梯度爆炸。
權重正則化也是為了解決梯度爆炸問題而提出的,常見的就是L1、L2正則化,在各個深度框架中都有對應的API可以使用正則化,正則化是通過對網路權重做正則限制過擬合,如下面的Loss Function:

其中α指的是正則化係數,當發生梯度爆炸的時候,權重的範數就會變得很大,通過正則項則可以防止部分梯度爆炸的發生。
5)LSTM
LSTM全稱是長短期記憶網路(long-short term memory networks),是不那麼容易發生梯度消失的,主要原因在於LSTM內部複雜的「門」(gates),如下圖,LSTM通過它內部的「門」可以接下來更新的時候「記住」前幾次訓練的」殘留記憶「,因此,經常用於生成文本中。目前也有基於CNN的LSTM,感興趣的可以嘗試一下。

重點深入了解下LSTM
長短期記憶網路(long-short term memory networks,LSTM)是循環神經網路的最知名和成功的擴展,可以對有價值的資訊進行長期記憶,從而減小循環神經網路的學習難度,因此在語音識別、語言建模、機器翻譯、命名實體識別、影像描述文本生成等問題中有著廣泛應用。
LSTM如何實現長期記憶功能?
還是上面的圖,與傳統循環神經網路相似,但是對內部結構進行精心設計,加入了輸入門、遺忘門以及輸出門,還有一個內部記憶單元。
1)輸入門控制當前計算的新狀況以多大程度更新到記憶單元中;
2)遺忘門控制前一步記憶單元中的資訊有多大程度被遺忘;
3)輸出門控制當前的輸出有多大程度上取決於當前的以及單元。
進一步解釋,也就是說LSTM的狀態轉移不一定全部由激活函數的計算結果,還得依賴於輸入門與遺忘門來共同控制,如:
在一個訓練好的網路中,當輸入的序列中沒有重要的資訊,LSTM的遺忘門的值會接近於1,輸入門的值接近於0,此時過去的記憶仍會被保留,從而實現了長期記憶功能;但如果輸入的序列中出現了重要資訊的時候,LSTM就會把它存入記憶中,此時輸入門的值會更新為1,而遺忘門的值會接近於0,這樣子舊的記憶就會被遺忘,新的資訊就會被記憶。
LSTM用的是什麼激活函數?
在LSTM中,遺忘門、輸入門和輸出門使用SIgmoid函數作為激活函數,在生成候選記憶時候,使用雙曲正切函數Tanh作為激活函數。因為Sigmoid函數的輸出值在0~1之間,符合門控的物理定理,即輸入較大or較小的時候其輸出會非常接近1or0,從而保證了門的開關。在生成候選記憶的時候,使用Tanh函數的原因是因為其取值範圍為-1~1之間,與大多數場景下特徵分布是0中心吻合,同時Tanh函數在輸入為0附近相比於Sigmoid函數有更大的梯度,通常使得模型收斂更快。
重點深入了解下Seq2Seq
Seq2Seq,全稱是Sequence to Sequence模型,大致是意思就是將一個序列訊號通過編碼和解碼生成一個新的序列資訊,通過會用於機器翻譯、語音識別、自動對話等任務。它的核心思想就是通過深度神經網路,將一個作為輸入的序列映射為一個作為輸出的序列,這一過程由編碼輸入和編碼輸出兩個環節構成,在經典的實現中,編碼器和解碼器各有一個循環神經網路來構成,既可以是傳統循環神經網路結構,也可以是LSTM、門控循環單元等。
這裡有一個簡單形象的例子:
在一次期末考試,我們將需要複習的知識經過複習(加工),形成了知識體系(結構),這就是編碼過程。在考試的時候,將高度抽象的知識體系應用到具體的問題中去求解,這就是解碼過程。 對於學霸,在複習過程就可以構建成一個比較強大的網路,可以對很長(很難很久遠)的資訊進行抽象理解,加工內化為編碼向量,在考試中從容應答問題。 對於一般人,很難記憶長距離、高難度的資訊,一般都只好」臨時抱佛腳「,編碼很短期的序列訊號,考試時候就聽天由命,能答多少就寫多少。
Seq2Seq的核心在於解碼
Seq2Seq的核心在於解碼部分,大量的改進也是在解碼環節衍生的,其最基本的解碼方法就是貪心法,即選取一種度量標準後,每次都在當前狀態下選擇最佳的一個結果,直到結束。這種方法有一個最大的弊端就是面對複雜的問題的時候,很難得到最優解。
那麼,這裡有一個改良的演算法,叫做集束搜索,它是一個啟發式演算法,該方法會保存beamsize個當前的較優選擇,然後解碼時每一步根據保存的選擇進行下一步擴展和排序,接著繼續選擇前beamsize個進行保存,循環迭代,直到結束時選擇最佳的一個作為解碼的結果。

解碼的另一重要改進:注意力機制
Attention Mechanism的提出源自於一個問題。在實際的使用中,隨著輸入序列的增長,模型的性能發生了顯著下降,因為編碼時輸入序列的全部資訊被壓縮到了一個向量表示中,隨著序列增長,句子越前面的詞的資訊丟失就越嚴重。
引入注意力機制就是為了解決上述問題的,在注意力機制中,仍可以用普通的循環神經網路對輸入序列進行編碼,得到隱狀態h1,h2,h3...,但是在解碼時,每一個輸出詞都依賴於前一個隱狀態以及輸入序列每一個對應的隱狀態。
更加直觀的理解,就是我們在生成一個輸出詞時,會考慮每一個輸入詞和當前輸出詞的對齊關係,對齊越好的詞,會有更大的權重,對生成當前輸出詞的影響就越大。

References
[1] 《百面機器學習》第10章
[2] 梯度消失和梯度爆炸問題詳解
http://www.sohu.com/a/332473808_468740
[3] 殘差網路ResNet解讀(原創)
https://blog.csdn.net/docrazy5351/article/details/78993347
[4] 詳解機器學習中的梯度消失、爆炸原因及其解決方法
https://blog.csdn.net/qq_25737169/article/details/78847691
