【CS231n 课程笔记】第十讲-----循环神经网络

目录

1.RNN

2.语言建模

3.反向传播

4.图像标注模型

5.视觉问答

6.多层递归神经网络

7.RNN反向传播

8.LSTM


1.RNN

之前我们看到了一种,“Vanulla”前馈网络网络,所有的网络架构都有这种基础架构,会接受一些输入,输入是固定尺寸的对象,比如一幅图片或一个向量,它在通过一些隐层后,给出单一的输出结果,如一个分类,如下图左一。但在机器学习中,有的时候我们希望有更加灵活的机器能够处理的数据类型。

这时候RNN就有很大的发挥空间,可以用RNN来处理各种类型的输入和输出数据,一旦使用RNN,我们可以实现一对多的模型,输入是固定尺寸的对象,但输出的是可变长度的序列,如一段文字描述,不同的描述可能造成单词量的不同,因此,输出值的长度需要是一个变量。如上图左二。

我们也有多对一的模型,即输入的尺寸是可变的,可能是一段文字,例如想得出一段文字的情感属性,或者在计算机视觉领域可以输入一个视频,视频的帧数可以是个变量,我们想要把整个视频当作输入,它有着可变的时间长度,最后做出分类决策,例如判断视频中做了什么运动或活动,。如上图左三。

还有一些情况我们希望输入和输出尺寸都是可变的,可能在机器翻译中可能碰到这种情况,如上图右二。

最后还可能遇到,输入是可变长度,比如视频帧数,我们要对该序列中的每个元素做出决策,在输入是视频的情况下,这一过程可能是对每一帧都做分类决策。RNN就是用于处理大小可变的有序数据的一类模型。使我们可以比较自然的理解模型中所有这些不同的架构。

所以RNN架构非常重要,即使对有固定输入大小和固定输出大小的问题,RNN也同样很有用。比如我们想对输入进行序列化处理,我们收到了一个固定大小的输入,如一幅图像,我们要做出分类决策,即图像中的数字是多少,我们不是做单一的前向传播,然后马上做出决策,而是看看图片,观察图片的各种不同部分,然后在完成观察后,做出最终决策,判断数字到底是几。

总体而言,每个RNN网络都有下面这样一个小小的循环核心单元,它把x作为输入,将其传入RNN,RNN有一个内部隐藏态,这一隐藏态会在RNN每次读取新的输入时更新,然后这一内部隐藏态会在模型下一次读取输入时将结果反馈至模型。

通常来说,我们想让RNN,在每一步时都能给出输出,因此就有了这样的模型,它读取输入,更新隐藏态,并且生成输出。

然后问题就是循环过程的计算公式,在绿色RNN模块中,我们对某种循环关系用f函数进行计算,这一f函数依赖权重W,它接收隐藏态ht-1,和当前态xt,然后会输出下一个隐藏态,或者更新后的隐藏态,我们称它为ht,接下来当我们读取下一个输入时,新的隐藏态ht,将再作为输入与xt+1传入同一个函数,如果我们想要在网络的每一步,都生成一些输出,那么我们可以增加全连接层,每一步都将ht作为输入。根据每一步的隐藏态,来做出决策。需要注意的是,我们在每一步都用的同样的函数f,和同样的权重w,

下图是vanilla RNN的公式,非常简单,在此架构中,如果我们想在每一时步都生成yt,可能需要另一个权值w来接受这一时刻隐藏态ht,转换为yt,如图最下面的公式

RNN可以从两方面思考,第一,它有一种隐藏态,可以循环反馈给自我,在第一时步,我们有初始隐层状态h0,通常情况下,h0=0,我们有现在的输入项xt,h0和xt会被代入fw函数中,计算得出下一个隐层状态h1,然后重复这个过程,直到用完输入项xt。这些块用着相同的权重。

每一步y可以计算一个损失值,最终的损失值是单独的损失值之和,最终的损失又会回溯到每一个时步的损失,然后每一个时步又会各自计算出在权重w上的梯度,它们的总和就是权重w的最终梯度,所以对于反向传播,我们可以计算每一个时步的梯度,最终的W梯度,是所有时步下独立计算出的梯度之和。

多对一:

 

一对多:

多对多问题可以看成是一对多和多对一的组合,这样就存在两个过程,分别是编码和解码,编码器会接受到一个不定长度的输入序列,可能是一个英语句子,然后整个句子会被编码器网络最终的隐层状态所编码,然后是一对多的情形,它的输入是前面编码完成的向量,生成的是一个不定长输出序列,对于这个不定长输入,我们会在每一个时步下做出预测,比如预测接下来的用词

 

2.语言建模

RNN会经常被用到语言建模问题上,在语言建模问题中,我们想要读取一些语句,从而让神经网络在一定程度上学会生成自然语言。举个例子,比如一个字符模型,网络会读取一串字符序列,然后它需要去预测这个文本流的下一个字符是什么。

在训练阶段,我们将这个字符序列作为输入项Xt,

因为每个输入实例是一个字母,所以需要在神经网络中表示这些字母,实际上我们要做的是找到在神经网络中整个单词的表示方式,在这个例子中单词由四个字母组成,用独热向量表示。随着网络的前向传播,在第一个时步中,神经网络会接受到输入h,该输入项会进入到神经网络第一个RNN单元内,之后输出yt,即网络对组成单词的每个字母做出的预测,也就是接下来它认为最可能出现的字母,因为我们的单词是'hello;,所以h后一个正确的字母应该是e,但是模型只是做预测,比如模型预测o是下一个字母,那么我们可以用sofmax损失函数来度量我们对这些预测结果的不满意程度。接下来的一个时步,我们将给模型输入在训练序列中的第二个字母,e,给模型一个输入向量,然后利用这个向量和之前计算出的隐层状态来生成输出一个新的隐层状态,并利用这第2个隐层状态,再一次对组成单词的其他字母做出预测。

在测试阶段,可以用这个训练好的神经网络模型生成新的文本。这里我们用的方法是通过输入一些文本的前缀,比如输入字母h,它会产生一个基于词库中所有的字母得分分布,我们会使用这些得分去输出一个结果,所以用softmax将得分转换为概率分布,然后我们会从这些概率分布中得到样本输出,去生成序列中的第二个字母e,在下一个时间步,e作为输入进这个网络,然后输出第三个样本,

然后我们重复这个过程,生成一个新的序列,该模型生成序列的过程,也是基于上一个时间步内,预测得到的概率分布,在下一个时间步内生成一个新的字母。

3.反向传播

假设我们有一个序列,每个时间步产生一个输出结果,然后计算一些损失值,这就是沿时间的反向传播方法,因为前向传播过程中我们沿时间做前向计算,误差反向传播过程中,我们会逆着时间反向计算所有的梯度,如果我们想要训练一个很长的序列,这个误差反向传播的过程会有些麻烦,在实际过程中,人们采用一种近似方法,我们称之为沿时间的截断反向传播方法,这个方法的思想是,即使我们输入的序列很长很长,我们训练过程中前向计算若干步,比如100步,然后沿着这个子序列反向传播误差,并计算梯度更新参数,当我们重复上述过程,仍然会得到网络中的一些隐藏状态(从第一批数据中计算得到),当我们计算下一批数据时,我们使用这些隐藏状态,所以前向计算过程是相同的,但是当我们基于下一批数据计算梯度时,我们只能根据第二批数据反向传播误差,现在我们基于沿时间的截断反向传播法计算一次梯度,这个过程会持续到我们使用下一批数据的时候,我们会复制这些隐藏层的状态值,但是前向计算和反向传播都是持续一定数量的时间步。

 

4.图像标注模型

图像标注模型指输入一个图像,然后输出自然语言的图像语义信息,

因为输出的语义信息可能是可变长度的字符序列,可能不同的标签有不同的字母数量,所以适合用循环神经网络模型。模型有一部分是卷积网络,用来处理输入图像的信息,它们将产生图像的特征向量,然后输入到接下来的RNN模型的第一个时序,模型一次产生一个单词。这里举一个例子。

在卷积神经网络过程中,我们不要最后的softmax层,而是使用来自模型末端的4096维向量。

                                                                      

