循环神经网络(RNN)浅析

2024-05-14

1. 循环神经网络(RNN)浅析

RNN是两种神经网络模型的缩写,一种是递归神经网络(Recursive Neural Network),一种是循环神经网络(Recurrent Neural Network)。虽然这两种神经网络有着千丝万缕的联系,但是本文主要讨论的是第二种神经网络模型——循环神经网络(Recurrent Neural Network)。
  
 循环神经网络是指一个随着时间的推移,重复发生的结构。在自然语言处理(NLP),语音图像等多个领域均有非常广泛的应用。RNN网络和其他网络最大的不同就在于RNN能够实现某种“记忆功能”,是进行时间序列分析时最好的选择。如同人类能够凭借自己过往的记忆更好地认识这个世界一样。RNN也实现了类似于人脑的这一机制,对所处理过的信息留存有一定的记忆,而不像其他类型的神经网络并不能对处理过的信息留存记忆。
  
 循环神经网络的原理并不十分复杂,本节主要从原理上分析RNN的结构和功能,不涉及RNN的数学推导和证明,整个网络只有简单的输入输出和网络状态参数。一个典型的RNN神经网络如图所示:
  
 
  
                                          
 由上图可以看出:一个典型的RNN网络包含一个输入x,一个输出h和一个神经网络单元A。和普通的神经网络不同的是,RNN网络的神经网络单元A不仅仅与输入和输出存在联系,其与自身也存在一个回路。这种网络结构就揭示了RNN的实质:上一个时刻的网络状态信息将会作用于下一个时刻的网络状态。如果上图的网络结构仍不够清晰,RNN网络还能够以时间序列展开成如下形式:
                                          
 等号右边是RNN的展开形式。由于RNN一般用来处理序列信息,因此下文说明时都以时间序列来举例,解释。等号右边的等价RNN网络中最初始的输入是x0,输出是h0,这代表着0时刻RNN网络的输入为x0,输出为h0,网络神经元在0时刻的状态保存在A中。当下一个时刻1到来时,此时网络神经元的状态不仅仅由1时刻的输入x1决定,也由0时刻的神经元状态决定。以后的情况都以此类推,直到时间序列的末尾t时刻。
  
 上面的过程可以用一个简单的例子来论证:假设现在有一句话“I want to play basketball”,由于自然语言本身就是一个时间序列,较早的语言会与较后的语言存在某种联系,例如刚才的句子中“play”这个动词意味着后面一定会有一个名词,而这个名词具体是什么可能需要更遥远的语境来决定,因此一句话也可以作为RNN的输入。回到刚才的那句话,这句话中的5个单词是以时序出现的,我们现在将这五个单词编码后依次输入到RNN中。首先是单词“I”,它作为时序上第一个出现的单词被用作x0输入,拥有一个h0输出,并且改变了初始神经元A的状态。单词“want”作为时序上第二个出现的单词作为x1输入,这时RNN的输出和神经元状态将不仅仅由x1决定,也将由上一时刻的神经元状态或者说上一时刻的输入x0决定。之后的情况以此类推,直到上述句子输入到最后一个单词“basketball”。
  
 接下来我们需要关注RNN的神经元结构:
                                          
 上图依然是一个RNN神经网络的时序展开模型,中间t时刻的网络模型揭示了RNN的结构。可以看到,原始的RNN网络的内部结构非常简单。神经元A在t时刻的状态仅仅是t-1时刻神经元状态与t时刻网络输入的双曲正切函数的值,这个值不仅仅作为该时刻网络的输出,也作为该时刻网络的状态被传入到下一个时刻的网络状态中,这个过程叫做RNN的正向传播(forward propagation)。注:双曲正切函数的解析式如下:
                                          
 双曲正切函数的求导如下:
                                          
 双曲正切函数的图像如下所示:
                                          
 这里就带来一个问题:为什么RNN网络的激活函数要选用双曲正切而不是sigmod呢?(RNN的激活函数除了双曲正切,RELU函数也用的非常多)原因在于RNN网络在求解时涉及时间序列上的大量求导运算,使用sigmod函数容易出现梯度消失,且sigmod的导数形式较为复杂。事实上,即使使用双曲正切函数,传统的RNN网络依然存在梯度消失问题,无法“记忆”长时间序列上的信息,这个bug直到LSTM上引入了单元状态后才算较好地解决。
  
 这一节主要介绍与RNN相关的数学推导,由于RNN是一个时序模型,因此其求解过程可能和一般的神经网络不太相同。首先需要介绍一下RNN完整的结构图,上一节给出的RNN结构图省去了很多内部参数,仅仅作为一个概念模型给出。
                                          
 上图表明了RNN网络的完整拓扑结构,从图中我们可以看到RNN网络中的参数情况。在这里我们只分析t时刻网络的行为与数学推导。t时刻网络迎来一个输入xt,网络此时刻的神经元状态st用如下式子表达:
                                          
 t时刻的网络状态st不仅仅要输入到下一个时刻t+1的网络状态中去,还要作为该时刻的网络输出。当然,st不能直接输出,在输出之前还要再乘上一个系数V,而且为了误差逆传播时的方便通常还要对输出进行归一化处理,也就是对输出进行softmax化。因此,t时刻网络的输出ot表达为如下形式:
                                          
 为了表达方便,笔者将上述两个公式做如下变换:
                                          
 以上,就是RNN网络的数学表达了,接下来我们需要求解这个模型。在论述具体解法之前首先需要明确两个问题:优化目标函数是什么?待优化的量是什么?
  
 只有在明确了这两个问题之后才能对模型进行具体的推导和求解。关于第一个问题,笔者选取模型的损失函数作为优化目标;关于第二个问题,我们从RNN的结构图中不难发现:只要我们得到了模型的U,V,W这三个参数就能完全确定模型的状态。因此该优化问题的优化变量就是RNN的这三个参数。顺便说一句,RNN模型的U,V,W三个参数是全局共享的,也就是说不同时刻的模型参数是完全一致的,这个特性使RNN得参数变得稍微少了一些。
  
 不做过多的讨论,RNN的损失函数选用交叉熵(Cross Entropy),这是机器学习中使用最广泛的损失函数之一了,其通常的表达式如下所示:
                                          
 上面式子是交叉熵的标量形式,y_i是真实的标签值,y_i*是模型给出的预测值,最外面之所以有一个累加符号是因为模型输出的一般都是一个多维的向量,只有把n维损失都加和才能得到真实的损失值。交叉熵在应用于RNN时需要做一些改变:首先,RNN的输出是向量形式,没有必要将所有维度都加在一起,直接把损失值用向量表达就可以了;其次,由于RNN模型处理的是序列问题,因此其模型损失不能只是一个时刻的损失,应该包含全部N个时刻的损失。
  
 故RNN模型在t时刻的损失函数写成如下形式:
                                          
 全部N个时刻的损失函数(全局损失)表达为如下形式:
                                          
 需要说明的是:yt是t时刻输入的真实标签值,ot为模型的预测值,N代表全部N个时刻。下文中为了书写方便,将Loss简记为L。在结束本小节之前,最后补充一个softmax函数的求导公式:
                                          
 由于RNN模型与时间序列有关,因此不能直接使用BP(back propagation)算法。针对RNN问题的特殊情况,提出了BPTT算法。BPTT的全称是“随时间变化的反向传播算法”(back propagation through time)。这个方法的基础仍然是常规的链式求导法则,接下来开始具体推导。虽然RNN的全局损失是与全部N个时刻有关的,但为了简单笔者在推导时只关注t时刻的损失函数。
  
 首先求出t时刻下损失函数关于o_t*的微分:
                                          
 求出损失函数关于参数V的微分:
                                          
 因此,全局损失关于参数V的微分为:
                                          
 求出t时刻的损失函数关于关于st*的微分:
                                          
 求出t时刻的损失函数关于s_t-1*的微分:
                                          
 求出t时刻损失函数关于参数U的偏微分。注意:由于是时间序列模型,因此t时刻关于U的微分与前t-1个时刻都有关,在具体计算时可以限定最远回溯到前n个时刻,但在推导时需要将前t-1个时刻全部带入:
                                          
 因此,全局损失关于U的偏微分为:
                                          
 求t时刻损失函数关于参数W的偏微分,和上面相同的道理,在这里仍然要计算全部前t-1时刻的情况:
                                          
 因此,全局损失关于参数W的微分结果为:
                                          
 至此,全局损失函数关于三个主要参数的微分都已经得到了。整理如下:
                                          
 接下来进一步化简上述微分表达式,化简的主要方向为t时刻的损失函数关于ot的微分以及关于st*的微分。已知t时刻损失函数的表达式,求关于ot的微分:
                                          
 softmax函数求导:
                                          
 因此:
                                          
 又因为:
                                          
 且:
                                          
 有了上面的数学推导,我们可以得到全局损失关于U,V,W三个参数的梯度公式:
                                          
 由于参数U和W的微分公式不仅仅与t时刻有关,还与前面的t-1个时刻都有关,因此无法写出直接的计算公式。不过上面已经给出了t时刻的损失函数关于s_t-1的微分递推公式,想来求解这个式子也是十分简单的,在这里就不赘述了。
  
 以上就是关于BPTT算法的全部数学推导。从最终结果可以看出三个公式的偏微分结果非常简单,在具体的优化过程中可以直接带入进行计算。对于这种优化问题来说,最常用的方法就是梯度下降法。针对本文涉及的RNN问题,可以构造出三个参数的梯度更新公式:
                                          
 依靠上述梯度更新公式就能够迭代求解三个参数,直到三个参数的值发生收敛。
  
 这是笔者第一次尝试推导RNN的数学模型,在推导过程中遇到了非常多的bug。非常感谢互联网上的一些公开资料和博客,给了我非常大的帮助和指引。接下来笔者将尝试实现一个单隐层的RNN模型用于实现一个语义预测模型。

