从动图中理解 RNN,LSTM 和 GRU

2024-05-08 00:59

1. 从动图中理解 RNN,LSTM 和 GRU

 递归神经网络(RNNs)是一类常用的序列数据人工神经网络。三种最常见的递归神经网络类型分别是: 
   要指出的一点是,我将使用"RNNS"来统称本质上是递归神经网络结构,"vanilla RNN"来指代在图一所展示的最简单的循环神经网络结构.
   有很多关于递归神经网络的图解.
   我个人最喜欢的一个是Michael Nguyen发表在《走向数据科学》(Towards Data Science)的这篇文章,因为他不仅给我们提供了对这些模型的直觉,更重要的是这些漂亮的插图,使我们更容易理解。但我发表这篇文章的动机是为了更好地理解这些单元中发生了什么,节点是如何共享的,以及它们是如何转换为输出节点。这里,我也受到了Michael的动画启发。 
   本文研究了vanilla RNN、LSTM和GRU单元。这是一个简短的概述,是为那些读过关于这些主题的文章的人准备的。(我建议在阅读本文之前先阅读Michael的文章),需要注意的是,以下动画是按顺序引导的,但在向量化的机器计算过程中并不反映时间上的顺序。
   下面是我用来做说明的图例:
      图0:动画图例
   在我的动画中,我使用了大小为3(绿色)的输入和2个隐藏单元(红色),批量大小为1。
   让我们开始吧!
   
      图1:vanilla RNN 示意动画
   
   图2:LSTM 示意动画
   注意,单元状态的维度与隐藏状态的维度相同。
   
      图3:GRU 示意动画
   希望这些动画能以某种方式帮助你!以下是静态图像中的概况:
      图4:Vanilla RNN 单元
      图5:LSTM 单元
      图6:GRU 单元
   一个提醒:我使用Google绘图来创建的这些示意图。
   
   想要继续查看该篇文章相关链接和参考文献?雷锋网雷锋网雷锋网
   点击【从动图中理解 RNN,LSTM 和 GRU】即可访问!
   今日资源推荐: CCF-GAIR | 张大鹏教授演讲 PPT:生物特征识别的新进展 - 纪念中国人工智能40年 
   非常高兴受邀参加本次会议,让我有机会汇报我的最新工作。今天我的讲题是“纪念中国人工智能40周年”,而我本人是中国学位法公布后首届入学的研究生,也是哈工大毕业的首个计算机博士,从 1980 年入学开始算起,我基本见证了中国人工智能这 40 年的发展历程。
   这是我研究生期间所能找到最早的一篇论文,选题与指纹识别有关。 1984 年,陈光熙教授是我的博士生导师,图片展示的是当年哈工大进行博士学位论文答辩的场景。
   点击链接获取:https://ai.yanxishe.com/page/resourceDetail/905

从动图中理解 RNN,LSTM 和 GRU

2. 了解RNN模型的基础单元LSTM、GRU、RQNN 与 SRU

RNN模型的基础结构是单元,其中比较常见的有LSTM单元,GRU单元等,它们充当了RNN模型中的基础结构部分。使用单元搭建出来的RNN模型会有更好的拟合效果。
  
 LSTM单元与GRU单元是RNN模型中最常见的单元,其内容由输入门、忘记门、和输出门三种结构组合而成。
  
 LSTM单元与GRU单元的作用几乎相同,唯一不同的是:
  
 相比之下,使用GRU单元会更加简单。
  
 QRNN(Quasi-Recurrent Neural Networks) 单元是一种RNN模型的基础单元,它比LSTM单元速度更快。
  
 QRNN单元发表于2016年。它使用卷积操作替代传统的循环结构,其网络结构介于RNN与CNN之间。
  
 QRNN内部的卷积结构可以将序列数据以矩阵方式同时运算,不再像循环结构那样必须按照序列顺序依次计算。其以并行的运算方式取代了串行,提升了运算速度。在训练时,卷积结构也要比循环结构的效果更加稳定。
  
 在实际应用中,QRNN 单元可以与RNN模型中的现有单元随意替换。
  
 了解更多,可以参考论文:
    Quasi-Recurrent Neural Networks 
  
 SRU单元是RNN模型的基础单元,它的作用与QRNN单元类似,也是对LSTM单元在速度方面进行了提升。
  
 LSTM单元必须要将样本按照序列顺序一个个地进行运算,才能够输出结果。这种运算方式使得单元无法在多台机器并行计算的环境中发挥最大的作用。
  
 SRU单元被发表于2017年。它保留LSTM单元的循环结构,通过调整运算先后顺序的方式(把矩阵乘法放在串行循环外,把相乘的再相加的运算放在串行循环内)提升了运算速度。
  
 若需要研究SRU单元更深层次理论,可以参考如下论文:
    Simple Recurrent Units for Highly Parallelizable Recurrence 
  
 关于函数tf.contrib.rnn.SRUCell 的更多使用方法,可以参照官方帮助文档。
    https://www.tensorflow.org/api_docs/python/tf/contrib/rnn/SRUCell 
    注:需要科学上网 
  
 github可以参考:
    https://github.com/tensorflow/tensorflow/blob/r1.15/tensorflow/contrib/rnn/python/ops/rnn_cell.py#L2738-L2816

3. lstm和gru结构的再理解

 我看大部分介绍rnn的文章里面都只画了cell的图,但是这对一个刚入门的人来说是会造成很大的误解,而正确的介绍方法应该先介绍rnn的总体结构,然后再介绍cell的结构。这才有可能对rnn有一个更清晰的认识。
   我们在网上多是看到这样的图
                                           cell是什么呢,我们首先回到MLP结构中
                                           RNN中的cell其实就是MLP结构中隐藏层的神经元。但是这个神经元有点特殊,它加入了时序的特点,所以不同时间段它的表达是不一样的。   所以,RNN正确的模型结构图应该是这样:
                                           横向是不同的时序,纵向是不同的层。这样是不是会更好理解了呢。
   而LSTM和GRU只是cell的变种形式,总体上RNN的结构是不变的。双向RNN的总体结构也没变,也只是cell的形式有所变化。
                                           好了,下面回到经常看到的图
                                           这张图是一个lstm的总体结构,我们知道,lstm里面最重要的概念是“门结构(gate)”,分为遗忘门,输入门和输出门。这里分4步来理解这个cell的结构。
                                           可以看到公式里面的[h, x],这里表示将这一时刻的输入x[t],和上一时刻t-1的输出h[t-1]做一个concat,然后经过sigmoid函数。
   因为sigmoid输出是0和1(大部分),这里面0和1与后面做乘法的时候,等于相应的让一些信息变成了0,就等于是忘记了一些信息。这里其实一个开关,控制信息的通过。
   举个例子,比如完形填空中填“他”或者“她”的问题,细胞状态可能包含当前主语的类别,当我们看到新的代词,我们希望忘记旧的代词。
                                           公式中[h,x]还是做的concat操作。   这里的意思可以看作为放什么新信息到细胞状态(C[t])中。   i[t]有一个sigmoid,类似于遗忘操作,这里就是对新知识的筛选, C`[t]可以将其看作全部的新知识。
                                           之前两补的操作就是为了更新细胞的状态,更新知识体系。包括让细胞忘记一些东西,然后给细胞补充新知识。
   这里另外说一点,为什么lstm可以解决RNN中梯度弥散/消失的问题。    因为C[t]是又两个结果相加得到,求导时会保留更新梯度。 
   
                                           
   lstm结构理解完了,其实gru结构的理解方式基本一致。还是那张图
                                           这里和lstm不同的是:
   如果r[t] = 1,z[t] = 1,那么gru和普通rnn的cell就是一样的。
   因为gru参数更少,所以gru训练起来比lstm更简单。   但是, 这两种cell最后的结果差不了太多! 用的时候不必纠结选择哪种结构。
   好了,lstm和gru说完了,下次来点新玩意,seq2seq和attention。

lstm和gru结构的再理解

4. 几种常见的循环神经网络结构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