循环神经网络RNN
前言
我们在思考和判断问题的时候,并不是总是以一个空白的状态进行思考的。我们的思考都是基于我们以前的知识或者经验,比如我们读到这篇博客的时候,考虑到这些词语或者语句表达的是什么意思,都是基于我们以前所学到的知识。也就是说我们的思想具有持续性。
传统的神经网络对于这种情况显得有点无能为力。比如你想要识别出一个电影片段里面的每一个画面,由于要考虑到前后画面的连续性,传统的神经网络很处理这种问题。RNN的出现解决了这个问题。RNN是包含循环的神经网络,允许信息的持久化。其实在上述描述情景里面涉及到时序数据,传统的HMM模型和动态时间规划算法(DTW)也可解决上述问题,但是效果却不如RNN。有兴趣的读者可以查看相关文献,这里就不再赘述。下面我们详细介绍RNN。
RNN的定义
递归神经网络(RNN)是两种人工神经网络的总称。一种是时间递归神经网络(recurrent neural network),另一种是结构递归神经网络(recursive neural network)。时间递归神经网络的神经元间连接构成矩阵,而结构递归神经网络利用相似的神经网络结构递归构造更为复杂的深度网络。RNN一般指代时间递归神经网络。
recurrent neural network原理
上面的图片是一个简单的RNN结构模块。表示输入数据,A表示正在处理数据,表示输出数据。循环可以使这些信息从当前一部传递到下一步。具体展开之后为右边的结构。通过展开我们简单的认为我们写出了全部的序列。其中循环神经网络对应的公式如下:
- 表示的是t时刻的输入,可以是一个one-hot向量。
- 是t时刻的隐层状态,它是记忆网络。是基于前一时刻隐层和当前时刻输入的计算,,其中f函数通常是非线性的,如ReLU或者tanh。其中第一个初始化状态记为0
- 表示t时刻的输出,例如,如果我们想预测句子a的下一个词,它将会是一个词汇表中的概率向量,
其中有几点注意事项:
- 你可以将隐层状态认为是网络的记忆。可以捕获之前所有时刻发生的信息。输出 的计算仅仅依赖于时刻t的记忆。上面已经简略提到,实际中这个过程有些复杂,因为 通常不能获取之前过长时刻的信息
- 不像传统的深度神经网络,在不同的层使用不同的参数,循环神经网络在所有步骤中共享参数(U、V、W)。这个反映一个事实,我们在每一步上执行相同的任务,仅仅是输入不同。这个机制极大减少了我们需要学习的参数的数量;
- 上图在每一步都有输出,但是根据任务的不同,这个并不是必须的。例如,当预测一个句子的情感时,我们可能仅仅关注最后的输出,而不是每个词的情感。相似地,我们在每一步中可能也不需要输入。循环神经网络最大的特点就是隐层状态,它可以捕获一个序列的一些信息;
同一层前一个神经元的输出可以作为下一个神经圆的输入,这就是RNN与全连接网络的区别,下图为一个全连接网络,可以看到全连接网络的同一层之间是没有联系的。
几种常见的应用
- one to many:输入一幅图片生成一个描述这个图片的句子
- many to one:输入一段句子判断情感,或者输入一段视频,判断视频的行为
- many to many:对于视频中的每一段都做出决策,或者机器翻译
CVPR上有很多这方面的论文可以学习。
循环神经网络训练
循环神经网络的训练类似于传统神经网络的训练。我们也使用反向传播算法,但是有所变化。因为循环神经网络在所有时刻的参数是共享的,但是每个输出的梯度不仅依赖当前时刻的计算,还依赖之前时刻的计算。例如,为了计算时刻 t = 4 的梯度,我们还需要反向传播3步,然后将梯度相加。这个被称为Backpropagation Through Time(BPTT)。现在,我们仅仅需要了解到利用BPTT算法训练出来的普通循环神经网络很难学习长期依赖(例如,距离很远的两步之间的依赖),原因就在于梯度消失/发散问题。目前已经有一些机制来解决这些问题,特定类型的循环神经网络(如LSTM)专门用于规避这些问题。
BPTT算法
这与我们在深度前馈神经网络中使用的标准反向传播算法基本相同。主要的差异就是我们将每时刻 W 的梯度相加。在传统的神经网络中,我们在层之间并没有共享参数,所以我们不需要相加。
为了与参考文献保持一致,这里我们把修改为,所以RNN的基本公式为:
我们定义损失熵为交叉熵,如下所示:
以语言模型为例,是t时刻上正确的词,是预测出来的词。我们通常将一整个序列(一个句子)作为一个训练实例,所以总的误差就是各个时刻(词)的误差之和。
请牢记,我们的目标是计算误差关于参数U、V和W的梯度,然后使用梯度下降法学习出好的参数。正如我们将误差相加,我们也将一个训练实例在每时刻的梯度相加:
为了计算这些梯度,我们需要使用微分的链式法则。当从误差开始向后时,这就是反向传递,这里我们以为例,仅仅是为了使用具体数字。
其中
推导过程:
因此有:
计算有所不同。为了了解原因,我们写出链式法则,正如上面所示。
其中依赖于,而又依赖于和W。如果我们队W求导,我们不能简单将视为一个常量,我们需要再次应用链式法则,我们真正想要的如下所示:
我们将每时刻对梯度的贡献相加。也就是说,由于 W 在每时刻都用在我们所关心的输出上,我们需要从时刻 t = 3 通过网络的所有路径到时刻 t = 0 来反向传播梯度:
请留意,这与我们在深度前馈神经网络中使用的标准反向传播算法完全相同。主要的差异就是我们将每时刻 W 的梯度相加。在传统的神经网络中,我们在层之间并没有共享参数,所以我们不需要相加。
依赖性问题
RNN 的关键点之一就是他们可以用来连接先前的信息到当前的任务上,例如使用过去的视频段来推测对当前段的理解。但是当相关信息和当前预测位置之间的间隔变得非常大,RNN 会丧失学习到连接如此远的信息的能力。RNN 绝对可以处理这样的长期依赖 问题。人们可以仔细挑选参数来解决这类问题中的最初级形式,但在实践中,RNN 肯定不能够成功学习到这些知识。训练和参数设计十分复杂。LSTM就是专门设计出来解决这个问题的。下一篇我们详细讨论LSTM
引用
[1].http://blog.****.net/heyongluoyao8/article/details/48636251