前言

循环神经网络(Recurrent Neural Networks,RNN)是一种特殊的神经网络模型,常常被用来处理序列数据。

基本原理

感性认识

传统的卷积神经网络的结构比较简单:输入层 – 隐藏层 – 输出层。层与层之间是全连接的,层中各神经元之间没有连接。而循环神经网络中隐藏层的神经元结点之间是有连接的。前一次的输出结果,带到下一次的隐藏层中,一起训练。一个NLP的工作原理如下:

假设输入是一个字符串,对字符串进行分割后有若干有先后顺序的单词作为网络输入:

1

先将 “what”作为 RNN 的输入,得到输出O1

2.gif

再将“time”输入到 RNN 网络,得到输出O2,这时前面 “what” 的输出也产生了影响(隐藏层中有一半(定性非定量)是黑色)

3.gif

以此类推,后续各输入都会受到之前输出结果的影响

4.gif

我们只需要关心最终的输出O5

5.gif

当然RNN的缺点也显而易见:随着时间序列的增加,前后信息关联度会逐渐减小,存在横向梯度消失现象。说人话就是越早输入的信息对后续的影响越小。短期的记忆影响较大(如橙色区域),但是长期的记忆影响就很小(如黑色和绿色区域)。这就是 RNN 存在的短期记忆问题。

1

公式推导

一个简单的 RNN结构实例如图:

1

上图中的 RNN 模型有一个输入层xx,一个隐藏层SS和一个输出层OOUU为连接输入层与隐藏层的权重矩阵,VV为连接隐藏层与输出层的权重矩阵,而WW为隐藏层中前节点到后节点的权重矩阵。将隐藏层的结构展开后,可以看出对应于不同时刻tt,其输出𝑂𝑡𝑂_𝑡不仅仅与当前时刻的输入𝑥𝑡𝑥_𝑡有关,还与上一时刻的隐藏层输出𝑆𝑡1𝑆_{𝑡−1}有关。总结为公式有:

Ot=g(VSt)St=f(Uxt+WSt1)\begin{align*} O_t&=g(VS_t) \\ S_t&=f(Ux_t+WS_{t-1}) \end{align*}

𝑔𝑔𝑓𝑓均代表激活函数,其中RNN激活函数ff常用为tanh,至于为什么不用Relu?可以看这里

将上述两个式子合并可得:

Ot=g(Vf(Uxt+Wf(Uxt1+Wf(Uxt2+Wf(Uxt3+)))))O_t=g\Bigg(Vf\bigg(Ux_t+Wf\Big(Ux_{t-1}+Wf\big(Ux_{t-2}+Wf(Ux_{t-3}+···)\big)\Big)\bigg)\Bigg)

由此可见,tt时刻的输出𝑂𝑡𝑂_𝑡会受到当前及以前若干次的输入𝑥𝑡𝑥_𝑡𝑥𝑡1𝑥_{𝑡−1}𝑥𝑡2𝑥_{𝑡−2}等的影响,且同一隐藏层会共享 UUVVWW等权重参数,即 RNN 会对不同时刻的输入做相同的特征提取工作,这样可以大大减少参数数量。还有一点需要注意,在实际应用中只需要最后一帧序列的识别结果,所以并不需要将每一时刻的隐藏层都与一个输出层相连,这样也可以减少不必要的计算。

优化算法之LSTM

长短期记忆网络( Long Short-Term Memory network,LSTM)是对RNN的改进,其能够避免RNN存在的短期记忆问题。具体算法原理后续文章再展开

优化算法之GRU

门控递归单元(Gated Recurrent Unit,GRU)是LSTM的一个变体。主要是在LSTM模型的基础上做了一些简化和调整,能够有更好的性能。同样具体算法原理后续文章再展开

参考

[1] https://easyai.tech/ai-definition/rnn/