我们有这个向量来概述整个图像的内容。在这个例子中,我们给循环网络一个特殊的开始记号,用以告知网络可以开始生成图像文字信息。之前的RNN语言模型中,我们得到的一些矩阵,矩阵把当前时间步的输入以及前一个时间步的隐藏状态结合得到下一个时间步的隐藏状态,我们现在需要添加图片信息,用一种不太相同的整合方式整合这些信息,一个简单的方式是加入第三个权重矩阵,即在每个时间步中添加图像信息来计算下一个隐藏状态

然后我们计算词汇表中所有分数的分布,词汇表可能很大,我们从分布中采样,并在下一次时间步时当作输入传回,即在下一个时间步中输入传回的词汇,然后得到一个关于所有词汇的分布,然后再取样产生下一个词,在这些事情做完后,我们就可以生成完整的句子了。一旦我们采样到特殊停止标记,就停止生成(对应于句子结束的时刻),这时候我们得到了这个图像的标题。我们采用监督学习的方式对模型进行学习,用带有自然语言标题的图像的数据集,微软的COCO训练集是应用最广泛的数据集。

 

5.视觉问答

模型将图片和一个用自然语言描述的问题作为输入,然后输出正确答案。

这是CNN和RNN连接起来得到的模型。这里多对一的情形,模型将自然语言序列作为输入,针对输入序列的每个元素建立递归神经网络,从而将输入的问题概括为一个向量,然后我们用CNN将图像也概括为一个向量,将CNN得出的向量和输入问题的向量结合(最简单的结合方式是将它们直接连接起来到全连接层中,更高级的做法比如可以在两个向量之间做乘法),通过RNN网络来预测答案的概率分布。

 

6.多层递归神经网络

我们之前讨论的都是单层递归神经网络,多层递归神经网络也很常见。

上图是以个三层循环神经网络结构,输出传进网络,然后在第一层的递归神经网络中产生一系列隐藏状态,我们运行第一层递归神经网络之后产生了第一层所有隐藏状态序列,然后将这个序列作为第二层递归神经网络的输入序列,以此类推。RNN与其他神经网络一样,也是层数越深表现越好,但一般来说实验2,3,4层的RNN就已经足够,很少用到特别深的RNN网络

 

7.RNN反向传播

RNN反向传播时,梯度沿如图红色箭头传播

因为当我们要计算,关于H0的损失函数的梯度时,反向传播需要经过递归神经网络的每一个单元,每次反向传播经过一个单元使,都要乘以其中某一个W的转置(有乘法门),这意味着最终对h0梯度的表达式会乘以很多矩阵。对于普通数字,步数很多时,对同一个数字做很多次乘法是非常糟糕的,这个数字绝对值大于1时可能发生梯度爆炸,绝对值小于1时,可能梯度消失,这个值恰好为1时,才能避免这些问题,但现实中很难见到这种情况。在矩阵中也类似,当我们用权重矩阵一个个相乘时,若矩阵的最大奇异值很大,最后得到的h0梯度矩阵会非常大,同理若奇异值很小,则情况相反,会梯度消失。

梯度截断是大家常用来解决梯度爆炸问题的方法,在我们计算梯度后,如果梯度的L2范数大于某个阈值,就将它剪断并做除法。

而对于梯度消失的问题,常见的做法是使用更加复杂的RNN结构,这就是使用LSTM网络的原因,即长短期记忆网络。

8.LSTM

LSTM是递归神经网络的一种更高级的递归结构,LSTM可以有效缓解梯度消失和梯度爆炸的问题。设计更好的结构,来获得更好地梯度流动,可以类比之前高级的CNN结构。

在LSTM中,每个时间步都维持两个隐藏状态,一个是ht,简单叫做隐藏状态,可以类比Vanilla RNN中对应的隐藏状态,但是LSTM还有第二个向量ct,叫做单元状态向量,这个单元状态向量相当于保留在LSTM内部的隐藏状态,并且不会完全暴露到外部去。首先我们可以用两个输入来计算四个门,i,f,o,g,我们使用这些门来更新单元状态ct,然后我们将这些单元状态作为参数来计算下一个时间步中的隐藏状态。

