RNN,也就是Recurrent Neural Network,循環神經網絡,是非線性動態系統,將序列映射到序列,主要參數有五個:[Whv, Whh, Woh, bh, bo, h0] ,典型的結構圖如下:
解釋一下上圖:
- 和普通神經網絡一樣,RNN有輸入層輸出層和隱含層,不一樣的是RNN在不同的時間t會有不同的狀態,其中t-1時刻隱含層的輸出會作用到t時刻的隱含層
- [Whv, Whh, Woh, bh, bo, h0]的參數意義是: Whv:輸入層到隱含層的權重參數,Whh:隱含層到隱含層的權重參數,Woh:隱含層到輸出層的權重參數,bh:隱含層的偏移量,bo輸出層的偏移量,h0:起始狀態的隱含層的輸出,一般初始爲0
- 不同時間的狀態共享相同的權重w和偏移量b
RNN的計算方式:
之前看過了一般神經網絡和CNN,再看RNN其實覺得結構並不複雜, 計算過程看起來的話,RNN的計算方式和普通的前饋算法也沒有什麼大的區別,不過是上一時刻的隱含層的輸出結果又在現在時刻的計算過程裏面用到了,也就是不斷傳遞的過程,這也就是爲什麼RNN是從序列到序列,一個狀態的出入和前面幾個狀態的輸出都有關係。
給定一個損失函數L:
當然不同的神經網絡對應的訓練方法也不一樣, RNN因爲加入了時間序列,因此訓練過程也是和之前的網絡不一樣,RNN的訓練使用的是BPTT(Back Prropagation Through TIme),該方法是由Werbo等人在1990年弄出來的
具體的訓練過程如下:
上面的算法也就是求解梯度的過程,使用的也是經典的BP算法,並沒有什麼新鮮的,但是值得一提的是,在 t-1 時刻對 ht−1的求導值,也需加上 t 時刻的求導中對 ht−1 的求導值,因此BPTT也是一個鏈式的求導過程。
但是因爲上面算法中的第10行,在訓練t時刻的時候,出現了t-1的參數,因此對單個的求導就變成了對整個之前狀態的求導之和,比如說我們在T時刻對Whh求導,計算公式如下:
也正是因爲存在長依賴關係,BPTT無法解決長時依賴問題(即當前的輸出與前面很長的一段序列有關,一般超過十步就無能爲力了),因爲BPTT會帶來所謂的梯度消失或梯度爆炸問題(the vanishing/exploding gradient problem)。這篇文章很好的解釋了爲什麼會產生梯度消失和爲什麼會梯度爆炸的問題,其實主要問題就是因爲在BPTT算法中,以w爲例,其求導過程的鏈太長,而太長的求導鏈在以tanh爲激活函數(其求導值在0~1之間的BPTT中,連乘就會使得最終的求導爲0,這就是梯度消失問題,也就是t時刻已經學習不到t-N時刻的參數了。當然,有很多方法去解決這個問題,如LSTMs便是專門應對這種問題的,還有一些方法,比如設計一個更好的初始參數以及更換激活函數(如換成ReLU激活函數)。
以上就是經典的RNN模型以及推導過程,最近幾年依賴RNN有了很多的變體和拓展,詳見:RNNs擴展和改進模型
參考文獻:
【1】SutskEver,Training Recurrent Neural Networks.PhD thesis,Univ.Toronto(2012)
【2】循環神經網絡(RNN, Recurrent Neural Networks)介紹