目录
为什么需要RNN?
标准的神经网络不适合用来处理待时间序列任务的场景,无法体现时序上的“前因后果”。
RNN的前后关联强,后面状态会受到前面状态的影响。从网络结构上看,RNN会记忆之前的信息,并利用这些信息影响后边结点的输出。也就是说,RNN的隐藏层之间的结点不是互不相关的,而是有连接的,隐藏层的输入不仅包括输入层的输出,还包括上一时刻隐藏层的输出。
RNN的网络结构
RNN是一个多输入多输出、串联的结构
RNN 跟传统神经网络最大的区别在于每次都会将前一次的输出结果,带到下一次的隐藏层中,一起训练。
RNN的单元结构:
a为对应的隐藏层状态值;Wax为输入层到隐藏层的权重矩阵;Wya为隐藏层到输出层的权重矩阵;Waa就是隐藏层上一次的值作为这一次的输入的权重。
用“What time is it?”来看看RNN是如何工作的。首先是将句子拆解。如下:
按照句子顺序将其输入到RNN网络中,将 “what”作为RNN的输入,得到输出01。想象一下,此时是没有前面隐藏层值的影响,what对应的状态(中间的圆圈)为黑色。
再将“time”输入到RNN网络,得到输出02.
此时RNN网络保留了“what”的隐藏层状态,将其也作为输入值输入到了网络中。“time”对应的隐藏层不光有本身的状态还有上一隐藏层的状态(一半黑色一半绿色)。
以此类推,前面所有的输入产生的结果都对后续的输出产生了影响(可以看到每个圆圈中包含了前面所有的颜色)
特点:
1.串联结构:体现出“前因后果”,后面结果的生成,要参考前面的信息
2.所有特征共享同一参数:
面对不同的输入(两个方面),能学到不同的相应的结果
极大减少了训练量
输入和输出数据在不同例子中可以有不同的长度
RNN前向传播:
RNN反向传播:
单个单元的梯度公式:
要结合具体的损失函数
一般是tanh:
梯度消失
当序列太长时,容易导致【梯度消失】,参数更新只能捕捉到局部依赖关系,没法再捕捉序列之间的【长期】关联或者依赖关系
RNN的梯度消失的真正含义是,梯度被近距离梯度主导,导致模型难以学习到远距离的依赖关系。
现象:
比如一句话The cat,which ate already,……,was full。就是后边的was还是were,要看前面是cat还是cats,但是一旦中间这个which的句子很长,cat的信息根本传不到was这里来,对was的更新没有任何帮助,这是RNN一个很大的不足之处。
例子:
前向传播
损失函数:假设使用平方误差
单个时间点求梯度:
假设在t=3时刻,损失函数为
网络参数 求梯度:W0:
Wx:
其中:
任意时刻下的梯度公式:
梯度爆炸和梯度消失的主要原因是Ws^(k-1)
根本原因在于反向传播训练法则,链式求导次数太多。
梯度爆炸:
解决方案:梯度修剪:观察你的梯度向量,如果它大于某个阈值,缩放梯度向量,保证它不会太大。
当t=20时
t = 3的节点,由于连乘过多导致梯度消失,无法将信息传回给t=20,因此t=20的更新,无法引入到t=3时的信息,认为t=20节点跟t=3节点无关联。
参考:
循环神经网络(RNN)_rnn循环神经网络_小朱小朱绝不服输的博客-CSDN博客
【【重温系列】RNN循环神经网络及其梯度消失 手把手公式推导+大白话讲解】 【重温系列】RNN循环神经网络及其梯度消失 手把手公式推导+大白话讲解_哔哩哔哩_bilibili