最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

[Quant 1.7] 從數(shù)理的角度理解一下RNN (2)

2022-08-08 11:08 作者:安平生一人好_  | 我要投稿

我先放資源

第一個是MIT的一本深度學(xué)習(xí)教材的RNN章節(jié),作者是Ian Goodfellow & Yoshua Bengio &?Aaron Courville

https://www.deeplearningbook.org/contents/rnn.html#pf7

第二個是吳恩達(dá) (Andrew Ng)博士的網(wǎng)課



吳博士的網(wǎng)課主要從NLP的角度出發(fā)介紹RNN,里面有幫助的理解的例子。但是它的notation我看不太習(xí)慣。然后那本教材我感覺是給更厲害的quant或者數(shù)據(jù)科學(xué)/AI專業(yè)的學(xué)生讀的,細(xì)節(jié)非常之多,我個人啃起來感覺吃力。這篇想把零零散散的知識點總結(jié)一下。(以下內(nèi)容可能有很多理解錯誤的地方,后續(xù)我發(fā)現(xiàn)問題的話會編輯。然后我會有很多中英文穿插著,畢竟面試可能會被問到,我也借這個專欄強化一下記憶。)

4. RNN和它的兩個弱點:梯度消失和梯度爆炸

這一步基本上我見過的所有視頻都會一筆帶過。他們只會講RNN的梯度消失和梯度爆炸會影響SGD optimizer對參數(shù)的更新,從而引出不存在這兩種問題的GRU和LSTM。但我認(rèn)為這部分的推導(dǎo)是整個RNN最高難最有趣的地方。仔細(xì)研究一下不僅能讓你復(fù)習(xí)很多忘掉的數(shù)學(xué),還能對RNN的運行過程有更深刻的理解。


這里我會用上面介紹的第一種RNN來作為例子求梯度。

回憶一下,這是最基本切具有代表性的RNN


我們要求的梯度,就是當(dāng)前的總損失對參數(shù)b%2CU%2CW%2Cc%2CV的梯度。求導(dǎo)的過程要用到我之前兩個專欄的內(nèi)容

所謂backward propogation,就是逆著unfolded computational graph箭頭方向求導(dǎo)的過程。從圖中我們能看出來,想對參數(shù)b%2CU%2CW%2Cc%2CV求梯度,o_t是必經(jīng)之路,所以我們先嘗試求一下總損失Lo_t的梯度,進(jìn)而對h_t的梯度。下一步再求解o_th_t對這5個參數(shù)的梯度。


假設(shè)RNN已經(jīng)訓(xùn)練到了時間%5Ctau,那么當(dāng)前的總損失就是

L%20%3D%20%5Csum%5Climits_%7Bt%7D%5E%7B%5Ctau%7DL_t

Lo_t的梯度可以寫成

%5Cnabla_%7Bo_t%7D%20L%20%3D%20%5Cfrac%7B%5Cpartial%20L%7D%7B%5Cpartial%20L_t%7D%20%5Ccdot%20%5Cnabla_%7B%5Chat%7By%7D_t%7D%20L_t%20%5Ccdot%20%5Cnabla_%7Bo_t%7D%5Chat%7By%7D_t

這個用到了之前說過的鏈?zhǔn)椒▌t。只要我們有關(guān)于梯度輸入和輸出維度的規(guī)定,梯度的鏈?zhǔn)椒▌t和求導(dǎo)的鏈?zhǔn)椒▌t是一致。在等號右邊的三個梯度中,第一個根據(jù)上面的總損失公式就等于1;第二個需要求一個Vector-to-scalar函數(shù)的梯度,因為%5Chat%7By%7D_tL_t的函數(shù)關(guān)系不涉及矩陣運算,我們只能用梯度的定義來求。之前我們假設(shè)我們的RNN用的是交叉熵?fù)p失函數(shù)cross entropy loss function,再假設(shè)RNN的輸出是n維列向量,因此;

%5Cnabla_%7B%5Chat%7By%7D_t%7D%20L_t%20%3D%20(-%5Cfrac%7By_t%5E1%7D%7B%5Chat%7By%7D_t%5E1%7D%20%5Cldots%20-%5Cfrac%7By_t%5En%7D%7B%5Chat%7By%7D_t%5En%7D)