循环神经网络(RNN)浅析

2. 循环神经网络(RNN)的应用

 循环神经网络(RNN)是目前深度学习最有前景的工具之一,它解决了传统神经网络不能共享从数据中共享位置的特征的问题。目前,RNN已经有了不少有意思的应用:
    语音识别 :输入的语音数据,生成相应的语音文本信息。比如微信的语音转文字功能。
    机器翻译 :不同语言之间的相互转换。像有道翻译、腾讯翻译官等。最近微软据说实现了中翻英媲美人类的水平
    音乐生成 :使用RNN网络生成音乐,一般会用到RNN中的LSTM算法(该算法可以解决RNN网络中相距较远的节点梯度消失的问题)。下面这个github项目实现了jazz音乐的生成。    deepjazz 
    文本生成 :利用RNN亦可以生成某种风格的文字。有兴趣的可以看一下一下两个github项目    numpy实现字符层面的文本生成器     keras实现特定作家风格的文本 
    情感分类 :输入文本或者语音的评论数据,输出相应的打分数据。
    DNA序列分析 :输入的DNA序列,输出蛋白质表达的子序列。
    视频行为识别 :识别输入的视频帧序列中的人物行为。
    实体名字识别 :从文本中识别实体的名字。

3. 循环神经网络(RNN)——处理序列样本

