从RNN到LSTM再到GRU

参考自(https://www.cnblogs.com/jiangxinyang/p/9362922.html)
先从rnn的最常见的模型来说起。
上图中左边是RNN模型没有按时间展开的图,如果按时间序列展开,则是上图中的右边部分。我们重点观察右边部分的图。

这幅图描述了在序列索引号t 附近RNN的模型。其中:

1)x(t)代表在序列索引号 t 时训练样本的输入。同样的,x(t-1) 和 x(t+1) 代表在序列索引号 t−1 和 t+1 时训练样本的输入。

2)h(t) 代表在序列索引号 t 时模型的隐藏状态。h(t)由x(t)和 h(t-1) 共同决定。

3)o(t) 代表在序列索引号 t 时模型的输出。o(t)只由模型当前的隐藏状态 h(t) 决定。

4)L(t) 代表在序列索引号 t 时模型的损失函数,模型整体的损失函数是所有的L(t)相加和。

5)y(t) 代表在序列索引号 t 时训练样本序列的真实输出。

6)U,W,V这三个矩阵就是我们的模型的线性关系参数,它在整个RNN网络中是共享的。也正是因为是共享的,它体现了RNN的模型的“循环反馈”的思想。
从RNN到LSTM再到GRU
循环网络的前向传播算法非常简单,对于t时刻

h(t)=ϕ(Ux(t)+Wh(t1)+b)h^{(t)}=\phi\left(U x^{(t)}+W h^{(t-1)}+b\right)
其中ϕ(.)为**函数,一般来说会选择tanh函数,b为偏置。则 t 时刻的输出:
o(t)=Vh(t)+c\boldsymbol{o}^{(t)}=V h^{(t)}+c
最终模型的预测输出为:
y^(t)=σ(o(t))\hat{y}^{(t)}=\sigma\left(o^{(t)}\right)
其中σ为**函数,**函数通常选择softmax函数。

循环神经网络的反向传播算法:
对于RNN,由于我们在序列的每个位置都有损失函数,因此最终的损失L为:
L=t=1nL(t)L=\sum_{t=1}^{n} L^{(t)}
因此可以得到U,V,W的偏导,其中V的比较好求
LV=t=1nL(t)o(t)o(t)V\frac{\partial L}{\partial V}=\sum_{t=1}^{n} \frac{\partial L^{(t)}}{\partial o^{(t)}} \cdot \frac{\partial o^{(t)}}{\partial V}

