Skip to content

5. 循环和递归神经网络RNN

bash
https://gitee.com/fakerlove/deep-learning

资料参考

bash
https://zybuluo.com/hanbingtao/note/541458

5.1 概念

文本分析或自然语言处理的递归神经网络(简称RNN)

5.1.1 概念

细想BP算法,CNN(卷积神经网络)我们会发现, 他们的输出都是只考虑前一个输入的影响而不考虑其它时刻输入的影响, 比如简单的猫,狗,手写数字等单个物体的识别具有较好的效果. 但是, 对于一些与时间先后有关的, 比如视频的下一时刻的预测,文档前后文内容的预测等, 这些算法的表现就不尽如人意了.因此, RNN就应运而生了.

RNN是一种特殊的神经网络结构, 它是根据"人的认知是基于过往的经验和记忆"这一观点提出的. 它与DNN,CNN不同的是: 它不仅考虑前一时刻的输入,而且赋予了网络对前面的内容的一种'记忆'功能.

RNN之所以称为循环神经网路,即一个序列当前的输出与前面的输出也有关。具体的表现形式为网络会对前面的信息进行记忆并应用于当前输出的计算中,即隐藏层之间的节点不再无连接而是有连接的,并且隐藏层的输入不仅包括输入层的输出还包括上一时刻隐藏层的输出。

RNN是两种神经网络模型的缩写,一种是递归神经网络(Recursive Neural Network),一种是循环神经网络(Recurrent Neural Network)

变形网络

RNN虽然解决了CNN无法处理的问题,但其本身仍然有些缺点,所以现在很多RNN的变形网络,其中最常被使用的网络之一为长短记忆网络(Long Short-Term Network,简称LSTM)。

这类网络的输入数据不限于是图像或文字,解决的问题也不限于翻译或文字理解。数值相关数据也同样可以使用LSTM进行分析,例如工厂机器预测性维修应用,可透过LSTM分析机台震动讯号,预测机器是否故障。在医学方面,LSTM可协助解读数以千计的文献,并找出特定癌症的相关信息,例如肿瘤部位、肿瘤大小、期数,甚至治疗方针或存活率等等,透过文字理解进行解析。也可结合图像识别提供病灶关键词,以协助医生撰写病理报告。

5.1.2 用途

RNN的应用领域有很多, 可以说只要考虑时间先后顺序的问题都可以使用RNN来解决.这里主要说一下几个常见的应用领域:

  • 自然语言处理(NLP): 主要有视频处理, 文本生成, 语言模型, 图像处理
  • 机器翻译, 机器写小说
  • 语音识别
  • 图像描述生成
  • 文本相似度计算
  • 音乐推荐网易考拉商品推荐Youtube视频推荐等新的应用领域.

有别于CNN,RNN的特色在于可处理图像或数值数据,并且由于网络本身具有记忆能力,可学习具有前后相关的数据类型。例如进行语言翻译或文本翻译,一个句子中的前后词汇通常会有一定的关系,但CNN网络无法学习到这层关系,而RNN因具有内存,所以性能会比较好。因为可以通过RNN进行文字理解,其他应用如输入一张图像,但是输出为一段关于图像叙述的句子。(如下图)

img

5.1.3 例子

我的手机坏了,我打算____一部新手机。

可以想象,如果我们只看横线前面的词,手机坏了,那么我是打算修一修?换一部新的?还是大哭一场?这些都是无法确定的。但如果我们也看到了横线后面的词是『一部新手机』,那么,横线上的词填『买』的概率就大得多了。

例二

我们先来看一个NLP很常见的问题,命名实体识别,举个例子,现在有两句话:

第一句话:I like eating apple!(我喜欢吃苹果!)

第二句话:The Apple is a great company!(苹果真是一家很棒的公司!)

现在的任务是要给apple打Label,我们都知道第一个apple是一种水果,第二个apple是苹果公司,假设我们现在有大量的已经标记好的数据以供训练模型,当我们使用全连接的神经网络时,我们做法是把apple这个单词的特征向量输入到我们的模型中(如下图),在输出结果时,让我们的label里,正确的label概率最大,来训练模型,但我们的语料库中,有的apple的label是水果,有的label是公司,这将导致,模型在训练的过程中,预测的准确程度,取决于训练集中哪个label多一些,这样的模型对于我们来说完全没有作用。问题就出在了我们没有结合上下文去训练模型,而是单独的在训练apple这个单词的label,这也是全连接神经网络模型所不能做到的,于是就有了我们的循环神经网络。

5.2 结构介绍

资料参考

bash
https://blog.csdn.net/the_future_way/article/details/118734283

参考资料2

bash
https://www.jianshu.com/p/87aa03352eb9

参考资料3

bash
https://blog.csdn.net/qq_32241189/article/details/80461635

参考资料4

bash
https://zhuanlan.zhihu.com/p/123211148

5.2.1 原理介绍

循环神经网络的原理并不十分复杂,本节主要从原理上分析RNN的结构和功能,不涉及RNN的数学推导和证明,整个网络只有简单的输入输出和网络状态参数。一个典型的RNN神经网络如图所示:

