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