12.循环神经网络

前文总结

之前已经讲了包括CNN结构、训练方法等,但是这些实际上只是一种前馈结构,所有的信息都是前向传播(有分支),每一层都接受单一输入(如图像等),每一层的输出都会进入下一层进行处理,最后输出一个单项,比如说一个完整的神经网络,我们输入一个图像,就可以输出一个标签(尽管这个标签未必是对的)

但是我们想要使用深度学习神经网络解决其他问题的话,CNN就难以解决了,比如说我们的输入不是一个,或者输出不是一个的情况(例如,输入一个序列,输出一个序列这样子)

此外,序列长度是不固定的,所以我们需要一种新方法来处理,这就是循环神经网络(Recurrent Neural Networks,RNN),实际上这种网络对于处理非顺序数据也非常有用(有人使用CNN来图像分类,每次读取图像的一小片)

MNIST的RNN处理示例

有人使用RNN,对MNIST数据集进行分类,不过其分类的方法不同于CNN,CNN是整张图像输入,RNN则是大量的“glimpses”,可以理解为每次看到图片的一小部分(大小不一定相等),看到多次之后进行分类

图像生成

RNN可以实现图像生成,输入一连串指令,然后RNN就可以生成一系列图像

循环神经网络

结构

CNN只有三部分,内部固定参数、输入、输出,即输入X,经过内部参数之后得到Y输出

但是RNN则不然,多了一个内部隐藏状态(或者叫内部状态),每一次输入之后,都会使用某种公式来更新这个状态,可以使用一个递归公式给出

16

其可以处理任意长度的序列,处理时间看序列中包含元素的个数,其处理的计时单位是时间步,一个时间步处理一个元素,但是循环网络和权重都是相同的

根据任务不同,网络的处理方法也不一样

  • 多对多的情况下,需要为序列中的每个点做出决定,类似于视频分类,我们需要为视频中的每一帧进行分类,这时候我们可以加上另一个权重矩阵 W Y W_Y WY,使得我们可以输出Y,然后处理得到标签 L n L_n Ln来进行预测,然后我们也可以在每一个时间步上应用损失函数来训练我们的模型:每个时间步的损失加在一起就是最终损失,然后就可以进行反向传播

    25

  • 多对一的情况下,我们最终产生一个标签,比如说我们想对这整个视频序列做一个分类,那么我们可以连接我们的模型,在序列的最后做一个预测

示例:Vanilla RNN

这是一个简单的循环神经网络

17

RNN计算图

我们以计算图的方式思考RNN是怎么工作的

22

我们首先给定一个初始状态 h 0 h_0 h0,然后不断在输入中进行更新,每一次我们都将状态和输入提供给递归关系函数,然后输出第一个隐藏状态,依次递归

注意一下,序列每次运算都是相同的矩阵,或者说在序列的每个时间步使用完全相同的权重矩阵,所以你可以看到在计算图中这表现为有一个不变节点W

Seq2Seq

序列到序列的学习(Sequence to Sequence,简称Seq2Seq)是一种广泛应用于自然语言处理(NLP)、语音识别、机器翻译等领域的深度学习方法。它的主要目的是将一个输入序列转换为一个输出序列,这两个序列的长度和内容可能会有所不同。

Seq2Seq模型通常由两个主要组件构成:编码器(Encoder)和解码器(Decoder)。

实际上,Seq2Seq就是先是一个多对一循环神经网络接受不定长度的输入序列(可能是英文句子),然后将整个序列的全部内容整合到一个输出的隐藏向量中,我们可以在编码器序列的末尾获取这个向量,然后将其作为单个输入提供给第二个循环神经网络(解码器),这是一个一对多循环神经网络

案例:语言模型

我们希望使用一个循环神经网络,接受数据之后来预测下一个字符或者单词是什么,这个称为语言模型

在训练的时候,我们使用独热向量来对输入序列进行编码,每个元素(一个字符)变成一个独热向量,然后输入到循环神经网络中进行处理,并且改变序列隐藏状态,然后我们就可以使用矩阵来预测每个点的词汇表中元素的分布,因为网络的任务是在每个时间点都试图预测序列中的下一个元素

32

如果已经有了一个训练有素的语言模型,可以用来生成新文本(以它学习到的文本的风格),这个过程是这样的

我们先给与一个初始种子(initial seed token,在这里给的是字符h),然后让网络生成以种子为条件的新文本,其工作方式将给予的种子转化为独热向量,然后得到对下一个字符的预测分布,然后采样出最有可能的字符,将其作为下一个时间步的输入,如此反复即可

40

训练方法

反向传播

