RNN Tutorial Part3 -- BPTT

RNN Tutorial Part3 -- BPTT

這篇專欄主要參考 Recurrent Neural Networks Tutorial, Part 3 – Backpropagation Through Time and Vanishing Gradients,同時給出了 Loss 函數對參數 V 求導的詳細過程。如果有寫錯或不明白的地方,歡迎在評論區留言,我將竭盡所能地回答大家的寶貴評論。

這部分主要介紹損失函數對參數V的求導,涉及到的知識點(敲黑板!)包括矩陣求導的技巧求導鏈式的確定softmax函數的求導

首先回顧一下模型:

s_t = 	ext{tanh}(U x_t + W s_{t-1}) \ hat{y_t} = 	ext{softmax}(V s_t)

x_tt 時刻的輸入,s_ts_{t-1} 分別為 tt-1 時刻的 hidden state,y_t 為 t 時刻的輸出。UWV 是模型的參數,並且這些參數在所有時刻都是共享的。

這裡我們使用的是 cross entropy loss,定義如下:

E_t(y_t, hat{y_t}) = - y_t log hat{y_t}

E(y, hat{y}) = sumlimits_t E_t(y_t, hat{y_t}) = - sumlimits_t y_t log hat{y_t}

y_tt 時刻的正確單詞,它是一個 C 維的 one-hot vector,C 是詞表的大小。hat{y_t} 是 C 維的預測輸出,每個維度表示對應單詞的概率。我們通常把一個句子當做一個訓練樣例,每個訓練樣例的總 loss 定義成每個時刻 loss 的求和。同理,我們把每個時刻 loss 函數對參數的梯度加起來,得到總 loss 對該參數的梯度,例如 frac{partial E}{partial W} = sumlimits_t frac{partial E_t}{partial W}

這裡我們只計算 frac{partial E_3}{partial V},其它導數的計算可以同理得到。參數 VC 	imes H 維的矩陣,對矩陣直接求導數是超出我們一般人的理解的,因此我們考慮對矩陣裡面的每一個元素 V_{ij} 求導,然後組合得到對矩陣的導數。接下來我們確定從 E_3V_{ij} 的鏈式求導路徑。

V_{ij} 的誤差傳播到 z_3,且只會傳播給 z_{3, i},其中 z_{3, i} = sumlimits_j V_{ij} cdot s_jz_{3, i} 可以通過 softmax 將誤差傳播到 hat{y_3} 的所有維度。但因為 y_3 是 one-hot vector,E_3 = - y_3 log hat{y_3},所以 hat{y_3} 只有一個維度的誤差會傳播到 E_3,這裡假設是第 K 個維度的值,所以 E_3 = - log hat{y_{3, k}}。由上面的分析,我們可以寫出鏈式求導路徑如下:

frac{partial E_3}{partial V_{ij}} = frac{partial E_3}{partial hat{y_{3, k}}} cdot frac{partial hat{y_{3, k}}}{partial e^{z_{3, i}}} cdot frac{partial e^{z_{3, i}}}{partial z_{3, i}} cdot frac{partial z_{3, i}}{partial V_{ij}}

	ext{其中} ;; hat{y_{3, k}} = 	ext{softmax}(z_{3, k}) = frac{e^{z_{3, k}}}{sum_{c=1}^C e^{z_{3, c}}}

然後我們可以得到鏈式求導路徑的各分量如下:

frac{partial E_3}{partial hat{y_{3, k}}} = - frac{1}{hat{y_{3, k}}}

frac{partial e^{z_{3, i}}}{partial z_{3, i}} = e^{z_{3, i}}

frac{partial z_{3, i}}{partial V_{ij}} = s_j

i=k

frac{partial hat{y_{3, k}}}{partial e^{z_{3, i}}} = frac{sum_{c=1}^C e^{z_{3, c}} - e^{z_{3, k}}}{left(sum_{c=1}^C e^{z_{3, c}}
ight)^2}

所以

egin{align} frac{partial E_3}{partial V_{ij}} & = frac{partial E_3}{partial hat{y_{3, k}}} cdot frac{partial hat{y_{3, k}}}{partial e^{z_{3, i}}} cdot frac{partial e^{z_{3, i}}}{partial z_{3, i}} cdot frac{partial z_{3, i}}{partial V_{ij}} 
otag \ & = -frac{sum_{c=1}^C e^{z_{3, c}}}{e^{z_{3, k}}} cdot frac{sum_{c=1}^C e^{z_{3, c}} - e^{z_{3, k}}}{left(sum_{c=1}^C e^{z_{3, c}}
ight)^2} cdot e^{z_{3, i}} cdot s_j 	ag{1} \ &= - frac{sum_{c=1}^C e^{z_{3, c}} - e^{z_{3, k}}}{sum_{c=1}^C e^{z_{3,c}}} cdot s_j  	ag{2} \ & = (hat{y_{3, k}} - y_{3, k}) cdot s_j 	ag{3}end{align}

在 (1) ? (2) 的過程中,我們約去了 sum_{c=1}^C e^{z_{3, c}}e^{z_{3, i}} (i=k) 。在 (2) ? (3) 的過程中,當 i=k 時,y_{3,k} = 1

i 
eq k 時,

frac{partial hat{y_{3, k}}}{partial e^{z_{3, i}}} = frac{0 - e^{z_{3, k}}}{left(sum_{c=1}^C e^{z_{3, c}}
ight)^2}

所以

egin{align} frac{partial E_3}{partial V_{ij}} & = frac{partial E_3}{partial hat{y_{3, k}}} cdot frac{partial hat{y_{3, k}}}{partial e^{z_{3, i}}} cdot frac{partial e^{z_{3, i}}}{partial z_{3, i}} cdot frac{partial z_{3, i}}{partial V_{ij}} 
otag \ & = -frac{sum_{c=1}^C e^{z_{3, c}}}{e^{z_{3, k}}} cdot frac{0 - e^{z_{3, k}}}{left(sum_{c=1}^C e^{z_{3, c}}
ight)^2} cdot e^{z_{3, i}} cdot s_j 	ag{4} \ &= frac{e^{z_{3, i}}}{sum_{c=1}^C e^{z_{3,c}}} cdot s_j  	ag{5} \ & = (hat{y_{3, i}} - y_{3, i}) cdot s_j 	ag{6}end{align}

在 (4) ? (5) 的過程中,我們約去了 sum_{c=1}^C e^{z_{3, c}}e^{z_{3, k}} 。在 (2) ? (3) 的過程中,當 i 
eq k 時,y_{3,k} = 0

綜合 (3) 和 (6),我們可以得到

frac{partial E_3}{partial V_{ij}} = (hat{y_{3, i}} - y_{3, i}) cdot s_j

寫成向量的表達形式是

frac{partial E_3}{partial V} = (hat{y_3}-y_3) otimes s

otimes 表示兩個向量間的 outer product。


推薦閱讀:

TAG:深度學習DeepLearning | 機器學習 | 神經網路 |