在反向传播时,在某一序列位置 t 的梯度损失由当前文职的输出对应的梯度损失和序列索引位置 t + 1 时的梯度损失两部分共同决定的。
对于W在某一序列位置 t 的梯度损失需要反向传播一步步的计算。
比如以t=3时刻为例
L(3)W=L(3)o(3)o(3)h(3)h(3)W+L(3)o(3)o(3)h(3)h(3)h(2)h(2)W+L(3)o(3)o(3)h(3)h(3)h(2)h(2)h(1)h(1)W\frac{\partial L^{(3)}}{\partial W}=\frac{\partial L^{(3)}}{\partial o^{(3)}} \frac{\partial o^{(3)}}{\partial h^{(3)}} \frac{\partial h^{(3)}}{\partial W}+\frac{\partial L^{(3)}}{\partial o^{(3)}} \frac{\partial o^{(3)}}{\partial h^{(3)}} \frac{\partial h^{(3)}}{\partial h^{(2)}} \frac{\partial h^{(2)}}{\partial W}+\frac{\partial L^{(3)}}{\partial o^{(3)}} \frac{\partial o^{(3)}}{\partial h^{(3)}} \frac{\partial h^{(3)}}{\partial h^{(2)}} \frac{\partial h^{(2)}}{\partial h^{(1)}} \frac{\partial h^{(1)}}{\partial W}
L(3)U=L(3)o(3)o(3)h(3)h(3)U+L(3)o(3)o(3)h(3)h(3)h(2)h(2)U+L(3)o(3)o(3)h(3)h(3)h(2)h(2)h(1)h(1)U\frac{\partial L^{(3)}}{\partial U}=\frac{\partial L^{(3)}}{\partial o^{(3)}} \frac{\partial o^{(3)}}{\partial h^{(3)}} \frac{\partial h^{(3)}}{\partial U}+\frac{\partial L^{(3)}}{\partial o^{(3)}} \frac{\partial o^{(3)}}{\partial h^{(3)}} \frac{\partial h^{(3)}}{\partial h^{(2)}} \frac{\partial h^{(2)}}{\partial U}+\frac{\partial L^{(3)}}{\partial o^{(3)}} \frac{\partial o^{(3)}}{\partial h^{(3)}} \frac{\partial h^{(3)}}{\partial h^{(2)}} \frac{\partial h^{(2)}}{\partial h^{(1)}} \frac{\partial h^{(1)}}{\partial U}
因此,在某个时刻的对 W 或是 U 的偏导数,需要追溯这个时刻之前所有时刻的信息。根据上面的式子可以归纳出 L 在 t 时刻对 W 和 U 偏导数的通式:
L(t)W=k=0tL(t)o(t)o(t)h(t)(j=k+1th(j)h(j1))h(k)W\frac{\partial L^{(t)}}{\partial W}=\sum_{k=0}^{t} \frac{\partial L^{(t)}}{\partial o^{(t)}} \frac{\partial o^{(t)}}{\partial h^{(t)}}\left(\prod_{j=k+1}^{t} \frac{\partial h^{(j)}}{\partial h^{(j-1)}}\right) \frac{\partial h^{(k)}}{\partial W}
L(t)U=k=0tL(t)o(t)o(t)h(t)(j=k+1th(j)h(j1))h(k)U\frac{\partial L^{(t)}}{\partial U}=\sum_{k=0}^{t} \frac{\partial L^{(t)}}{\partial o^{(t)}} \frac{\partial o^{(t)}}{\partial h^{(t)}}\left(\prod_{j=k+1}^{t} \frac{\partial h^{(j)}}{\partial h^{(j-1)}}\right) \frac{\partial h^{(k)}}{\partial U}
引入**函数后:
j=k+1thjhj1=j=k+1ttanhWs\prod_{j=k+1}^{t} \frac{\partial h^{j}}{\partial h^{j-1}}=\prod_{j=k+1}^{t} \tanh ^{\prime} \cdot W_{s}
利用BPTT算法训练网络时容易出现梯度消失的问题,当序列很长的时候问题尤其严重,因此上面的RNN模型一般不能直接应用。而较为广泛使用的是RNN的一个特例LSTM。

LSTM

所有 RNN 都具有一种重复神经网络模块的链式的形式。在标准的 RNN 中,这个重复的模块只有一个非常简单的结构,例如一个 tanh 层。
从RNN到LSTM再到GRU
LSTM 同样是这样的结构,但是重复的模块的结构更加复杂。不同于 单一神经网络层,整体上除了 h 在随时间流动,细胞状态 c 也在随时间流动。细胞状态 c 就代表着长期记忆,而状态 h 代表了短期记忆。
从RNN到LSTM再到GRU
如图中上面的长横线。这个隐藏状态我们一般称为细胞状态(Cell State),记为 Ct 。如下图所示:
从RNN到LSTM再到GRU
细胞状态类似于传送带。直接在整个链上运行,只有一些少量的线性交互。信息在上面流传保持不变会很容易。LSTM 有通过精心设计的称作为“门”的结构来去除或者增加信息到细胞状态的能力。LSTM在在每个序列索引位置t的门一般包括遗忘门,输入门和输出门三种。下面我们就来研究上图中LSTM的遗忘门,输入门和输出门以及细胞状态。

遗忘门
ft=σ(Wf[ht1,xt]+bf)f_{t}=\sigma\left(W_{f} \cdot\left[h_{t-1}, x_{t}\right]+b_{f}\right)
从RNN到LSTM再到GRU
输入门:
it=σ(Wi[ht1,xt]+bi)i_{t}=\sigma\left(W_{i} \cdot\left[h_{t-1}, x_{t}\right]+b_{i}\right)
C~t=tanh(WC[ht1,xt]+bC)\tilde{C}_{t}=\tanh \left(W_{C} \cdot\left[h_{t-1}, x_{t}\right]+b_{C}\right)
从RNN到LSTM再到GRU
在获得了输入门和遗忘门系数之后就可以更新当前的细胞状态,Ct-1 更新为 Ct 。
Ct=ftCt1+itC~tC_{t}=f_{t} * C_{t-1}+i_{t} * \tilde{C}_{t}
从RNN到LSTM再到GRU
输出门:
ot=σ(Wo[ht1,xt]+bo)o_{t}=\sigma\left(W_{o}\left[h_{t-1}, x_{t}\right]+b_{o}\right)
ht=ottanh(Ct)h_{t}=o_{t} * \tanh \left(C_{t}\right)
从RNN到LSTM再到GRU
LSTM前向传播算法

