RNN原理
RNN在实际使用的频率并不多,大多使用LSTM替代RNN,因此对RNN进行简单的介绍。RNN是研究LSTM的基础,毕竟LSTM是基于RNN的改良,二者循环原理大体一致。
初识RNN,要记住在时间步上,RNN的权值共享即可。
RNN的运行原理就相当于,每一个时间步利用RNN计算一次得到输出结果,每个时间步上的RNN都是同一个东西。
RNN输入到输出
- 输入:
RNN只有两个输入: x t x_t xt和 h t − 1 h_{t-1} ht−1。这两个输入分别为当前时刻的样本输入和上一时刻的隐层状态输入。我们无法操作 h t − 1 h_{t-1} ht−1,只需要指定 x t x_t xt即可。
- 输出:
RNN有两个输出: O t O_t Ot和 h t h_t ht。这两个输出分别为当前时间步的输出和当前时间步的隐藏层输出。当前隐藏层转态将作为输入参与下一时间步的计算。
由输入到输出 O t O_t Ot和 h t h_t ht的计算公式分别为:
h t = σ ( U ∗ x t + V ∗ h t − 1 + b ) ( 1 ) h_t=\sigma(U*x_t+V*h_{t-1}+b) \qquad(1) ht=σ(U∗xt+V∗ht−1+b)(1)
O t = W ∗ h t + c ( 2 ) O_t=W*h_t+c\qquad(2) Ot=W∗ht+c(2)
输出整个RNN网络的最终结果时,最后一层RNN输出的结果 O t O_t Ot需要进行一次非线性变换,如果是分类网络,激活函数一般为softmax。
y ~ t = f ( O t ) ( 3 ) \widetilde y_t =f(O_t) \qquad(3) y t=f(Ot)(3)
RNN优缺点
优点:
- 处理短序列,循环神经网络工作的比较好。
缺点:
- 不能处理长序列问题,原因是RNN循环相乘相乘导致梯度消失或者梯度爆炸,几乎不可训练
- RNN的这种利用上一步的输出作为上一时间步的信息输入到当前时间步,在任意时间步处理中,只参考了前面时间步的特征,序列后方没有学到更前面的时间步的特征。因此引出了BRNN。
RNN梯度消失或者梯度爆炸的原因和解决办法
在RNN反向传播中,需要求 h t h_t ht相对权重V的偏导数,而这时由于有 h t − 1 h_{t-1} ht−1, h t − 1 h_{t-1} ht−1又是关于V的函数,根据链式求导法则,需要求 h t h_t ht对 h t − 1 h_{t-1} ht−1的偏导数,一直回溯1~(t-1)所有时刻的信息,于是会存在连乘项 ∏ ∂ h t ∂ h t − 1 \prod {\partial h_t \over \partial h_{t-1}} ∏∂ht−1∂ht。
根据(1)式可知, ∂ h t ∂ h t − 1 {\partial h_t \over \partial h_{t-1}} ∂ht−1∂ht偏导数为: σ ′ ∗ V \sigma'*V σ′∗V,连乘之后,会有 σ ′ \sigma' σ′连乘。由于RNN使用sigmod激活函数,其导数范围在[0,0.25]之间,那么当V>4时会产生梯度爆炸,而当V<4时会产生梯度消失。
所以RNN在处理长序列时,会导致梯度消失和梯度爆炸。梯度爆炸可以采取clip,但是梯度消失比较难以解决。