第三個是求一個Vector-to-vector函數(shù)的梯度,我們需要求的是Jacobian矩陣。o_t%5Chat%7By%7D_t的關(guān)系是softmax函數(shù),即

%5Chat%7By%7D_t%5Ei%20%3D%20%5Cfrac%7Be%5E%7Bo_t%5Ei%7D%7D%7B%5Csum%5Climits_%7Bj%3D1%7D%5Ene%5E%7Bo_t%5Ej%7D%7D%20

Jacobian矩陣J%20%5Cin%20%5Cmathbb%7BR%7D%5E%7Bn%5Ctimes%20n%7D的第i行j列可以表示為

J_%7Bij%7D%20%3D%20%5Cleft%5C%7B%0A%5Cbegin%7Barray%7D%7Bll%7D%0A%5Chat%7By%7D_t%5Ei%20-%20(%5Chat%7By%7D_t%5Ei)%5E2%5C%5C%0A-%5Chat%7By%7D_t%5Ei%20%5Chat%7By%7D_t%5Ej%5C%5C%0A%5Cend%7Barray%7D%0A%5Cright.

所以%5Cnabla_%7Bo_t%7D%20L的計算實質(zhì)上是一個1%5Ctimes%20n的梯度向量乘以一個n%20%5Ctimes%20n的Jacobian矩陣

%5Cbegin%7Balign%7D%0A%5Cnabla_%7Bo_t%7D%20L%20%26%3D%20%0A%0A%5Cbegin%7Bpmatrix%7D%0A-%5Cfrac%7By_t%5E1%7D%7B%5Chat%7By%7D_t%5E1%7D%20%5Cldots%20-%5Cfrac%7By_t%5En%7D%7B%5Chat%7By%7D_t%5En%7D%0A%5Cend%7Bpmatrix%7D%0A%0A%5Cbegin%7Bpmatrix%7D%0A%5Chat%7By%7D_t%5E1%20-%20(%5Chat%7By%7D_t%5E1)%5E2%20%26-%5Chat%7By%7D%5E1_t%5Chat%7By%7D%5E2_t%20%26%20%5Cldots%20%26%20-%5Chat%7By%7D%5E1_t%5Chat%7By%7D%5En_t%20%5C%5C%0A-%5Chat%7By%7D%5E2_t%5Chat%7By%7D%5E1_t%20%26%20%5Cddots%20%20%26%20%26%20%5Cvdots%20%5C%5C%0A%5Cvdots%20%26%20%26%20%5Cddots%20%26%20%5Cvdots%5C%5C%0A-%5Chat%7By%7D%5En_t%5Chat%7By%7D%5E1_t%20%26%20%5Cldots%20%26%20%5Cldots%20%26%20%5Chat%7By%7D_t%5En%20-%20(%5Chat%7By%7D_t%5En)%5E2%0A%5Cend%7Bpmatrix%7D%5C%5C%0A%0A%26%3D%0A%5Chat%7By%7D_t%5ET%20-%20y_t%5ET%0A%5Cend%7Balign%7D


我們現(xiàn)在成功獲得了Lo_t上面的梯度,下一步就可以求o_t在別的參數(shù)上的梯度了。


我們先來看h_%5Ctau,?h_%5Ctau只從o_%5Ctau上面遺傳下來。因為RNN中有明確的o_%5Ctau關(guān)于h_%5Ctau的矩陣表達(dá)式,所以我們可以用之前學(xué)過的Vector-to-vector求梯度的方法來計算:

%5Cnabla_%7Bh_%5Ctau%7Do_%5Ctau%20%3D%20V

所以

%5Cnabla_%7Bh_%5Ctau%7DL%20%3D%20(%5Chat%7By%7D_t%5ET%20-%20y_t%5ET)%20%5Ccdot%20V

但是問題來了,h_%5Ctau是只從o_%5Ctau上面遺傳下來,但是h_t不是。從圖中可以看出來,h_t的傳播方向不僅有o_t,還有h_%7Bt%2B1%7D。所以為了鏈?zhǔn)椒▌t能夠連接到h_t,我們需要找到h_%7Bt%2B1%7Dh_t上的梯度