循环神经网络(Recurrent Neural Network,RNN)具有记忆功能,他可以发现样本之间的序列关系,是处理序列样本的首选模型。循环神经网络大量应用在数值、文本、声音、视频处理等领域。
  
 循环神经网络模型是一个具有记忆功能的模型。它可以发现样本之间的相互关系,多用于处理带有序列特征的样本数据。
  
 RNN模型有很多种结构,其最基本的结构是将全连接网络的输出节点复制一份并传回到输入节点中,与输入数据一起进行下一次运算。这种神经网络将数据从输入层又传回到输出层,形成了循环结构,所以被叫做循环神经网络。
  
 通过RNN模型,可以将上一个序列的样本输出结果与下一个序列样本一起输入模型中进行运算,使模型所处理的特征信息中,既含有该样本之前序列的信息,又含有该样本自身的数据信息,从而使网络具有记忆功能。
  
 在实际开发中,所使用的RNN模型还会基于上述的原理做更多的结构改进,使得网络的记忆功能更强。
  
 在深层网络结构中,还会在RNN模型基础上结合全连接网络、卷积网络、等组成拟合能力更强的模型。

循环神经网络(RNN)——处理序列样本

4. 循环神经网络

  为什么卷积神经网络不会出现严重的数值问题呢?    卷积神经网络中每一层的权重矩阵 W 是不同的,并且在初始化时它们是独立同分布的,因此可以相互抵消,在多层之后一般不会出现严重的数值问题。   循环神经网络采用 ReLu 激活函数,只有当 W 的取值在单位矩阵附近时才能取得比较好的效果,因此需要将 W 初始化为单位矩阵。
   Seq2Seq 模型最基础的解码方法是贪心法,即选取一种度量标准后,每次都在当前状态下选择最佳的一个结果,直到结束。贪心法的计算代价低,适合作为基准结果与其他方法相比较。贪心法获得的是一个局部最优解,由于实际问题的复杂性,该方法往往不能取得最好的结果。    集束搜索: 是一种启发式算法,会保存 beam size 个当前的较佳选择,然后解码时每一步根据保存的选则进行下一步扩展和排序,接着选择前 b 个进行保存,循环迭代,知道结束时选择最佳的一个作为解码的结果。 b 往往选择一个适中的范围,以 8-12 为佳。    
                                           
    Seq2Seq 模型引入注意力机制是为了解决什么问题?为什么选用了双向的循环神经网络模型?    编码时输入序列的全部信息压缩到了一个向量中,随着序列增长,句子越前面的词的信息丢失越严重。同时,Seq2Seq 模型的输出序列中,常常会损失部分输入序列信息,这是解码时,当前词及对应的源语言词的上下文信息和位置信息在编解码过程中丢失了。 引入注意力机制,解决上述问题 。使用双向的循环神经网络进行建模,可以获取前后文的信息。

