主要是個人備忘錄,很不完整和規范。
基本都省略了偏置。
簡單RNN
數學公式
\[h_{t}=g(W^{(h)}h_{t-1}+W^{(x)}x_t) \\ y_{t}=f(Vh_t) \]
簡單解釋就是,對於每個位置,輸入保存的上一個狀態 \(h_{t - 1}\)和輸入\(x_t\),然后輸出新的狀態\(h_t\),這個操作一般是線性變換再接一個激活函數,比如\(tanh,sigmoid\),然后傳遞新狀態和利用新的狀態\(s_t\)輸出定義的\(y_t\),比如\(softmax\)啥的。
反向傳播
為了標記簡介,將兩個上面的式子寫成一個矩陣的形式,即
\[h_t = g(W[h_{t-1};x_t]) \]
展開計算圖大概是下面這樣

則
\[\frac{\partial L}{\partial \mathbf{W}}=\sum_{j=0}^{T-1} \frac{\partial L_{j}}{\partial \mathbf{W}} \]
而
\[\begin{aligned} \frac{\partial L_{j}}{\partial \mathbf{W}} &= \sum_{k=0}^{j} \frac{\partial L_{j}}{\partial h_{k}} \frac{\partial h_{k}}{\partial \mathbf{W}} \\ &=\sum_{k=0}^{j} \frac{\partial L_{j}}{\partial y_{j}} \frac{\partial y_{j}}{\partial h_{j}} \frac{\partial h_{j}}{\partial h_{k}} \frac{\partial h_{k}}{\partial \mathbf{W}} \\ \end{aligned} \]
而
\[\frac{\partial h_{j}}{\partial h_{k}}=\prod_{m=k+1}^{j} \frac{\partial h_{m}}{\partial h_{m-1}} \]
合並在一起,得到
\[\frac{\partial L}{\partial \mathbf{W}}=\sum_{j=0}^{T-1} \sum_{k=0}^{j} \frac{\partial L_{j}}{\partial y_{j}} \frac{\partial y_{j}}{\partial h_{j}}\left(\prod_{m=k+1}^{j} \frac{\partial h_{m}}{\partial h_{m-1}}\right) \frac{\partial h_{k}}{\partial \mathbf{W}} \]
加上激活函數
\[h_{m}=f\left(\mathbf{W}_{h} h_{m-1}+\mathbf{W}_{x} x_{m}\right) \\ \frac{\partial h_{m}}{\partial h_{m-1}}=\mathbf{W}_{h}^{T} \operatorname{diag}\left(f^{\prime}\left(\mathbf{W}_{h} h_{m-1}+\mathbf{W}_{x} x_{m}\right)\right) \\ \frac{\partial h_{j}}{\partial h_{k}} = \prod_{m=k+1}^{j}\mathbf{w}_{h}^{T} \operatorname{diag}\left(f^{\prime}\left(\mathbf{W}_{h} h_{m-1}+\mathbf{W}_{x} x_{m}\right)\right). \]
可以看出中間連乘部分會導致嚴重的梯度消失和梯度爆炸的現象,想要解決這一問題,一就是改變網絡結構,讓連乘變成其他的,然后就有\(LSTM\)和\GRU兩種結構來改善梯度消失這種現象,讓連乘變成了連加,梯度爆炸主要通過截斷方法解決。
DNN和RNN中梯度消失的不同點,采用一個知乎用戶的評論:
梯度消失其實在DNN和RNN中意義不一樣,DNN中梯度消失指的是誤差無法傳遞回淺層,導致淺層的參數無法更新;而RNN中的梯度消失是指較早時間步所貢獻的更新值,無法被較后面的時間步獲取,導致后面時間步進行誤差更新的時候,采用的只是附近時間步的數據。【即,RNN中參數還是可以更新的,但是沒辦法滿足它最開始的假設,利用到較早信息。】
LSTM
LSTM是Jurgen Schmidhuber大佬在1997年就提出的一種結構,原文在此
用數學表達式,數學表達每一步是這樣子的
\[\begin{aligned} f_{t} &= \sigma\left(W^{(f)} x_{t}+U^{(f)} h_{t-1}\right) -Forget Gate (gate 0, forget \, past) \\ i_{t} &= \sigma\left(W^{(i)} x_{t}+U^{(i)} h_{t-1}\right) -Input Gate (current\,cell\, matters)\\ \tilde{c}_{t} &= \tanh \left(W^{(c)} x_{t}+U^{(c)} h_{t-1}\right) -New\,memory\,cell\\ c_{t} &= f_{t} \odot c_{t-1}+i_{t} \odot \tilde{c}_{t} -Final\,memory\,cell\\ o_{t} &= \sigma\left(W^{(o)} x_{t}+U^{(o)} h_{t-1}\right) -Output\,Gate (how\,much \,cell\,is\,exposed)\\ h_{t} &= o_{t} \odot \tanh \left(c_{t}\right) -Final\,hidden\,state \\ \end{aligned} \]
不同於簡單RNN,在每一步,LSTM將狀態分為\(c_t\)和\(h_t\),分別表示記憶塊和隱藏狀態,其中的\(i,f,o\)分別表示\(input,forget,output\),對於各種參數詳細直觀解釋和為甚效果好可以參考
GRU
GRU是2014年提出的新的帶門結構,結構更簡單,運算更容易,效果不遜於LSTM,因此得到了廣泛應用,原文在此,另外一篇關於LSTM與GRU對比的論文在這里
GRU數學公式如下
\[\begin{aligned} r_{t} &= \sigma\left(W^{(r)} x_{t}+U^{(r)} h_{t-1}\right) -Reset\,gate: determines\,how\, to\,combine\,the\, new\, input\,with\,the \,previous\,memory \\ z_{t} &= \sigma\left(W^{(z)} x_{t}+U^{(z)} h_{t-1}\right)-Update\,gate: decides\,how\, much\,of\,the\,previous\, memory\,to\,keep\,around \\ \tilde{h}_{t} &= \tanh \left(W x_{t}+\ U(h_{t-1} \odot r \right)) -Candidate\, hidden\, layer \\ h_{t} &= z_{t} \odot h_{t-1}+\left(1-z_{t}\right) \odot \tilde{h}_{t} -Final\,state \end{aligned} \]