1、什么是RNN?
全名,叫做Recurrent neural network,它可以处理有序列的或者有前后关系的句子,利用前面的信息预测后面的信息,这个是RNN和CNN最大的区别。CNN不考虑顺序依赖关系,RNN考虑顺序依赖关系。
2、RNN的结构
这个图就是一个循环神经网络,它循环其实是一个"假"循环,就是将每个时间步的输入拆开即可。首先说一下RNN的输入和学习的参数。
输入:x_t:每个时间步的输入,s_t每个时间步的隐状态向量。
输出:o_t每个时间步的输出
接下来说说如何得到隐状态向量和输出。
s_t:由上一个时间步的输入x和隐状态计算决定,因此它包含了上一个步骤的一些携带信息。,f也是一个激活函数。
o_t:是每个时间步的s_t来决定的,这个s_t已经有了上一个隐状态和当前输入的计算了。
那么从上面隐状态的计算和输出的计算可以看到,需要学习的参数就是U,V,W这三个参数。这里很重要的一点就是每个状态步共享这个三个参数,也就是说这三个参数在每一步都是一样的。那么从公式的推导其实可以看出来为啥它可以处理有顺序依赖关系的句子,而CNN不能处理,其关键的部分就在于s_t隐状态向量,因为它捕获了之前每个时间步的信息。RNN的主要特征是它的隐藏状态,它捕获了一些关于前边序列的信息。
3、RNN应用
- 机器翻译
- 语音识别
- 句子的情感预测
- ........
4、RNN的BPTT
训练RNN需要用使用的是随机梯度下降算法,更新参数的时候肯定还是用到的方向传播,但是实际上这个反向传播和CNN中的反向传播是有一些区别的。
我们用的损失函数是交叉熵损失函数,写出总的损失函数。
每个时间步的损失函数:
总的损失函数:
待学习的参数是U,V,W因此要对这些参数进行求导。
以第3步为例
对V的偏导仅仅取决于当前的步长,那么多对W、U的求导可就不仅仅取决于当前的步长,以W为例子
可以看到s3的值取决于s2,s2有取决于s1因此需要根据链式要对之前的都分别求偏导,然后计算总的梯度贡献值
对U的求导同理可得。
5、RNN的缺点
如果一个句子太长那么RNN不能捕捉到前面信息对后面信息的贡献,可以这么认为那个隐状态能记录的信息是有限的,当然从原理上来讲会在反向传播的过程中出现梯度的消失或者梯度爆炸问题。
由刚才计算梯度的式子来看
其中也是链式法则求导
因此可以将上述式子改成下面的
其导数为
如果激活函数是sigmoid,导数的上界是1/4.
是一个在区间 这样经过连乘以后,不管是sigmoid或者tanth的激活函数都是取于0的时候,连乘之后最远的梯度对当前的梯度就几乎没有什么影响了。那么比较远位置的向量就对它当前的学习没什么贡献,这个和我们说RNN的初衷就不一样了,因为句子太长,造成梯度为0,学习位置较远的信息就失效了。最终无法学习长期的依赖关系,当然了如果这个导数的值越大经过连乘之后就会造成梯度爆炸loss计算过程就会出此案NaN值,这个可以用梯度裁剪(将梯度剪切到预先定义的阈值),而梯度消失往往不明显,当然改进梯度消失可以换激活函数或者正则化,但是都没从根本解决这个问题。因此LSTM就应运而生了。
Reference:https://www.zhihu.com/question/44895610/answer/616818627;http://www.wildml.com/2015/10/recurrent-neural-network-tutorial-part-4-implementing-a-grulstm-rnn-with-python-and-theano/