5. 循环神经网络

 花书中关于RNN的内容记录于 https://www.jianshu.com/p/206090600f13 。
   在前馈神经网络中,信息的传递是单向的,这种限制虽然使得网络变得更容易学习,但在一定程度上也减弱了神经网络模型的能力。在生物神经网络中,神经元之间的连接关系要复杂的多。 前馈神经网络可以看作是一个复杂的函数,每次输入都是独立的,即网络的输出只依赖于当前的输入。但是在很多现实任务中,网络的输入不仅和当前时刻的输入相关,也和其过去一段时间的输出相关 。因此,前馈网络难以处理时序数据,比如视频、语音、文本等。时序数据的长度一般是不固定的,而前馈神经网络要求输入和输出的维数都是固定的,不能任意改变。因此,当处理这一类和时序相关的问题时,就需要一种能力更强的模型。
    循环神经网络(Recurrent Neural Network,RNN)是一类具有短期记忆能力的神经网络。在循环神经网络中,神经元不但可以接受其它神经元的信息,也可以接受自身的信息,形成具有环路的网络结构。 和前馈神经网络相比,循环神经网络更加符合生物神经网络的结构。循环神经网络已经被广泛应用在语音识别、语言模型以及自然语言生成等任务上。循环神经网络的参数学习可以通过 随时间反向传播算法 来学习。
   为了处理这些时序数据并利用其历史信息,我们需要让网络具有短期记忆能力。而前馈网络是一个静态网络,不具备这种记忆能力。
   一种简单的利用历史信息的方法是建立一个额外的延时单元,用来存储网络的历史信息(可以包括输入、输出、隐状态等)。比较有代表性的模型是延时神经网络。
   延时神经网络是在前馈网络中的非输出层都添加一个延时器,记录最近几次神经元的输出。在第  个时刻,第  层神经元和第  层神经元的最近  次输出相关,即:
     
    延时神经网络在时间维度上共享权值,以降低参数数量。因此对于序列输入来讲,延时神经网络就相当于卷积神经网络 。
    自回归模型(Autoregressive Model,AR) 是统计学上常用的一类时间序列模型,用一个变量  的历史信息来预测自己:
     
   其中  为超参数,  为参数,  为第  个时刻的噪声,方差  和时间无关。
    有外部输入的非线性自回归模型(Nonlinear Autoregressive with ExogenousInputs Model,NARX) 是自回归模型的扩展,在每个时刻  都有一个外部输入  ,产生一个输出  。NARX通过一个延时器记录最近几次的外部输入和输出,第  个时刻的输出  为:
     
   其中  表示非线性函数,可以是一个前馈网络,  和  为超参数。
   循环神经网络通过使用带自反馈的神经元,能够处理任意长度的时序数据。
   给定一个输入序列  ,循环神经网络通过下面   公式更新带反馈边的隐藏层的活性值  :
     
   其中  ,  为一个非线性函数,也可以是一个前馈网络。
                                           从数学上讲,上式可以看成一个动力系统。动力系统(Dynamical System)是一个数学上的概念,指 系统状态按照一定的规律随时间变化的系统 。具体地讲,动力系统是使用一个函数来描述一个给定空间(如某个物理系统的状态空间)中所有点随时间的变化情况。因此, 隐藏层的活性值  在很多文献上也称为状态(State)或隐状态(Hidden States) 。理论上,循环神经网络可以近似任意的非线性动力系统。
   简单循环网络(Simple Recurrent Network,SRN)是一个非常简单的循环神经网络,只有一个隐藏层的神经网络。
   在一个两层的前馈神经网络中,连接存在相邻的层与层之间,隐藏层的节点之间是无连接的。而 简单循环网络增加了从隐藏层到隐藏层的反馈连接 。
   假设在时刻  时,网络的输入为  ,隐藏层状态(即隐藏层神经元活性值)   不仅和当前时刻的输入  相关,也和上一个时刻的隐藏层状态  相关: 
     
   其中  为隐藏层的净输入,  是非线性激活函数,通常为Logistic函数或Tanh函数,  为状态-状态权重矩阵,  为状态-输入权重矩阵,  为偏置。上面两式也经常直接写为:
     
    如果我们把每个时刻的状态都看作是前馈神经网络的一层的话,循环神经网络可以看作是在时间维度上权值共享的神经网络 。下图给出了按时间展开的循环神经网络。
                                           由于循环神经网络具有短期记忆能力,相当于存储装置,因此其计算能力十分强大。 前馈神经网络可以模拟任何连续函数,而循环神经网络可以模拟任何程序。 
   定义一个完全连接的循环神经网络,其输入为  ,输出为  :
     
   其中  为隐状态,  为非线性激活函数,  和  为网络参数。
    这样一个完全连接的循环神经网络可以近似解决所有的可计算问题 。
   循环神经网络可以应用到很多不同类型的机器学习任务。根据这些任务的特点可以分为以下几种模式: 序列到类别模式、同步的序列到序列模式、异步的序列到序列模式 。
   序列到类别模式主要用于序列数据的分类问题:输入为序列,输出为类别。比如在文本分类中,输入数据为单词的序列,输出为该文本的类别。
   假设一个样本  为一个长度为  的序列,输出为一个类别  。我们可以将样本  按不同时刻输入到循环神经网络中,并得到不同时刻的隐藏状态  。我们可以将  看作整个序列的最终表示(或特征),并输入给分类器  进行分类:
     
   其中  可以是简单的线性分类器(比如Logistic 回归)或复杂的分类器(比如多层前馈神经网络)
   除了将最后时刻的状态作为序列表示之外,我们还可以对整个序列的所有状态进行平均,并用这个平均状态来作为整个序列的表示:
     
                                           同步的序列到序列模式 主要用于序列标注(Sequence Labeling)任务,即每一时刻都有输入和输出,输入序列和输出序列的长度相同 。比如词性标注(Partof-Speech Tagging)中,每一个单词都需要标注其对应的词性标签。
   输入为序列  ,输出为序列  。样本  按不同时刻输入到循环神经网络中,并得到不同时刻的隐状态  。每个时刻的隐状态  代表当前和历史的信息,并输入给分类器  得到当前时刻的标签  。
     
                                           异步的序列到序列模式也称为 编码器-解码器(Encoder-Decoder)模型,即输入序列和输出序列不需要有严格的对应关系,也不需要保持相同的长度。 比如在机器翻译中,输入为源语言的单词序列,输出为目标语言的单词序列。
   在异步的序列到序列模式中,输入为长度为  的序列  ,输出为长度为  的序列  。经常通过 先编码后解码 的方式来实现。先将样本  按不同时刻输入到一个循环神经网络(编码器)中,并得到其编码  。然后再使用另一个循环神经网络(解码器)中,得到输出序列  。为了建立输出序列之间的依赖关系,在解码器中通常使用非线性的自回归模型。
     
   其中  分别为用作编码器和解码器的循环神经网络,  为分类器,  为预测输出  的向量表示。
                                           循环神经网络的参数可以通过梯度下降方法来进行学习。给定一个训练样本  ,其中  为长度是  的输入序列,  是长度为  的标签序列。即在每个时刻  ,都有一个监督信息  ,我们定义时刻  的损失函数为:
     
   其中  为第  时刻的输出,  为可微分的损失函数,比如交叉熵。那么整个序列上损失函数为:
     
   整个序列的损失函数  关于参数  的梯度为:
     
   即每个时刻损失  对参数  的偏导数之和。
   循环神经网络中存在一个递归调用的函数  ,因此其计算参数梯度的方式和前馈神经网络不太相同。在循环神经网络中主要有两种计算梯度的方式: 随时间反向传播(BPTT)和实时循环学习(RTRL)算法。 
    随时间反向传播(Backpropagation Through Time,BPTT) 算法的主要思想是通过类似前馈神经网络的错误反向传播算法来进行计算梯度。
    BPTT算法将循环神经网络看作是一个展开的多层前馈网络,其中“每一层”对应循环网络中的“每个时刻”。在“展开”的前馈网络中,所有层的参数是共享的,因此参数的真实梯度是将所有“展开层”的参数梯度之和 。
   因为参数  和隐藏层在每个时刻  的净输入  有关,因此第  时刻的损失函数  关于参数  的梯度为:
     
   其中  表示“直接”偏导数,即公式  中保持  不变,对  求偏导数,得到:
     
   其中  为第  时刻隐状态的第  维;  除了第  个值为  外,其余都为  的行向量。
   定义误差项  为第  时刻的损失对第  时刻隐藏神经层的净输入  的导数,则:
     
   从而:
     
   写成矩阵形式为:
     
   由此得到整个序列的损失函数  关于参数  的梯度:
     
   同理可得,  关于权重  和偏置  的梯度为:
     
   在BPTT算法中,参数的梯度需要在一个完整的“前向”计算和“反向”计算后才能得到并进行参数更新。如下图所示。
                                            与反向传播的BPTT算法不同的是,实时循环学习(Real-Time Recurrent Learning)是通过前向传播的方式来计算梯度。 
   假设循环神经网络中第  时刻的状态  为:
     
   其关于参数  的偏导数为:
     
   RTRL算法从第1 个时刻开始,除了计算循环神经网络的隐状态之外,还依次前向计算偏导数  。
   两种学习算法比较:
   RTRL算法和BPTT算法都是基于梯度下降的算法,分别通过前向模式和反向模式应用链式法则来计算梯度。 在循环神经网络中,一般网络输出维度远低于输入维度,因此BPTT算法的计算量会更小,但BPTT算法需要保存所有时刻的中间梯度,空间复杂度较高。RTRL算法不需要梯度回传,因此非常适合于需要在线学习或无限序列的任务中 。
   循环神经网络在学习过程中的主要问题是由于 梯度消失或爆炸问题 ,很难建模长时间间隔(Long Range)的状态之间的依赖关系。
   在BPTT算法中,我们有:
     
   如果定义  ,则:
     
   若  ,当  时,  ,会造成系统不稳定,称为梯度爆炸问题;相反,若  ,当  时,  ,会出现和深度前馈神经网络类似的梯度消失问题。
   虽然简单循环网络理论上可以建立长时间间隔的状态之间的依赖关系,但是由于梯度爆炸或消失问题,实际上只能学习到短期的依赖关系。这样,如果t时刻的输出  依赖于  时刻的输入  ,当间隔  比较大时,简单神经网络很难建模这种长距离的依赖关系,称为 长程依赖问题(Long-Term dependencies Problem) 。
   一般而言,循环网络的梯度爆炸问题比较容易解决,一般 通过权重衰减或梯度截断来避免。 权重衰减是通过给参数增加  或  范数的正则化项来限制参数的取值范围,从而使得  。梯度截断是另一种有效的启发式方法,当梯度的模大于一定阈值时,就将它截断成为一个较小的数。
   梯度消失是循环网络的主要问题。除了使用一些优化技巧外,更有效的方式就是改变模型,比如让  ,同时使用  ,即:
     
   其中  是一个非线性函数,  为参数。
   上式中,  和  之间为线性依赖关系,且权重系数为1,这样就不存在梯度爆炸或消失问题。但是,这种改变也丢失了神经元在反馈边上的非线性激活的性质,因此也降低了模型的表示能力。
   为了避免这个缺点,我们可以采用一种更加有效的改进策略:
     
   这样  和  之间为既有线性关系,也有非线性关系,并且可以缓解梯度消失问题。但这种改进依然存在两个问题:
   为了解决这两个问题,可以通过引入 门控机制 来进一步改进模型。
   为了改善循环神经网络的长程依赖问题,一种非常好的解决方案是引入门控机制来控制信息的累积速度,包括 有选择地加入新的信息,并有选择地遗忘之前累积的信息 。这一类网络可以称为基于门控的循环神经网络(Gated RNN)。本节中,主要介绍两种基于门控的循环神经网络: 长短期记忆网络和门控循环单元网络。 
    长短期记忆(Long Short-Term Memory,LSTM)网络 是循环神经网络的一个变体,可以有效地解决简单循环神经网络的梯度爆炸或消失问题。
   在  基础上,LSTM网络主要改进在以下两个方面:
     
   其中  和  三个门(gate)来控制信息传递的路径;  为向量元素乘积;  为上一时刻的记忆单元;  是通过非线性函数得到的候选状态:
     
   在每个时刻  ,LSTM网络的内部状态  记录了到当前时刻为止的历史信息。
   在数字电路中,门(Gate)为一个二值变量{0, 1},0代表关闭状态,不许任何信息通过;1代表开放状态,允许所有信息通过。LSTM网络中的“门”是一种“软”门,取值在(0, 1) 之间,表示 以一定的比例运行信息通过 。LSTM网络中三个门的作用为:
   (1)遗忘门  控制上一个时刻的内部状态  需要遗忘多少信息。   (2)输入门  控制当前时刻的候选状态  有多少信息需要保存。   (3)输出门