%5Cbegin%7Balign%7D%0A%5Cnabla_%7Bh_t%7Dh_%7Bt%2B1%7D%20%0A%26%20%3D%20diag(tanh.'(b%2BUx_%7Bt%2B1%7D%2BWh_t))%20%5Ccdot%20W%5C%5C%0A%26%20%3D%20diag(1-(h_%7Bt%2B1%7D)%5E2)%20%5Ccdot%20W%20%5Cquad%20%5Ctext%7B%E6%A0%B9%E6%8D%AE%E5%8F%8C%E6%9B%B2%E6%AD%A3%E5%88%87%E5%87%BD%E6%95%B0%E7%9A%84%E5%AF%BC%E5%87%BD%E6%95%B0%7D%5C%2C%20tanh'%20%3D%201%20-%20tanh%5E2%0A%5Cend%7Balign%7D

這個梯度的求解過程可以參考Quant 1.5里面的最后一個例子


因此我們能夠得到關(guān)于h_t梯度的迭代公式

%5Cbegin%7Balign%7D%0A%5Cnabla_%7Bh_t%7D%20L%20%26%3D%20%5Cnabla_%7Bo_t%7D%20L%20%5Ccdot%20%20%5Cnabla_%7Bh_t%7D%20o_t%20%2B%20%20%5Cnabla_%7Bh_%7Bt%2B1%7D%7D%20L%20%5Ccdot%20%20%5Cnabla_%7Bh_t%7D%20h_%7Bt%2B1%7D%5C%5C%0A%26%3D%20(%5Chat%7By%7D_t%5ET%20-%20y_t%5ET)%5Ccdot%20V%20%2B%20%5Cnabla_%7Bh_%7Bt%2B1%7D%7D%20L%20%5Ccdot%20diag(1-(h_%7Bt%2B1%7D)%5E2)%20%5Ccdot%20W%0A%0A%5Cend%7Balign%7D

我們逐步迭代,直到t%2B1%20%3D%20%5Ctau,我們就能獲得L關(guān)于h_t梯度的確定的值。


所有的準(zhǔn)備工作都做完了,我們現(xiàn)在獲得了關(guān)于o_th_t的全部梯度,需要繼續(xù)利用鏈?zhǔn)椒▌t求b%2CU%2CW%2Cc%2CV的梯度:

%5Cbegin%7Balign%7D%0A%5Cnabla_b%20L%20%26%3D%20%20%5Csum%5Climits_%7Bt%7D%5E%5Ctau%20%5Cnabla_%7Bh_t%7DL%20%5Ccdot%20%5Cnabla_b%20h_t%5C%5C%0A%26%20%3D%20%5Csum%5Climits_%7Bt%7D%5E%5Ctau%20%5Cnabla_%7Bh_t%7DL%20%5Ccdot%20diag(1-(h_t)%5E2)%5C%5C%0A%5C%5C%0A%5Cnabla_c%20L%20%26%3D%20%5Csum%5Climits_t%5E%5Ctau%20%5Cnabla_%7Bo_t%7DL%20%5Ccdot%20%5Cnabla_%7Bc%7Do_t%5C%5C%0A%26%3D%20%5Csum%5Climits_t%5E%5Ctau%20%5Cnabla_%7Bo_t%7DL%0A%5Cend%7Balign%7D

多說一句以防大家忘記,這里的鏈?zhǔn)椒▌t的情形比前面的要復(fù)雜一些。之前例子中的鏈?zhǔn)椒▌t都是單鏈的,也就是說從復(fù)合函數(shù)的自變量變換到因變量的過程只有一個路徑,但是在RNN中時間t的存在使得b%2CU%2CW%2Cc%2CV到損失L的變換在每一個時間t都有一條平行的路徑。多鏈的鏈?zhǔn)椒▌t需要我們把每個平行路徑的梯度加和來求總梯度。


然后上面我們已經(jīng)求的了五個梯度中最簡單的兩個。但是在求另外三個的時候就會遇到一個問題...按照正常的鏈?zhǔn)椒▌t,求關(guān)于U的梯度的時候應(yīng)該有

%5Cnabla_U%20L%20%3D%20%5Csum%5Climits_t%5E%5Ctau%20%5Cnabla_%7Bh_t%7D%20L%20%5Ccdot%20%5Cnabla_U%20h_t

