主要是个人备忘录,很不完整和规范。
基本都省略了偏置。
简单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}
\]