循环神经网络

6. 分析RNN和NN(神经网络)的区别。

4.从处理输入来说,RNN可以用于处理单独的一个一个的输入。但是,当我们处理序列信息时,即前面的输入跟后面的输入是有关系的,普通的神经网络(NN)模型就无法实现了。【摘要】
分析RNN和NN(神经网络)的区别。【提问】
区别有好几方面,1.从名字上来说:RNN是循环神经网络,NN是神经网络【回答】
2.从定义上来说,传统的神经网络模型(左图),输入层(input layer)到隐藏层(hidden layer),隐藏层再到输出层(output layer),层与层之间是全连接的,但是隐藏层节点之间是无连接的。循环神经网络(右图),隐藏层节点之间是有连接的。【回答】
【回答】
3.从基本结构来看,在RNN中,每一层都共享参数U、V、W,降低了网络中需要学习的参数,提高学习效率。【回答】
U是输入层到隐藏层的权重矩阵。​ V是隐藏层到输出层的权重矩阵。【回答】
4.从处理输入来说,RNN可以用于处理单独的一个一个的输入。但是,当我们处理序列信息时,即前面的输入跟后面的输入是有关系的,普通的神经网络(NN)模型就无法实现了。【回答】

7. 几种常见的循环神经网络结构RNN、LSTM、GRU

 传统文本处理任务的方法中一般将TF-IDF向量作为特征输入。显而易见,这样的表示实际上丢失了输入的文本序列中每个单词的顺序。在神经网络的建模过程中,一般的前馈神经网络,如卷积神经网络,通常接受一个定长的向量作为输入。卷积神经网络对文本数据建模时,输入变长的字符串或者单词串,然后通过滑动窗口加池化的方式将原先的输入转换成一个固定长度的向量表示,这样做可以捕捉到原文本中的一些局部特征,但是两个单词之间的长距离依赖关系还是很难被学习到。   循环神经网络却能很好地处理文本数据变长并且有序的输入序列。它模拟了人阅读一篇文章的顺序,从前到后阅读文章中的每一个单词,将前面阅读到的有用信息编码到状态变量中去,从而拥有了一定的记忆能力,可以更好地理解之后的文本。   其网络结构如下图所示:
                                           由图可见,t是时刻,x是输入层,s是隐藏层,o是输出层,矩阵W就是隐藏层上一次的值作为这一次的输入的权重。
                                           如果反复把式 2 带入到式 1,将得到:
                                           其中f和g为激活函数,U为输入层到隐含层的权重矩阵,W为隐含层从上一时刻到下一时刻状态转移的权重矩阵。在文本分类任务中,f可以选取Tanh函数或者ReLU函数,g可以采用Softmax函数。
   通过最小化损失误差(即输出的y与真实类别之间的距离),我们可以不断训练网络,使得得到的循环神经网络可以准确地预测文本所属的类别,达到分类目的。相比于卷积神经网络等前馈神经网络,循环神经网络由于具备对序列顺序信息的刻画能力,往往能得到更准确的结果。
   RNN的训练算法为:BPTT   BPTT的基本原理和BP算法是一样的,同样是三步:   1.前向计算每个神经元的输出值;   2.反向计算每个神经元的误差项值,它是误差函数E对神经元j的加权输入的偏导数;   3.计算每个权重的梯度。   最后再用随机梯度下降算法更新权重。   具体参考: https://www.jianshu.com/p/39a99c88a565    最后由链式法则得到下面以雅可比矩阵来表达的每个权重的梯度:
                                                                                   由于预测的误差是沿着神经网络的每一层反向传播的,因此当雅克比矩阵的最大特征值大于1时,随着离输出越来越远,每层的梯度大小会呈指数增长,导致梯度爆炸;反之,若雅克比矩阵的最大特征值小于1,梯度的大小会呈指数缩小,产生梯度消失。对于普通的前馈网络来说,梯度消失意味着无法通过加深网络层次来改善神经网络的预测效果,因为无论如何加深网络,只有靠近输出的若干层才真正起到学习的作用。 这使得循环神经网络模型很难学习到输入序列中的长距离依赖关系 。
   关于RNN梯度下降的详细推导可以参考: https://zhuanlan.zhihu.com/p/44163528 
   梯度爆炸的问题可以通过梯度裁剪来缓解,即当梯度的范式大于某个给定值时,对梯度进行等比收缩。而梯度消失问题相对比较棘手,需要对模型本身进行改进。深度残差网络是对前馈神经网络的改进,通过残差学习的方式缓解了梯度消失的现象,从而使得我们能够学习到更深层的网络表示;而对于循环神经网络来说,长短时记忆模型及其变种门控循环单元等模型通过加入门控机制,很大程度上弥补了梯度消失所带来的损失。
   LSTM的网络机构图如下所示:
                                           与传统的循环神经网络相比,LSTM仍然是基于xt和ht−1来计算ht,只不过对内部的结构进行了更加精心的设计,加入了输入门it 、遗忘门ft以及输出门ot三个门和一个内部记忆单元ct。输入门控制当前计算的新状态以多大程度更新到记忆单元中;遗忘门控制前一步记忆单元中的信息有多大程度被遗忘掉;输出门控制当前的输出有多大程度上取决于当前的记忆单元。
   在经典的LSTM模型中,第t层的更新计算公式为
                                                                                                                                                                                                                                                   其中it是通过输入xt和上一步的隐含层输出ht−1进行线性变换,再经过激活函数σ得到的。输入门it的结果是向量,其中每个元素是0到1之间的实数,用于控制各维度流过阀门的信息量;Wi 、Ui两个矩阵和向量bi为输入门的参数,是在训练过程中需要学习得到的。遗忘门ft和输出门ot的计算方式与输入门类似,它们有各自的参数W、U和b。与传统的循环神经网络不同的是,从上一个记忆单元的状态ct−1到当前的状态ct的转移不一定完全取决于激活函数计算得到的状态,还由输入门和遗忘门来共同控制。
   在一个训练好的网络中,当输入的序列中没有重要信息时,LSTM的遗忘门的值接近于1,输入门的值接近于0,此时过去的记忆会被保存,从而实现了长期记忆功能;当输入的序列中出现了重要的信息时,LSTM应当把其存入记忆中,此时其输入门的值会接近于1;当输入的序列中出现了重要信息,且该信息意味着之前的记忆不再重要时,输入门的值接近1,而遗忘门的值接近于0,这样旧的记忆被遗忘,新的重要信息被记忆。经过这样的设计,整个网络更容易学习到序列之间的长期依赖。
   GRU是在LSTM上进行简化而得到的,GRU的网络结构如下所示:
                                           Zt代表更新门,更新门的作用类似于LSTM中的遗忘门和输入门,它能决定要丢弃哪些信息和要添加哪些新信息。   Rt代表重置门,重置门用于决定丢弃先前信息的程度。
   要注意的是,h只是一个变量,因此在每个时刻,包括最后的线性组合,h都是在用以前的自己和当前的备选答案更新自己。举例来说,这一个变量好比一杯酒,每次我们要把一部分酒倒出去,并把倒出去的酒和新加入的原料混合,然后在倒回来,这里的reset控制的就是要倒出去的,并且混合好之后再倒回来的酒的比例,而update控制的则是用多大的比例混合新原料和倒出来的之前调制好的酒。同理,也可以以此理解LSTM,LSTM的遗忘门功能上和reset相似,而输入门与update相似,不同之处在于LSTM还控制了当前状态的exposure,也就是输出门的功能,这是GRU所没有的。
   1.百面机器学习   2. https://zhuanlan.zhihu.com/p/45649187    3. https://www.jianshu.com/p/39a99c88a565 

几种常见的循环神经网络结构RNN、LSTM、GRU

8. CNN(卷积神经网络)、RNN(循环神经网络)、DNN(深度神经网络)的内部网络结构有什么区别?

如下:
1、DNN:存在着一个问题——无法对时间序列上的变化进行建模。然而,样本出现的时间顺序对于自然语言处理、语音识别、手写体识别等应用非常重要。对了适应这种需求,就出现了另一种神经网络结构——循环神经网络RNN。
2、CNN:每层神经元的信号只能向上一层传播,样本的处理在各个时刻独立,因此又被称为前向神经网络。
3、RNN:神经元的输出可以在下一个时间戳直接作用到自身,即第i层神经元在m时刻的输入,除了(i-1)层神经元在该时刻的输出外,还包括其自身在(m-1)时刻的输出!

介绍
神经网络技术起源于上世纪五、六十年代,当时叫感知机(perceptron),拥有输入层、输出层和一个隐含层。输入的特征向量通过隐含层变换达到输出层,在输出层得到分类结果。早期感知机的推动者是Rosenblatt。
在实际应用中,所谓的深度神经网络DNN,往往融合了多种已知的结构,包括卷积层或是LSTM单元。
最新文章
热门文章
推荐阅读