LSTM模型有两个隐藏状态 ht , Ct ,模型参数几乎是RNN的4倍,因为现在多了 Wf, Uf, bf, Wa, Ua, ba, Wi, Ui, bi, Wo, Uo, bo 这些参数。
前向传播过程在每个序列索引位置的过程为:
1)更新遗忘门输出:
ft=σ(Wfht1+Ufxt+bf)f_{t}=\sigma\left(W_{f} h_{t-1}+U_{f} x_{t}+b_{f}\right)
2)更新输入门两部分输出:
it=σ(Wiht1+Uixt+bi);at=tanh(Waht1+Uaxt+ba)\mathrm{i}_{\mathrm{t}}=\sigma\left(\mathrm{W}_{\mathrm{i}} \mathrm{h}_{\mathrm{t}-1}+\mathrm{U}_{\mathrm{i}} \mathrm{x}_{\mathrm{t}}+\mathrm{b}_{\mathrm{i}}\right) ; \quad \mathrm{a}_{\mathrm{t}}=\tanh \left(\mathrm{W}_{\mathrm{a}} \mathrm{h}_{\mathrm{t}-1}+\mathrm{U}_{\mathrm{a}} \mathrm{x}_{\mathrm{t}}+\mathrm{b}_{\mathrm{a}}\right)
3)更新细胞状态:
Ct=Ct1ft+itatC_{t}=C_{t-1} f_{t}+i_{t} a_{t}
4)更新输出门输出:
ot=σ(Woht1+Uoxt+bo)\mathrm{o}_{\mathrm{t}}=\sigma\left(\mathrm{W}_{\mathrm{o}} \mathrm{h}_{\mathrm{t}-1}+\mathrm{U}_{\mathrm{o}} \mathrm{x}_{\mathrm{t}}+\mathrm{b}_{\mathrm{o}}\right)
ht=ottanh(Ct)\mathrm{h}_{\mathrm{t}}=\mathrm{o}_{\mathrm{t}} \tanh \left(\mathrm{C}_{\mathrm{t}}\right)
5)更新当前序列索引预测输出:
yt=σ(ht+c)y_{t}=\sigma\left(\vee h_{t}+c\right)

GRU

GRU是LSTM网络的一种效果很好的变体,它较LSTM网络的结构更加简单,而且效果也很好,因此也是当前非常流形的一种网络。GRU既然是LSTM的变体,因此也是可以解决RNN网络中的长依赖问题。

在LSTM中引入了三个门函数:输入门、遗忘门和输出门来控制输入值、记忆值和输出值。而在GRU模型中只有两个门:分别是更新门和重置门。具体结构如下图所示:
从RNN到LSTM再到GRU
图中的zt和rt分别表示更新门和重置门。更新门用于控制前一时刻的状态信息被带入到当前状态中的程度,更新门的值越大说明前一时刻的状态信息带入越多。重置门控制前一状态有多少信息被写入到当前的候选集 h~t 上,重置门越小,前一状态的信息被写入的越少。

GRU前向传播

根据上面的GRU的模型图,我们来看看网络的前向传播公式:
rt=σ(Wr[ht1,xt])r_{t}=\sigma\left(W_{r} \cdot\left[h_{t-1}, x_{t}\right]\right)
zt=σ(Wz[ht1,xt])z_{t}=\sigma\left(W_{z} \cdot\left[h_{t-1}, x_{t}\right]\right)
h~t=tanh(Wh~[rtht1,xt])\tilde{h}_{t}=\tanh \left(W_{\tilde{h}} \cdot\left[r_{t} * h_{t-1}, x_{t}\right]\right)
ht=(1zt)ht1+zth~th_{t}=\left(1-z_{t}\right) * h_{t-1}+z_{t} * \tilde{h}_{t}
yt=σ(Woht)y_{t}=\sigma\left(W_{o} \cdot h_{t}\right)

相关文章: