


基于《智能计算系统》各章节内容
抽取核心知识点扩展讲解
配合《智能计算系统》课程“一起服用”
帮你轻松领路全栈!
灶友们,今天的开小灶Heyro将带大家了解另一种不同于卷积神经网络CNN的神经网络——循环神经网络RNN。
我们将分别从概念、出现原因、结构及训练方法的角度来介绍这种循环神经网络。接下来就让我们一起开启循环神经网络RNN的探索之旅吧。

循环神经网络(Recurrent Neural Network, RNN)是一种用于处理序列数据的神经网络结构。该网络结构主要用于机器翻译、图片描述、视频标注、视觉问答等领域。循环神经网络是根据“人的认知是基于过往的经验和记忆”这一理念而被提出的。
循环神经网络主要用于处理序列数据。序列数据包括文字、语音、视频等对象。这些数据有两个主要特点:其一,数据无固定长度。例如一句话中包含的文字数目是可变的,在这句话表述完全之前,我们无法知道它究竟包含有多少个文字。其二,序列数据是按时序输入的、有时间信息的数据,其相邻数据之间存在相关性,并非相互独立。同样以文字为例,一个词在不同的语境、语序中的意思可能完全不同,该词的存在与其前后的文字息息相关,如“京东”如果放到“北京东站”四个字里就不再是原先的含义。
正是基于序列数据中相邻数据相关性的信息存储需求,卷积神经网络CNN不再适用于处理这类型的数据。卷积神经网络在处理数据时只需要固定的权重参数,不需要根据已处理的前一张图片的情况来改变内部状态。换言之,卷积神经网络不具备存储信息的能力因而不能将之前输入的序列信息用于之后的预测中。
为了创造出具有“记忆”能力的神经网络,循环神经网络RNN便应运而生了。这体现的即为我们在前文提到的——“人的认知是基于过往的经验和记忆”的理念。RNN可以有效保存序列数据的历史信息,因此比较适合处理序列数据。
RNN使用带有自我反馈的神经元,从而可以处理任意长度的序列数据。接下来,让我们一起来认识循环神经网络的结构。

循环神经网络结构
在一个循环神经网络中,输入为x,输出为ŷ,隐层为h。其中,隐层h被称为记忆单元,它具有存储信息的能力。隐层中的输出会影响其下一时刻的输入,因此我们会在RNN的结构中看到隐层位置有一个反馈的箭头。
那么我们又该怎样认识这种信息存储和反馈机制呢?为了解答这个问题,我们将RNN按时间序列展开来观察。

循环神经网络结构展开
首先,我们假设时刻t的输入为,输出为
,隐藏状态为
。
与两个值相关,即与当前时刻的输入和上一时刻的隐藏状态相关。每一个时间步(time step)对应的输出和隐藏状态的可更新为,

