DNN:LSTM的前向计算和参数训练
原文-LSTM的反向傳播:深度學習(6)-長短期網路;此處僅摘抄一小段,建議拜訪全文。
LSTM的參數訓練:https://www.jianshu.com/p/dcec3f07d3b5;LSTM的參數訓練和前向計算比RNNs還是稍微復雜一些。
長短時記憶網絡的前向計算
前面描述的開關是怎樣在算法中實現的呢?這就用到了門(gate)的概念。門實際上就是一層全連接層,它的輸入是一個向量,輸出是一個0到1之間的實數向量。假設W是門的權重向量,b是偏置項,那么門可以表示為:
門的使用,就是用門的輸出向量按元素乘以我們需要控制的那個向量。因為門的輸出是0到1之間的實數向量,那么,當門輸出為0時,任何向量與之相乘都會得到0向量,這就相當于啥都不能通過;輸出為1時,任何向量與之相乘都不會有任何改變,這就相當于啥都可以通過。因為(也就是sigmoid函數)的值域是(0,1),所以門的狀態都是半開半閉的。
LSTM用兩個門來控制單元狀態c的內容,一個是遺忘門(forget gate),它決定了上一時刻的單元狀態有多少保留到當前時刻;另一個是輸入門(input gate),它決定了當前時刻網絡的輸入有多少保存到單元狀態。LSTM用輸出門(output gate)來控制單元狀態有多少輸出到LSTM的當前輸出值。
我們先來看一下遺忘門:
上式中,是遺忘門的權重矩陣,表示把兩個向量連接成一個更長的向量,是遺忘門的偏置項,是sigmoid函數。如果輸入的維度是,隱藏層的維度是,單元狀態的維度是(通常),則遺忘門的權重矩陣維度是。事實上,權重矩陣都是兩個矩陣拼接而成的:一個是,它對應著輸入項,其維度為;一個是,它對應著輸入項,其維度為。可以寫為:
下圖顯示了遺忘門的計算:
接下來看看輸入門:
上式中,是輸入門的權重矩陣,是輸入門的偏置項。下圖表示了輸入門的計算:
接下來,我們計算用于描述當前輸入的單元狀態,它是根據上一次的輸出和本次輸入來計算的:
下圖是的計算:
現在,我們計算當前時刻的單元狀態。它是由上一次的單元狀態按元素乘以遺忘門,再用當前輸入的單元狀態按元素乘以輸入門,再將兩個積加和產生的:
符號o表示按元素乘。下圖是的計算:
這樣,我們就把LSTM關于當前的記憶和長期的記憶組合在一起,形成了新的單元狀態。由于遺忘門的控制,它可以保存很久很久之前的信息,由于輸入門的控制,它又可以避免當前無關緊要的內容進入記憶。下面,我們要看看輸出門,它控制了長期記憶對當前輸出的影響:
下圖表示輸出門的計算:
LSTM最終的輸出,是由輸出門和單元狀態共同確定的:
下圖表示LSTM最終輸出的計算:
式1到式6就是LSTM前向計算的全部公式。至此,我們就把LSTM前向計算講完了。
?
長短時記憶網絡的訓練
熟悉我們這個系列文章的同學都清楚,訓練部分往往比前向計算部分復雜多了。LSTM的前向計算都這么復雜,那么,可想而知,它的訓練算法一定是非常非常復雜的。現在只有做幾次深呼吸,再一頭扎進公式海洋吧。
LSTM訓練算法框架
LSTM的訓練算法仍然是反向傳播算法,對于這個算法,我們已經非常熟悉了。主要有下面三個步驟:
關于公式和符號的說明
首先,我們對推導中用到的一些公式、符號做一下必要的說明。
接下來的推導中,我們設定gate的激活函數為sigmoid函數,輸出的激活函數為tanh函數。他們的導數分別為:
從上面可以看出,sigmoid和tanh函數的導數都是原函數的函數。這樣,我們一旦計算原函數的值,就可以用它來計算出導數的值。
LSTM需要學習的參數共有8組,分別是:遺忘門的權重矩陣和偏置項、輸入門的權重矩陣和偏置項、輸出門的權重矩陣和偏置項,以及計算單元狀態的權重矩陣和偏置項。因為權重矩陣的兩部分在反向傳播中使用不同的公式,因此在后續的推導中,權重矩陣都將被寫為分開的兩個矩陣:、。
我們解釋一下按元素乘符號o。當o作用于兩個向量時,運算如下:
當o作用于一個向量和一個矩陣時,運算如下:
當o作用于兩個矩陣時,兩個矩陣對應位置的元素相乘。按元素乘可以在某些情況下簡化矩陣和向量運算。例如,當一個對角矩陣右乘一個矩陣時,相當于用對角矩陣的對角線組成的向量按元素乘那個矩陣:
當一個行向量右乘一個對角矩陣時,相當于這個行向量按元素乘那個矩陣對角線組成的向量:
上面這兩點,在我們后續推導中會多次用到。
在t時刻,LSTM的輸出值為。我們定義t時刻的誤差項為:
注意,和前面幾篇文章不同,我們這里假設誤差項是損失函數對輸出值的導數,而不是對加權輸入的導數。因為LSTM有四個加權輸入,分別對應,我們希望往上一層傳遞一個誤差項而不是四個。但我們仍然需要定義出這四個加權輸入,以及他們對應的誤差項。
誤差項沿時間的反向傳遞
沿時間反向傳遞誤差項,就是要計算出t-1時刻的誤差項。
我們知道,是一個Jacobian矩陣。如果隱藏層h的維度是N的話,那么它就是一個矩陣。為了求出它,我們列出的計算公式,即前面的式6和式4:
顯然,都是的函數,那么,利用全導數公式可得:
下面,我們要把式7中的每個偏導數都求出來。根據式6,我們可以求出:
根據式4,我們可以求出:
因為:
我們很容易得出:
將上述偏導數帶入到式7,我們得到:
根據的定義,可知:
式8到式12就是將誤差沿時間反向傳播一個時刻的公式。有了它,我們可以寫出將誤差項向前傳遞到任意k時刻的公式:
將誤差項傳遞到上一層
我們假設當前為第l層,定義l-1層的誤差項是誤差函數對l-1層加權輸入的導數,即:
?
本次LSTM的輸入由下面的公式計算:
上式中,表示第l-1層的激活函數。
因為都是的函數,又是的函數,因此,要求出E對的導數,就需要使用全導數公式:
式14就是將誤差傳遞到上一層的公式。
?
權重梯度的計算
對于的權重梯度,我們知道它的梯度是各個時刻梯度之和(證明過程請參考文章零基礎入門深度學習(5) - 循環神經網絡),我們首先求出它們在t時刻的梯度,然后再求出他們最終的梯度。
我們已經求得了誤差項,很容易求出t時刻的:
將各個時刻的梯度加在一起,就能得到最終的梯度:
對于偏置項的梯度,也是將各個時刻的梯度加在一起。下面是各個時刻的偏置項梯度:
下面是最終的偏置項梯度,即將各個時刻的偏置項梯度加在一起:
對于的權重梯度,只需要根據相應的誤差項直接計算即可:
以上就是LSTM的訓練算法的全部公式。因為這里面存在很多重復的模式,仔細看看,會發覺并不是太復雜。
當然,LSTM存在著相當多的變體,讀者可以在互聯網上找到很多資料。因為大家已經熟悉了基本LSTM的算法,因此理解這些變體比較容易,因此本文就不再贅述了。
?
長短時記憶網絡的實現
完整代碼請參考GitHub:?https://github.com/hanbt/learn_dl/blob/master/lstm.py?(python2.7)
在下面的實現中,LSTMLayer的參數包括輸入維度、輸出維度、隱藏層維度,單元狀態維度等于隱藏層維度。gate的激活函數為sigmoid函數,輸出的激活函數為tanh。
激活函數的實現
我們先實現兩個激活函數:sigmoid和tanh。
class SigmoidActivator(object):def forward(self, weighted_input):return 1.0 / (1.0 + np.exp(-weighted_input))def backward(self, output):return output * (1 - output) class TanhActivator(object):def forward(self, weighted_input):return 2.0 / (1.0 + np.exp(-2 * weighted_input)) - 1.0def backward(self, output):return 1 - output * outputLSTM初始化、前向計算、反向傳播(誤差項、梯度項)、梯度下降法、梯度檢查Python代碼的實現;
請繼續參考原文:
https://zybuluo.com/hanbingtao/note/581764
?
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的DNN:LSTM的前向计算和参数训练的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 方舟翼龙怎么驯服 方舟无齿翼龙怎么驯服
- 下一篇: OpenCV:OpenCV4.0更新