1. 引入
我們可以在[1]中,看到RNN的結構,如下圖所示。
假設我們輸入兩個句子如下:
- The cat, which already xxx yyy zzz …, was full.
- The cats, which alrady xxx yyy zzz …, were full.
這兩句話中,“xxx yyy zzz …”表示句子中間有很長的文本,此處略去。我們只看單數與複數,最後一個逗號後,也要對應was和were。我們期望RNN網絡能學到這種單數複數的語法。
但是由於句子太長了,而RNN本身是不擅長捕捉這種長期依賴效應(very long-term dependencies)的。
這是爲什麼呢?
2. 梯度消失
在文章[3]中,我們解釋過一種情況:普通的多層神經網絡中,如果網絡深度很深,則“激活函數將會成指數級遞增”,最終導致在反向傳播過程中梯度很難向前傳遞,也就是“梯度消失”。這就是從y輸出的梯度,很難傳播回去。
RNN也具有同樣的問題,各個時刻激活函數的輸出值a累乘到一起,傳到靠後的時刻後,值已經很小了,在反向傳播過程中,就很容易出現“梯度消失”。
所以,需要在序列後面生成單複數was或were,也是比較困難的,因爲前面序列傳過來的a,可能到後面就消失了。
正因如此,輸出序列某個值,是比較容易受到附近值的影響,但不容易受到離他很遠的值的影響。比如y<10>,容易被x<9>,x<8>,x<7>影響到,但不容易被x<2>影響到。
3. 梯度爆炸
除了“梯度消失”,RNN訓練過程中也可能遇到“梯度爆炸”。但對RNN來說,“梯度消失”更嚴重。爲什麼呢?
因爲“梯度爆炸”會導致你的網絡參數大到崩潰,所以“梯度爆炸”更容易被發現。“梯度爆炸”時,你可以觀測到網絡參數出現數值溢出(數據過大)。
出現“梯度爆炸”時,可以用梯度修剪
的方法來解決:
- 觀察梯度向量,如果它大於某個閾值,就縮放梯度向量,保證它不會太大。
這種梯度修剪
法,相對是比較魯棒的方法。而梯度消失則很難解決。
4. 總結
在訓練很深的神經網絡時,隨着層數的增加,導數可能呈指數型的下降或增加,所以我們會遇到“梯度消失”(使得你的網絡無法捕獲長期依賴)或“梯度爆炸”。
如果一個RNN處理10000個值的序列,這就是一個10000個層的神經網絡(因爲前面時刻激活函數的輸出值a會不斷疊加到後面時刻)。
其中,“梯度爆炸”問題用梯度修剪
法基本就能解決。但“梯度消失”則很難解決(可以用GRU來解決,後面再介紹,門控循環單元網絡)。
參考
- [1]. 理解RNN的結構+特點+計算公式. https://blog.csdn.net/ybdesire/article/details/103449597
- [2]. 序列模型用途介紹及數學符號. https://blog.csdn.net/ybdesire/article/details/102963683
- [3]. 深度學習中的梯度消失與梯度爆炸. https://blog.csdn.net/ybdesire/article/details/79618727
- [4]. Andrew Ng Sequence Models video