但是根據(jù)我目前學(xué)到的知識,這個我是算不出來的,因為%20%5Cnabla_U%20h_t是一個Matrix-to-vector函數(shù)的梯度,首先它的梯度求出來應(yīng)該是一個三維tensor的形式,其次即使它的梯度有矩陣的表達(dá)形式,但是我認(rèn)為這種表達(dá)形式放入chain rule進(jìn)行計算是錯誤的。因此,上面的梯度無法這么求。


那我們應(yīng)該怎么辦呢?我們雖然不確定Matrix-to-vector函數(shù)的梯度能不能插入鏈?zhǔn)椒▌t里面,但是我們能確定Matrix-to-scalar函數(shù)肯定是可以的!那我們可以不可以修改一下路徑,使得由h_tU的梯度變成Matrix-to-vector函數(shù)的梯度呢?可以!我們只要把h_t的每一項拿出來作為中間項過度就可以了。大致變化差不多下面這張圖,需要把h_t展開:

最后按照右邊的圖片,關(guān)于U的梯度就變成了

%5Cbegin%7Balign%7D%0A%5Cnabla_UL%20%3D%20%5Csum%5Climits_t%5E%5Ctau%20%5Csum%5Climits_%7Bi%3D1%7D%5En%20%5Cfrac%7B%5Cpartial%20L%7D%7B%5Cpartial%20h_t%5Ei%7D%20%20%5Cnabla_U%20h_t%5Ei%0A%0A%5Cend%7Balign%7D

接下來是全篇最蹩腳的地方:如何化簡上面的等式?首先我們要求一個Matrix-to-scalar函數(shù)的梯度

%20%5Cnabla_U%20h_t%5Ei%0A

這個就不是很好理解。我們先看一下矩陣U變換到h_t%5Ei的過程:第一步對于矩陣U進(jìn)行線性變換b%2BUx_t%2BWh_%7Bt-1%7D,對得到的向量只保留第i項a%5Ei_t,第二部是h_t%5Ei%20%3D%20tanh(a%5Ei_t)。所以根據(jù)鏈?zhǔn)椒▌t:

%5Cbegin%7Balign%7D%20%0A%5Cnabla_U%20h_t%5Ei%20%26%3D%20%5Cfrac%7B%5Cpartial%20h_t%5Ei%7D%7B%5Cpartial%20a_t%5Ei%7D%20%5Ctimes%20%5Cnabla_U%20a_t%5Ei%5C%5C%0A%26%3D%20(1%20-%20(h%5Ei_t)%5E2)%20%5Ctimes%20%0A%5Cbegin%7Bpmatrix%7D%0A%5Cmathbf%7B0%7D%5C%5C%0A%5Cvdots%5C%5C%0Ax_t%5ET%5C%5C%0A%5Cvdots%5C%5C%0A%5Cmathbf%7B0%7D%0A%5Cend%7Bpmatrix%7D%20%5C%2C%5C%2C%5C%2C%20%5Ctext%7Bwith%20the%20i-th%20row%7D%20%5C%2C%20%5C%2C%20x_t%5ET%0A%5Cend%7Balign%7D

關(guān)于后面這個Matrix-to-scalar函數(shù)的梯度,因為這個函數(shù)里面的沒有trace,所以我們只能通過Matrix-to-scalar函數(shù)梯度的定義來理解了。因為我們最后只取向量的第i項,所以矩陣U只有第i行和a_t%5Ei有關(guān)系。將a_t%5Ei對矩陣U的第i行各項求導(dǎo),得到的就是向量x_t每一項。因此,得到的梯度矩陣除了第i行是x_t%5ET以外,其余項都是0。


下一步依然是難理解的一步,我們想要取消內(nèi)部的求和符號就需要把所有%20%5Cnabla_U%20h_t%5Ei關(guān)于i都加起來:

%5Cbegin%7Balign%7D%0A%26%5Csum%5Climits_%7Bi%3D1%7D%5En%20%5Cfrac%7B%5Cpartial%20L%7D%7B%5Cpartial%20h_t%5Ei%7D%20%20%5Cnabla_U%20h_t%5Ei%5C%5C%20%0A%3D%26%20%5Csum%5Climits_%7Bi%3D1%7D%5En%20%5Cfrac%7B%5Cpartial%20L%7D%7B%5Cpartial%20h_t%5Ei%7D%20(1%20-%20(h%5Ei_t)%5E2)%20%5Ctimes%20%0A%5Cbegin%7Bpmatrix%7D%0A%5Cmathbf%7B0%7D%5C%5C%0A%5Cvdots%5C%5C%0Ax_t%5ET%5C%5C%0A%5Cvdots%5C%5C%0A%5Cmathbf%7B0%7D%0A%5Cend%7Bpmatrix%7D%20%5C%2C%5C%2C%5C%2C%20%5Ctext%7Bwith%20the%20i-th%20row%7D%20%5C%2C%20%5C%2C%20x_t%5ET%5C%5C%0A%3D%26%20%0A%5Cbegin%7Bpmatrix%7D%0A%5B1%20-%20(h_t%5E1)%5E2%5D%5Cfrac%7B%5Cpartial%20L%7D%7B%5Cpartial%20h_t%5E1%7D%20%5C%5C%0A%5Cvdots%5C%5C%0A%5B1%20-%20(h_t%5En)%5E2%5D%5Cfrac%7B%5Cpartial%20L%7D%7B%5Cpartial%20h_t%5En%7D%0A%5Cend%7Bpmatrix%7D%0A%5Cbegin%7Bpmatrix%7D%0Ax_1%20%26%20%5Cldots%20%26%20x_n%0A%5Cend%7Bpmatrix%7D%5C%5C%0A%0A%3D%20%26%0A%5Cbegin%7Bpmatrix%7D%0A1%20-%20(h_t%5E1)%5E2%20%5C%5C%0A%5Cvdots%5C%5C%0A1%20-%20(h_t%5En)%5E2%0A%5Cend%7Bpmatrix%7D%0A%5Ctimes%0A%5Cbegin%7Bpmatrix%7D%0A%5Cfrac%7B%5Cpartial%20L%7D%7B%5Cpartial%20h_t%5E1%7D%20%5C%5C%0A%5Cvdots%5C%5C%0A%5Cfrac%7B%5Cpartial%20L%7D%7B%5Cpartial%20h_t%5En%7D%0A%5Cend%7Bpmatrix%7D%0A%5Ccdot%0A%5Cbegin%7Bpmatrix%7D%0Ax_1%20%26%20%5Cldots%20%26%20x_n%0A%5Cend%7Bpmatrix%7D%5C%5C%0A%3D%26%20diag(1-(h_t)%5E2)%20%5Ccdot%20(%5Cnabla_%7Bh_t%7D%20L)%5ET%20x%5ET_t%0A%5Cend%7Balign%7D

所以

%5Cnabla_UL%20%3D%20%5Csum%5Climits_t%5E%5Ctau%20%0Adiag(1-(h_t)%5E2)%20%5Ccdot%20(%5Cnabla_%7Bh_t%7D%20L)%5ET%20x%5ET_t%0A

如果線代學(xué)的不是特別好的話,從求和符號到矩陣乘法之間的轉(zhuǎn)換可能需要比較長的時間消化,這里大家可以多總結(jié)一下。


然后關(guān)于矩陣W%2C%20V的梯度和U十分類似,我就不再推一遍了

%5Cbegin%7Balign%7D%0A%5Cnabla_WL%20%26%3D%20%5Csum%5Climits_t%5E%5Ctau%20%0Adiag(1-(h_t)%5E2)%20%5Ccdot%20(%5Cnabla_%7Bh_t%7D%20L)%5ET%20h%5ET_t%5C%5C%0A%5Cnabla_VL%20%26%3D%20%5Csum%5Climits_t%5E%5Ctau%20(%5Cnabla_%7Bo_t%7DL)%5ET%20h_t%5ET%0A%5Cend%7Balign%7D


梯度求完了,我們現(xiàn)在要討論的是梯度為什么會消失 (gradient vanishing),梯度又為什么會爆炸 (gradient exploding)。我在網(wǎng)上能找到的所有視頻關(guān)于這兩點都是泛泛而談,包括上面的教材和視頻,沒有一個解釋的很詳細(xì)的,我感覺很無語。所以這里試著解釋一下:


我們從上面一系列的梯度的推導(dǎo)中可以看出,每一個time step對參數(shù)的梯度都是有貢獻(xiàn)的。但是如果我們的神經(jīng)網(wǎng)絡(luò)深度足夠大的話,早期的time step對梯度的貢獻(xiàn)會過小或者過大。這就是梯度消失/爆炸。


難道早期的time step對梯度的貢獻(xiàn)小不是應(yīng)該的嗎?不一定!吳教授的視頻中舉了一個例子,假如我們現(xiàn)在想要預(yù)測一句不完整的話的下一個詞是什么:

The cats, which already ate,?were?full.

The cat, which already ate,?was full.

我們在預(yù)測這個was/were的時候,最重要的參考信息不是中間的非限制性定語從句,而是前面的cat/cats。因此,模型參數(shù)應(yīng)該在cat/cats這個詞對應(yīng)time step的hidden state上面的梯度很大,從而可以顯著的修改神經(jīng)網(wǎng)絡(luò)中的矩陣參數(shù)。然而,如果這個cat/cats離was/were太遠(yuǎn)了,這個梯度就會產(chǎn)生爆炸或者消失,導(dǎo)致我們最后訓(xùn)練出來的神經(jīng)網(wǎng)絡(luò)參數(shù)沒有預(yù)測價值。畢竟語法上非限制性定語從句可以無限長。


那么如何從梯度的公式上理解梯度消失和梯度爆炸呢?根據(jù)我們之前推導(dǎo)過的梯度公式,可以知道損失函數(shù)關(guān)于各個矩陣/向量參數(shù)的梯度大多與%5Cnabla_%7Bh_t%7D%20L有關(guān)系,而%5Cnabla_%7Bh_t%7D%20L還有遞推公式:

%0A%5Cnabla_%7Bh_t%7D%20L%20%0A%3D%20(%5Chat%7By%7D_t%5ET%20-%20y_t%5ET)%5Ccdot%20V%20%2B%20%5Cnabla_%7Bh_%7Bt%2B1%7D%7D%20L%20%5Ccdot%20diag(1-(h_%7Bt%2B1%7D)%5E2)%20%5Ccdot%20W

我們多寫出來一步

%5Cbegin%7Balign%7D%0A%5Cnabla_%7Bh_%7Bt-1%7D%7DL%20%3D%20%26(%5Chat%7By%7D_%7Bt-1%7D%5ET-y_%7Bt-1%7D%5ET)%5Ccdot%20V%20%2B%20(%5Chat%7By%7D_t%5ET%20-%20y_t%5ET)%5Ccdot%20V%5Ccdot%20diag(1-(h_t)%5E2)%5Ccdot%20W%5C%5C%0A%2B%26%20%5Cnabla_%7Bh_%7Bt%2B1%7D%7DL%20%5Ccdot%20diag(1-(h_%7Bt%2B1%7D)%5E2)%20%5Ccdot%20W%20%5Ccdot%20diag(1-(h_t)%5E2)%5Ccdot%20W%0A%0A%5Cend%7Balign%7D

這是兩個time step的遞推公式,我們可以知道當(dāng)time step的間隔足夠大的時候,多個W矩陣會累乘到一起作為晚期time step梯度的系數(shù)。這就導(dǎo)致早期的time step梯度受矩陣W的影響很大。就像是1.01%5E%7B100%7D0.99%5E%7B100%7D差距很大一樣,梯度下降的進(jìn)程會受參數(shù)初始化的影響,如果W初始化太大會造成梯度爆炸,太小則會造成梯度消失。


[Quant 1.7] 從數(shù)理的角度理解一下RNN (2)的評論 (共 條)

分享到微博請遵守國家法律
于田县| 陕西省| 克拉玛依市| 金华市| 扎囊县| 峡江县| 永仁县| 拉萨市| 淳化县| 庆阳市| 临潭县| 自贡市| 哈密市| 安顺市| 开平市| 如东县| 赤水市| 南汇区| 桂林市| 福安市| 普定县| 美姑县| 绩溪县| 平武县| 漳平市| 东兰县| 河北区| 淅川县| 彩票| 永顺县| 阿荣旗| 长寿区| 婺源县| 九龙县| 盱眙县| 济阳县| 兰考县| 拜城县| 新沂市| 庆安县| 乌拉特中旗|