其中,b、c代表偏置,U、V、W分别为输入-隐层、隐层-输出、隐层-隐层三种连接的权重矩阵。在不同时刻,权重矩阵对应值不变。f(x)为非线性激活函数,通常为tanh或ReLU函数。
在此我们且先暂停,结合RNN网络结构图仔细分析一下上述详细步骤,从而更好地理解RNN的存储反馈机制:
在t时刻下,隐层要同时接收来自两个方向的数据,一是上一时刻的隐藏状态值
,该值通过与隐层-隐层权重矩阵W相乘来得到反馈数据。一是这一时刻的实时输入值
,该值通过与输入-隐层权重矩阵U相乘来得到新数据。之后,我们将这两个方向的数据相加,并加上偏置b进行调整,从而得到函数f(x)对应的自变量x值。
在此基础上,我们通过非线性激活函数f(x)的运算,就可以得到这一时刻的实时隐层数据。此时,我们就把上一时刻的序列数据存储到了记忆单元上。
在接下来的步骤中,我们就可将记忆单元的数据通过权重调整和全连接层的处理获得t时刻的输出
。在权重调整中,我们采用
与隐层-输出权重矩阵V相乘并加上偏置c的运算来获得一个中间输出数据
。之后,中间输出数据
会通过softmax全连接层的处理得到t时刻的相应输出
。
通过上述步骤,每个t时刻的输入会得到一个对应的输出
。每个记忆单元
在经过权重调整运算f(x)后会一次迭代出新的
值。这种不断循环迭代的过程展示了循环神经网络RNN的本质。
通过这样的循环神经网络我们可以建模序列信息。其中,序列中的前后数据(,
)相互影响。循环神经网络的循环特点体现在对每个输入的操作是相同的——我们可以循环往复地重复这些操作,并且每个时刻的参数W和U也均相同。
循环神经网络的存储记忆体现在隐层捕捉了t时刻之前的所有时刻的信息。理论上而言,中可能蕴藏了
,
,…,
中的信息,即可以蕴藏t时刻之前的全部信息,其记忆的内容可以无限延长。但在实际训练中,由于梯度爆炸等原因导致训练中能够获取存储的记忆是非常有限的。
此外,RNN在应用方面也很灵活。我们只需要提供训练样本,RNN就可以根据我们的需要训练出一对多、多对一或多对多等多种输入-输出结构。
RNN训练一般采用一种改进过的反向传播方法,即基于时间的反向传播(Back-Propagation Through Time, BPTT)。该训练方法的核心思想是将RNN按时间展开后做反向传播。

循环神经网络BPTT训练流程
BPTT完成正向传播后一般用交叉熵作为损失函数,然后再做梯度下降。其中,损失函数L为每个时刻的损失函数之和,即

损失函数对参数V的偏导为

损失函数对参数W的偏导为

之后,我们基于前文RNN网络结构中关于、、三式的运算,并与偏导的链式法则结合,可得

其中,diag(1-())为对角矩阵,其中包含元素1-()
,则

同理,损失函数对参数U的偏导为

对于上式中的步骤:

当t≫k时,该步骤很容易把一个稍大的梯度传递到下一时刻,从而变成更大的梯度。由此,在不断的反复迭代中,梯度会越来越大,即正反馈会越来越大并迅速趋向于无穷,直至产生梯度爆炸。
另一种相对的情况则是,该步骤把较小的梯度传递到下一时刻,从而导致在不断反复中梯度越来越小并很快趋向于0,最终产生梯度消失。
正是由于RNN很容易出现梯度爆炸或梯度消失,RNN的训练只能学习到时期很短的依赖关系,比如邻近几个时刻内的数据依赖。
RNN中显著的梯度爆炸或消失现象主要是循环结构引起的。一般的神经网络有很多层且每一层的权重矩阵不同,但RNN中每一层的权重矩阵均相同,这就导致梯度的绝对值急剧地单调递增或单调递减。
那么,我们该如何解决上述的梯度问题呢?
对于梯度爆炸问题,Pascanu等人提出了梯度截断方法。已知梯度ĝ为

当梯度ĝ大于预定义的threshold(阈值)时,我们可对其进行截断,从而得到

而对于梯度消失的问题,则可以使用目前流行的长短期记忆模型(Long Short-Term Memory, LSTM)或门限循环单元(Gated Recurrent Unit, GRU)来处理。

本期的开小灶到这里就结束啦。在下一期开小灶中,Heyro将为大家详细介绍解决RNN训练中出现的梯度消失问题的方法——LSTM和GRU。灶友们,我们下期再见~
除了关注公众号的“开小灶”专栏以外,灶友们还可以在“哔哩哔哩”观看智能计算系统的在线公开课程。

听说小灶讲解与视频课程配套学习会更香哦!
在全面进入AI时代的拐点上 每一个拥抱新技术的人都是时代的弄潮儿 无论你早已整装待发 还是正走在获取装备的路上 Heyro都希望大家能通过学习智能计算系统的课程 成为更棒的AI时代全栈先行者——