BPTT(back-propagation through time)算法是常用的训练RNN的方法,其实本质还是BP算法,只不过RNN处理时间序列数据,所以要基于时间反向传播,故叫随时间反向传播算法。BPTT的中心思想和BP算法相同,沿着需要优化的参数的负梯度方向不断寻找更优的点直至收敛。综上所述,BPTT算法本质还是BP算法,BP算法本质还是梯度下降法,那么求各个参数的梯度便成了此算法的核心。

我们前面提到,循环神经网络的损失是将所有时间步上的损失进行相加,然后进行反向传播,但是这有一个问题,如果想处理很长的序列,这会耗费大量内存,尤其是一些超大的语言模型,所以我们在实践中训练循环神经网络的语言模型的时候,我们有时候会使用替代的近似算法,称为随时间截断的反向传播

我们要做的就是,截取序列的一些子集,比如说前十个序列或者前一百个序列,然后展开网络的前向传播,来计算梯度和传播,也就是说,我们将一些序列变为一个块,然后每个块来计算这个输出和梯度,这使得训练循环神经网络变得可行

也就是说,我们每给一块序列提供一个输入,得到输出之后就可以计算损失,然后就对这块序列进行训练

46

这样就可以携带隐藏状态一直向前,但是只会在某些时间步上进行反向传播,大大减小了训练难度

训练案例:莎士比亚作品集

53

这是将莎士比亚某个作品中的一段作为数据集进行训练的,可以看到,最开始就是胡言乱语,但是最后可以有逻辑的进行生成文本

甚至讲师还想用这个来训练抽象代数或者代数几何的文本内容(笑)

案例:图片说明

我们想为视频配上说明字幕,这也就是一个一对多问题

我们要输入一个图像将它提供给一个卷积网络来提取特征,然后将特征传递给循环神经网络,该模型将一次生成一个词来描述该图像的内容,这有些像迁移学习

在实际操作的时候,我们先对卷积神经网络进行截断,舍去其最后的两层

在这里,与语言模型不同的是,我们处理的是有限长度的数据(视频是有限长度的),所以我们需要关注具有一些实际的开始和结束,开始序列的第一个元素总是一个叫做start的特殊标记,这意味着这是一个新句子的开始

然后,我们需要以某种方式将来自卷积神经网络的数据连接到循环神经网络,或者说,我们将卷积网络输出的特征向量 v v v与矩阵 W i h W_{ih} Wih相乘,进行一次线性变换,然后使用隐藏状态和序列当前元素,结合在一起使用tanh函数进行压缩,然后不断进行处理,直至另一个特殊标记end出现为止

77

所以无论我们处理的有限长度序列是什么,将这两个额外的特殊标记添加到词汇表中是很常见的,一个称为开始标记,我们放在每个序列的开头,另一个称为结束标记,代表序列的结束

至于实际效果,总的来说还是很不错的,模型输出的不只是猫、狗、卡车这种单一标签,而是一连串的单词

79

但这些图像字幕模型实际上并没有那么聪明

80

比如说第一张图片,它说一个女人手里拿着一只猫,因为不知何故,女人外套的质地可能看起来有点像猫毛的质地,或者左下角图片中的把人拿着苹果手机认作人使用鼠标,或者中间图片的把一个倒立的人认作人拿着冲浪板

梯度爆炸/消失问题

循环神经网络也是使用梯度进行训练的,那么自然也会有这方面的问题

85

首先我们知道,在这个神经网络中我们是使用tanh函数进行非线性传递的,那么其反向传播的时候,tanh就会出现一些不好的情况

我们在一个单元里面计算梯度的话,它接受上流的梯度并且乘以本身的梯度并且传递下去,但是,当我们计算数以百计的单元的时候,如果最大奇异值大于一并且反复相乘,那么就会发生梯度爆炸,反之则会出现梯度消失

在这里,对于梯度爆炸问题,我们有一个方案,就是限制最大梯度,我们会检查局部梯度的欧几里得范数,如果太高就进行缩小,然后进行反向传播(如上图所示),这样就至少不会出现梯度爆炸问题了(虽然这个方法看起来很不学术)

对于梯度消失问题,大概研究者所做的事情就是换一种循环神经网络,比如说长短期记忆网络LSTM

LSTM:长短记忆神经网络

RNN的不足

RNN的关键点之一就是他们可以用来连接先前的信息到当前的任务上,例如使用过去的视频段来推测对当前段的理解。如果RNN可以做到这个,他们就变得非常有用。但是真的可以么?答案是,还有很多依赖因素。