在这里插入图片描述

我们现在这样来理解,如果把上面有W的那个带箭头的圈去掉,它就变成了最普通的全连接神经网络。

x是一个向量,它表示输入层的值(这里面没有画出来表示神经元节点的圆圈);

s是一个向量,它表示隐藏层的值(这里隐藏层面画了一个节点,你也可以想象这一层其实是多个节点,节点数与向量s的维度相同);

U是输入层到隐藏层的权重矩阵,o也是一个向量,它表示输出层的值;

V是隐藏层到输出层的权重矩阵。

循环神经网络的隐藏层的值s不仅仅取决于当前这次的输入x,还取决于上一次隐藏层的值s。

权重矩阵W就是隐藏层上一次的值作为这一次的输入的权重。

我们给出这个抽象图对应的具体图:

在这里插入图片描述

表示时间序列. ​表示输入的样本. 表示样本在时间处的的记忆,

​. W表示输入的权重, U表示此刻输入的样本的权重, V表示输出的样本权重.

​时刻, 一般初始化输入​, 随机初始化​, 进行下面的公式计算:

其中,均为激活函数. 其中f可以是tanh,relu,sigmoid等激活函数,g通常是softmax也可以是其他。

时间就向前推进,此时的状态作为时刻1的记忆状态将参与下一个时刻的预测活动,也就是:

我们可以用下面的公式来表示循环神经网络的计算方法:

的值不仅仅取决于,还取决于

​是t时刻输出层的计算公式,输出层是一个全连接层,也就是它的每个节点都和隐藏层的每个节点相连。V是输出层的权重矩阵,g是激活函数。

​是t时刻隐藏层的计算公式,它是循环层。U是输入x的权重矩阵,W是上一次的值作为这一次的输入的权重矩阵,f是激活函数。

这就是为什么循环神经网络可以往前看任意多个输入值的原因。

注意点

  • 这里的W,U,V在每个时刻都是相等的(权重共享).
  • 隐藏状态可以理解为: S=f(现有的输入+过去记忆总结)

5.2.2 RNN的反向传播

每一次的输出值都会产生一个误差值, 则总的误差可以表示为

可以使用交叉熵损失函数也可以使用平方误差损失函数.

由于每一步的输出不仅仅依赖当前步的网络,并且还需要前若干步网络的状态,那么这种BP改版的算法叫做Backpropagation Through Time(BPTT) , 也就是将输出端的误差值反向传递,运用梯度下降法进行更新。

也就是要求参数的梯度:

由前面的W的更新可以看出它是每个时刻的偏差的偏导数之和.

在这里我们以时刻为例, 根据链式求导法则可以得到​时刻的偏导数为:

此时根据公式​我们会发现,​除了和W有关之外,还和前一时刻​有关

对于S3直接展开得到下面的式子:

对于S2直接展开得到下面的式子:

对于S1直接展开得到下面的式子:

5.2.3 例子

假设现在我们已经训练好了一个RNN,如图,我们假设每个单词的特征向量是二维的,也就是输入层的维度是二维,且隐藏层也假设是二维,输出也假设是二维,所有权重的值都为1且没有偏差且所有激活函数都是线性函数,现在输入一个序列,到该模型中,我们来一步步求解出输出序列:

输入矩阵:

绿色的为隐藏层

黄色的为输入层

粉红色的为输出层

img

你可能会好奇W去哪了?W在实际的计算中,在图像中表示非常困难 ,所以我们可以想象上一时刻的隐藏层的值是被存起来,等下一时刻的隐藏层进来时,上一时刻的隐藏层的值通过与权重相乘,两者相加便得到了下一时刻真正的隐藏层,如图可以看做每一时刻存下来的值,当然初始时​是没有存值的,因此初始值为0

img

当我们输入第一个序列,[1,1],如下图,其中隐藏层的值,也就是绿色神经元,是通过公式计算得到的,

因为所有权重都是1,所以也就是(我把向量X拆开计算的,只详细列了其中一个神经元的计算过程),

输出层的值4是通过公式计算得到的,也就是​,(同上,也是只举例其中一个神经元,得到输出向量【4,4】

img

当[1,1]输入过后,我们的记忆里的已经不是0了,而是把这一时刻的隐藏状态放在里面,即变成了2,如图,

输入下一个向量[1,1],隐藏层的值通过公式,得到

输出层的值通过公式得到,最终得到输出向量[12,12]

img

同理,该时刻过后的值变成了6,也就是输入第二个【1,1】过后所存下来的值,同理,输入第三个向量【2,2】,如图,细节过程不再描述,得到输出向量【32,32】:

img

由此,我们得到了最终的输出序列为:

输出矩阵:

至此,一个完整的RNN结构我们已经经历了一遍,我们注意到,每一时刻的输出结果都与上一时刻的输入有着非常大的关系,如果我们将输入序列换个顺序,那么我们得到的结果也将是截然不同,这就是RNN的特性,可以处理序列数据,同时对序列也很敏感。

5.3 LSTM

梯度消失和爆炸的问题

5.4 GRU