在LSTM中第一件要做的事情就是给定前一时刻的隐藏状态ht,LSTM中我们仍然拿上一时间步的隐藏状态和当前的输入拼接在一起,然后乘上一个非常大的权重矩阵W,计算得到四个不同的门向量,每个门向量的大小和隐藏状态向量一样,这四个门分别叫i,f,o,g。i表示input,表示LSTM要接受多少新的输入信息;f是forget,表示要遗忘多少之前的单元记忆,就是上一时间步的记忆信息;O是output,输出门,表示我们要展现多少信息给外部;G表示我们有多少信息要写到输入单元去。

这四个门都用了不同的非线性函数,i,f,o的输出值在0,1之间(因为用了sigmoid),g用了tanh,所以输出都在-1到1之间。上一时间步的单元状态经过了遗忘门操作,遗忘门中的值告诉我们对于单元状态中的每个元素,如果遗忘值的门是0,说明我们想要忘记这个单元状态中的元素值,如果是1,则表示要记住单元状态中的值,我们用遗忘值来断开部分单元的值后,我们需要使用输入门,即i和g做逐元素乘法,输入门告诉我们,对于单元状态的每个元素值,如果i的值是1,说明我们想要保留单元状态的元素,是0说明不保留。g中的值是当前时间步中我们可能会写入到单元状态中去的候选值。

我们看到单元状态中的公式,可以看到每个时间步中单元状态都有这些不同的独立的标量值,在每个时间步中可以被加一或者减去一,就是说在单元状态内部我们可以保留或者遗忘之前的状态,在每个时间步中,可以给单元状态的每个元素加上或者减去最多是1的值,所以可以把单元状态的每个元素看做是小的标量计数器,每个时间步中只能自增或者自减。

在计算了单元状态ct之后,我们将通过更新过的单元状态来计算隐状态ht,这个向量是要暴露到外部的,因为之前把单元状态解释成计数器,每个时间步都是加一或者减一,我们想要把这个计数通过tanh压缩到-1到1之间,现在用输出门逐元素乘上单元状态,输出门告诉我们对于每一个单元状态我们在每个时刻计算外部的隐状态时到底想不想暴露那个单元状态的元素(因为输出门也是0,1组成)

在原始RNN中,一些不好的现象在反向传播中出现,但在LSTM中不同,我们通过传输进来的单元获得上游梯度,然后我们通过加法运算后进行反向传播,这个加法运算仅仅是将上游的梯度复制到两个分支去,这样上游梯度直接被复制,然后通过元素相乘的方式直接贯穿了反向传播过程,然后上游的梯度最终通过遗忘门得到相乘后的元素,当我们通过这个单元状态反向传播时,对于上游梯度状态唯一会发生的事情就是它最终会通过遗忘门得到相乘后的元素,这比原始RNN好很多。原因有二,一是这里的遗忘门是矩阵元素相乘,而不是矩阵相乘;第二个原因是矩阵元素相乘时,可能会在不同的时间点乘以一个不同的遗忘门,但在原始RNN中,我们会不断乘以相同的权重矩阵,但LSTM中遗忘门在每一个时间点会发生变化,所以可以减缓梯度消失或梯度爆炸问题,而且遗忘门会乘以sigmoid函数,所以值为0和1,这也会使数值性质更好。

原始的RNN中,在每一个梯度传播的时间步长中都会经过一个tanh函数,但是现在一个LSTM中,我们的输出是使用隐藏状态来计算输出y_t,因此每一个隐藏状态从最后得隐藏单元状态反向传播到第一个单元状态,在反向传播的路径上我们只通过一个单一的非线性tanh反向传播,而不是在每一个时间步长中单独设置tanh函数,

这种通过单元状态进行反向传播的路径是一种梯度高速公路,它使得梯度相对畅通无阻地从模型末端的损失函数返回到模型最开始的初始单元状态。

LSTM实际上跟残差网络非常相似,残差网络中反向传播也有一条高速公路,与LSTM类似。 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值