有时候,我们仅仅需要知道先前的信息来执行当前的任务。例如,我们有一个语言模型用来基于先前的词来预测下一个词。如果我们试着预测这句话中“the clouds are in the sky”最后的这个词“sky”,我们并不再需要其他的信息,因为很显然下一个词应该是sky。在这样的场景中,相关的信息和预测的词位置之间的间隔是非常小的,RNN可以学会使用先前的信息

不幸的是,在这个间隔不断增大时,RNN会丧失学习到连接如此远的信息的能力。

在理论上,RNN绝对可以处理这样的长期依赖问题。人们可以仔细挑选参数来解决这类问题中的最初级形式,但在实践中,RNN则没法太好的学习到这些知识。Bengio,etal.(1994)等人对该问题进行了深入的研究,他们发现一些使训练RNN变得非常困难的相当根本的原因。

换句话说, RNN 会受到短时记忆的影响。如果一条序列足够长,那它们将很难将信息从较早的时间步传送到后面的时间步。

因此,如果你正在尝试处理一段文本进行预测,RNN 可能从一开始就会遗漏重要信息。在反向传播期间(反向传播是一个很重要的核心议题,本质是通过不断缩小误差去更新权值,从而不断去修正拟合的函数),RNN 会面临梯度消失的问题。

因为梯度是用于更新神经网络的权重值(新的权值 = 旧权值 - 学习率*梯度),梯度会随着时间的推移不断下降减少,而当梯度值变得非常小时,就不会继续学习。
换言之,在递归神经网络中,获得小梯度更新的层会停止学习—— 那些通常是较早的层。 由于这些层不学习,RNN会忘记它在较长序列中以前看到的内容,因此RNN只具有短时记忆

所以,RNN的一种变体,也就是LSTM出现了,可以一定程度上解决这两个问题

LSTM解析

LSTM的特点是,具有两个不同的隐藏向量,分别代表长时间记忆和短期记忆,其中一个为 C t C_t Ct,一个是 H t H_t Ht,前者称为细胞状态,后者称为隐藏状态

实际上第一篇LSTM论文是1997年发表的,但是近年来才开始热门起来,成为最常见的循环神经网络之一

91

在LSTM中,我们接受输入向量X和状态向量H,然后使用权重矩阵W进行线性映射,然后将输出分为四个不同向量,每个向量的大小为h,h是隐藏单元中元素数量,这也称为四个门(如图所示),而普通的循环神经网络则是矩阵乘法输出就是下一个隐藏状态,然后使用非线性函数进行输出

  • Gate Gate:经过tanh,值域在正负一之间,决定如何修改Cell的值,比如说是增加还是减少
  • Input Gate:告诉我们具体改变多少Cell的值
  • Forget Gate:决定细胞要丢弃哪些东西,它通过查看 h t − 1 h_{t-1} ht1 x t x_t xt信息来输出一个0-1之间的向量,该向量里面的0-1值表示细胞状态 C t − 1 C_{t-1} Ct1中的哪些信息保留或丢弃多少。0表示不保留,1表示都保留。
  • Output Gate:使用输入门、遗忘门和Gate门计算输出,我们使用tanh对细胞状态进行非线性压缩,然后使用输出门对隐藏状态进行改变

梯度流

LSTM单个单元的数据传递方式如下

93

一个很好的地方在于,Cell中只有加法和数乘,这对于梯度的反向传播是一个非常好的改进,便于LSTM在学习过程中保持信息流

Cell状态常被认为是一种LSTM的私有变量

LSTM某种意义上类似于ResNet,ResNet可以有数百层的深度,可以看到通过添加跨越不同层和深度卷积的连接的方式,来提供跨越多层的不间断梯度流

96

比如说我们有一连串的LSTM单元连接在一起,然后沿着序列进行处理,那么通过所有的细胞状态(Cell State)的上层路径形成了一条不间断的梯度高速公路,信息可以沿着这条高速公路非常容易地通过,这样,LSTM就可以长时间记住东西了

多层RNN

我们已经看到了对于处理图像的CNN来说,更多层通常性能更好,更多层通常允许模型在使用的任务上性能更好,所以我们自然而然的想到,我们能不能使用类似的方法来在RNN上堆叠不同的层,这也就是多层循环神经网络或者深度循环神经网络,一般是在隐藏状态序列之上应用另一个递归神经网络来做到这一点(如图所示)

99

在这里,我们有一个循环神经网络来处理原始输入序列,产生隐藏状态序列,然后隐藏状态序列被当做另一个循环神经网络的输入序列,然后产生第二个隐藏状态序列,如此循环多次;但是一般来说,循环神经网络的深度没有CNN那么深

在卷积神经网络中,不同的层我们会使用不同的权重矩阵,在这里也是一样的

猜你喜欢

转载自blog.csdn.net/qq_46202265/article/details/130646679
今日推荐