递归神经网络怎么解决时序数据分析算法问题的算法

递归神经网络_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
递归神经网络
上传于||文档简介
&&递​归​神​经​网​络​简​介
阅读已结束,如果下载本文需要使用0下载券
想免费下载更多文档?
定制HR最喜欢的简历
下载文档到电脑,查找使用更方便
还剩2页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢大数据(508)

深入探究递归神经网络:大牛级的训练和优化如何修成?
摘要:不同于传统FNN,RNN无需在层面之间构建,同时引入定向循环,能够更好地处理高维度信息的整体逻辑顺序。本文中,MIT的Nikhil Buduma将带您深入探析RNN的原理、训练和优化等各方面的内容,以及RNN已经获取的一些成就。
在深度学习领域,传统的前馈神经网络(feed-forward neural net,简称FNN)具有出色的表现,取得了许多成功,它曾在许多不同的任务上——包括手写数字识别和目标分类上创造了记录。甚至到了今天,FNN在解决分类任务上始终都比其他方法要略胜一筹。
尽管如此,大多数专家还是会达成共识:FNN可以实现的功能仍然相当有限。究其原因,人类的大脑有着惊人的计算功能,而“分类”任务仅仅是其中很小的一个组成部分。我们不仅能够识别个体案例,更能分析输入信息之间的整体逻辑序列。这些信息序列富含有大量的内容,信息彼此间有着复杂的时间关联性,并且信息长度各种各样。例如视觉、开车、演讲还有理解能力,这些都需要我们同时处理高维度的多种输入信息,因为它们时时都在变化,而这是FNN在建模时就极为匮乏的。
现在的问题在于如何学习信息的逻辑顺序,解决这一问题有一个相当靠谱的途径,那就是递归神经网络(Recurrent Neural Net,简称RNN)。
RNN是什么?
RNN建立在与FNN相同的计算单元上,两者之间区别在于:组成这些神经元相互关联的架构有所不同。FNN是建立在层面之上,其中信息从输入单元向输出单元单向流动,在这些连通模式中并不存在不定向的循环。尽管大脑的神经元确实在层面之间的连接上包含有不定向循环,我们还是加入了这些限制条件,以牺牲计算的功能性为代价来简化这一训练过程。因此,为了创建更为强大的计算系统,我们允许RNN打破这些人为设定强加性质的规定:RNN无需在层面之间构建,同时定向循环也会出现。事实上,神经元在实际中是允许彼此相连的。
RNN例图,包含直接循环和内部连通
RNN包含输入单元(input units)群,我们将其标记为u1,u2直到uK,而输出单元(output units)群则被标记为y1,y2直到yL。RNN还包含隐藏单元(hidden units),我们将其标记为x1,x2直到xN,这些隐藏单元完成了最为有意思的工作。你会发现,在例图中:有一条单向流动的信息流是从输入单元到达隐藏单元的,与此同时另一条单向流动的信息流从隐藏单元到达输出单元。在某些情况下,RNN会打破后者的限制,引导信息从输出单元返回隐藏单元,这些被称为“backprojections”,不让RNN分析更加复杂。我们在这里讨论的技术同样适用于包含backprojections的RNN。
训练RNN存在很多相当具有挑战性的难题,而这仍是一个非常活跃的研究领域。了解概念之后,本文将带您深入探析RNN的原理、训练和优化等各方面的内容,以及RNN已经获取的一些成就。
现在我们了解到RNN的结构了,可以讨论一下RNN模拟一系列事件的方式。举个简单的例子,下文中的这个RNN的运作方式类似一个计时器模块,这是由Herbert Jaeger设计的一个经典案例(他的原稿请点击查看)。
简单案例:一个完美的RNN如何模拟计时器
在这个例子中,我们有两个输入单元,输入单元u1相当于一个二进制开关,峰值时数值为1(在RNN开始计时的时候);输入单元u2是一个离散变量,其取值范围在0.1到1.0之间变化,指的是计时器如果在那一瞬间开启,则输出值相应开启的长度。在RNN的规范中,要求它将输出结果持续在1000 u2的区间里开启。最终,训练案例中的输出结果会在0(关闭)与0.5(开启)之间来回拨动。
但是,一个神经网络究竟是如何完成这个计算的呢?首先,RNN的所有隐藏层行为会被初始化成为一些预设的状态,然后在每个时间步长中(时间 t =1,2,……),所有的隐藏单元通过外部连接发送其当前的行为,再通过其他神经元(如果有自我连接则包括自身)的输入和当前值的输入,进行加权求和(logit)之后重新计算出新的行为,然后将其写入神经元的特定功能中(简单的复制操作,可调函数,soft-max等等)。因为之前的行为矢量被用在计算每个时间步长的行为矢量中,RNN可以保留之前的事件记忆并使用该记忆来做决定。
显然一个神经网络不大可能完全根据规范而构建,但是可以想象一下,在RNN的训练进行过数百次或数千次之后,其输出结果(橙色)会非常接近客观数据(蓝色)。下文中我们会对RNN训练的方式进行更多讨论。
经过良好的训练后,RNN在实验案例中接近输出测试用例
此时此刻,你可能觉得这相当酷,但是有相当多的案例都很不自然。实践中运用RNN的策略是什么呢?我们调查了真实的系统以及随着时间流逝它们对于刺激物的回应行为。举例来说,你可以教会一个RNN通过建立一个数据组将声频转化为文字(在某种意义上,在训练组中观察人类的听觉系统对于输入内容的回应)。你还可以使用一个训练过的神经网络来模拟一个系统在异常刺激下的反映。
RNN在实践中如何运用
但是如果你富有创意的话,可以通过更为惊人方式来使用RNN,比如一种专门的RNN——LSTM(Long Short-Term Memory),就已经被用来实现规模巨大的数据压缩比率了,尽管目前基于RNN的压缩方法还需要花费大量的时间。(后文将有详细解释。)
通过时间进行RNN-BP(BackPropagation)算法的训练
我们一开始又是如何对RNN进行训练,让它来完成所有这些惊人的功能呢?尤其我们是如何确定每个连接的强度(或称权值)呢?我们又是如何从所有隐藏单元中选择初始行为的呢?我们的第一反应可能是直接使用BP算法,毕竟这种算法在FNN中使用过而且效果良好。
这里使用BP算法的问题在于我们有着周期性的依赖关系。在FNN中,我们在针对一个层面中的权值来计算误差衍生时,可以根据上一层面中的误差衍生对其进行完全表达。RNN中并没有这种漂亮的分层,因为神经元并未组成有向非循环图。在RNN中使用BP算法可能会迫使我们根据它自身来进行误差衍生的表达,这样会使分析复杂化。
因此,使用BP算法需要执行一个机智的转化:将RNN转化为一个新的架构,这个新架构在本质上来说就是一个FNN,我们将这个策略称为通过时间“展开”RNN。下面图表中有一个样例(为了简化起见,每个时间步长中只有一个输入/输出):
通过时间将RNN“展开”以使用BP算法
具体步骤非常简单,但对我们分析神经网络的能力有着深远的影响。我们将RNN输入、输出、隐藏单元和复制分别看作时间步长。在我们的新FNN中,这些分别对应着不同的层面,然后我们将隐藏单元按照下面的方式连接起来,在原始的RNN中,w表示从神经元i到神经元j的连接强度(即权值),而在新的FNN中,我们画出一个连接w的图,分别连接每个tk层中的神经元i和每个tk+1层中的神经元j。
这样一来,为了训练RNN,我们取随机的初始化权值,将其“展开”到FNN中,然后通过BP算法以确定最佳权值。为了确定时间0时隐藏状态的赋初值,我们可以将初始行为视作注入FNN底层的参数,然后通过BP算法以确定其最佳值。
但是这里我们遇到了一个问题:在使用过每一批训练案例之后,我们需要基于计算出的误差衍生来修正权值。在FNN中,我们有一套连接关系,全部与原始的RNN中同样的连接关系相对应。但是,根据权值计算出的误差衍生却无法保证是相同的,也就是说我们可能会用不同的数量来修正误差。我们当然不想变成这样!
对于这一问题,我们的解决办法是:将同一组中所有连接的误差衍生求平均值(或者求和)。也就是说每一批训练之后,我们会用相同的数量来修正相应连接,因此如果它们的赋初值相同,则最终值也会相同,这很好地解决了我们的问题。
深层BP算法的问题
不同于传统的FNN,由展开RNN而产生的FNN可能会有非常多层。这就产生了一个严重的现实问题:通过时间手段使用BP算法来进行训练可能会变得非常困难。让我们退回一步,研究一下原因。
我们试着训练RNN做一个非常简单的工作:先给RNN的一个隐藏单元赋予一个偏差值,然后把它与自身还有一个单一的输出接口相连接。我们希望这个神经网络在50步以后输出一个固定目标值,这个值我们设定为0.7。这样我们在将要在第50步的时候,使用输出的均方误差(squared error)作为误差函数,就能通过权值和偏差值画出一个曲面:
一个简单的RNN的问题误差曲面(图片出自:)
现在,假定我们从红色五角星处开始(使用一个随机的权值赋初值),你会注意到:在使用梯度下降(gradient descent)的时候,图线会越来越趋近于曲面的局部最小值。但是突然间,在稍微越过低谷并触及峭壁的时候,在相反方向出现一个巨大的梯度,这就使得我们向反方向反弹并远离局部最小值。一旦我们进入了虚空中,就会很快发现:梯度几近消失,想要再次接近则需要近乎无穷的时间。这个问题被称做“梯度的爆发与消失”(exploding and vanishing gradients),可以想象一下:我们可以通过改变梯度值,让它永远不要超过最大值来控制这个问题(请看撞到峭壁后点线的路径),但是这个方法仍然不是非常有效,尤其是在更复杂的RNN中。(想要查看这个问题的数学处理方法,请查看这篇。)
长短时记忆
为了解决这些问题,研究人员提出了RNN的修正架构,以协助在强制的输入、适当的回应与防止梯度爆发之间建立一个长期的时滞。这个架构强制其在特殊记忆单元中的内部状态保持一个常数误差流(constant error flow),这样一来图线既不会爆发也不会消失。这个长短时记忆(LSTM)架构利用了下面结构中显示的单元:
基本的LSTM单元架构
LSTM单元包含一个尝试将信息储存较久的存储单元。这个记忆单元的入口被一些特殊的门神经元(gate neurons)所保护,被保护的功能包括保存、写入和读取操作。这些门神经元都是logistic units,它们不会将自己的行为作为输入值发送给其他神经元,而是负责在神经网络的其它部分与记忆单元连接的边缘处设定权值。这个记忆单元是一个线型的神经元,有自体内部连接。当保存门被打开时(如1中的行为),自体连接权值为1,记忆单元将内容写入自身。当保存门输出为0时,记忆单元会清除之前的内容。写入门允许在输出值为1的时候,神经网络的其它部分将内容写入记忆单元,而读取门则允许在输出值为1的时候,神经网络的其它部分读取记忆单元。
因此,这个操作究竟是如何保持一个时间的常数误差流,从而在局部防止爆发与消失梯度的产生呢?为了更加形象化,我们将LSTM单元按照时间展开:
通过时间区域展开LSTM单元
首先,保存门被设定为0,写入门被设定为1,并在记忆单元中存入4.2这个值。在随后保存值为1的时候,4.2这个值一直被保存在记忆单元中,拒绝值为0时的读取或写入,最终这个单元在被读取后清除。现在,让我们试着从4.2这个值被载入记忆单元的那一刻起进行BP算法,直到从记忆单元中读出4.2的那一刻并随之将其清除为止。我们发现,根据记忆神经的线型本质,我们从读取点到写入点接收到的BP误差派生的变化完全可以忽略,因为通过所有时间层连接记忆单元的连接权值加权后约等于1。因此,我们可以在几百步中对这个误差派生值进行局部保存,而无需担心梯度的爆发或消失。
LSTM RNN非常有效,而且同样适用于很多其他领域。我们早些时候讨论过,LSTM RNN的深层架构被用于实现了相当惊人的数据压缩率。(如果对LSTM RNN的特定应用有兴趣,可以查看这篇做更深入的了解。)
有效进行神经网络训练的相关方法仍旧是一个活跃的研究领域,并引出了大量置换手段,目前尚无哪一种表现出明显的优势。LSTM RNN架构就是这样一个提高RNN训练的方法。还有一个方法就是使用更好的最优化控制器来对付梯度的爆炸与消失。Hessian-free优化器尝试通过小型梯度探测方向,甚至带来了更小的曲度,这使得它比单纯的梯度下降表现更佳。三分之一的方法涉及到权值谨慎的赋初值,期望借此避免头一个梯度爆发和消失的问题(例如:反射状态网络,基于动量的方法)。
原文链接:&(编译/孙薇 校对/周建丁)
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:213326次
积分:3413
积分:3413
排名:第7603名
原创:22篇
转载:682篇
评论:22条
(8)(10)(9)(14)(9)(39)(64)(37)(4)(2)(18)(61)(27)(26)(64)(25)(39)(18)(11)(19)(34)(29)(41)(32)(48)(30)400-189-8992
当前位置: >> 实验室报告
>>cuDNN 5中的递归神经网络(RNN)优化
cuDNN 5中的递归神经网络(RNN)优化
作者/来源:Jeremy Appleyard/GPUS技术部门翻译&&&&
发布于:&&&&
点击数:791
图表1: cuDNN 5 + Torch 加速 对比&Torch-rnn 实现,M40,Intel(R) Xeon(R) Processor E5-2698
网络A:&RNN 尺寸&2560,输入尺寸2560,1 层(layer), 序列长度200,&批尺寸(batch size)64
网络B: RNN 尺寸256,输入尺寸64,3层(layers),批尺寸(batch size)64
网络C:RNN 尺寸&256,&输入尺寸256,&1 层(layer),批尺寸(batch size)32,&序列长度1000
& & & 在英伟达GTC 2016上,英伟达发布了NVIDIA 深度学习SDK的最新更新版,&其中囊括了cuDNN 5。在这个第5版中新增加了几项新功能、对性能进行了改进,并对提供了支持.。cuDNN 5中的新功能包括:
1.使用威诺格拉德(Winograd)卷积算法时实现更快速的正、反卷积速度;
2.三维快速傅里叶变换平铺(3D FFT Tiling);
3.空间变换网络(Spatial Transformer Networks);
4.改进了性能并降低了在Pascal GPU上运行FP16半精度程序时的内存消耗;
5.支持用于实现序列学习的LSTM(长短期记忆)递归神经网络,速度提升6倍。
& & & 英伟达在&&中增加的一项新功能就是支持神经递归网络(RNN)。RNN 是一个用于多领域序列学习的强大工具,从语音识别到为影像添加字幕。要获得RNN、LSTM和序列学习更高层的介绍,我推荐你去看一下Tim Dettmers 近期的文章《》,要更深入的了解,请阅读&Soumith Chintala的文章《》。
& & & 我对于cuDNN 5对RNN的支持能力感到很激动;&我们对于它们在NVIDIA GPU上的性能优化方面做出了很多努力,而对于优化方面的细节,我也会在这篇博文上发布出来。
& & & &cuDNN 5 支持四种RNN 模式:&&ReLU(修正线性单元)激活函数,tanh(双曲正切)激活函数,&门递归单元(GRU&- Gated Recurrent Units),&以及长短期记忆(LSTM)。&在本例中,我将着眼于LSTM 神经网络,但大多数优化均可用于任意一种RNN之中。
步骤1:&优化单次迭代
下列等式用于控制LSTM单元中数据的正向传播。图表2 是LSTM 单元的示意图。
图表2&LSTM 单元的示意图
& & & &&从计算的角度来看,此处可归结为八次矩阵-矩阵相乘(GEMM)—&四次输入&i,四次输入h&—&以及很多逐点操作。
& & & & 在这个案例分析中的出发点是LSTM的逐步实现。对于每一次迭代、每一层,在实现过程中都要调用cuBLAS sgemm来实现八次矩阵乘法中的每一步,手动编写的CUDA内核来调用逐点操作的每一步。实现方法的伪代码如下所示。&
for layer in layers:&&
& & for iteration in iterations:&&&&
& & & & perform 4 SGEMMs on input from last layer&&&&
& & & &&perform 4 SGEMMs on input from last iteration&&&&&
& & & &&perform 逐点操作
& & & &我计算出在Tesla M40 GPU上的每一步、每一层的运算时间,来作为对照数据。我的对照LSTM数据为512个隐藏单元、计算的最小批尺寸为64。这一基础成绩相当的低,在M40上仅达到大约350 GFLOPS。而这块GPU 的峰值性能大约为6000 GFLOPS,因此还有很大的提升空间,让我们开始吧。
优化1:合并GEMM操作
& & & &GPU具有非常高的浮点吞吐量峰值,不过它们需要进行很多并行化处理来达到这一峰值。你对它们进行的并行化工作越多,它们的性能就会越高。剖析一下LSTM 代码就可以看到,GEMM操作所使用的CUDA线程块(thread blocks)&要明显少于GPU上的SM数量,表明GPU还有很大程度的闲置。
& & & &GEMM对于输出的矩阵阶数而言是一种典型的并行化操作,每个线程都会进行大量最高效能的输出计算。在这个案例中,八次输出矩阵中的每一个都包含有512×64个元素,其结果只占据四个线程块。原则上可以运行的块要比GPU所具有SM数量更多,要达到这个内核的理论最大占用率,每个SM至少要有四个块&(或总共96个块)。(参看:&&。)
& & & 如果n个独立矩阵相乘共用相同的输入值,那么它们可以合并到一个更大的矩阵乘法中,输出结果会大n倍。因此,优化首先是将四个权矩阵在递归步骤上的操作合并到一个权矩阵中,然后将四个权矩阵在输入时的操作合并到另一个当中。这就会给我们两个相乘的矩阵而不是八个,不过体积都变成了原先的四倍大,并且其并行能力也为原来的四倍(每个GEMM为16个块)。这样的优化在多数框架实现过程中都相当的普遍:非常容易改变而取得良好的加速效果——代码运行速度大约可以提高两倍。
优化2:流式化GEMM
& & & &即便在合并后有了更大的GEMM,但性能还是会因为缺乏并行能力而受到限制:虽然原先的4个块变成了16个块,但目标至少要达到96个。剩下的两个GEMM是单独存在的,因而它们可以用&。这将可并行的块数翻了一倍,达到了32个。&
优化3:融合逐点操作
& & & 图表3 展示出目前要耗费很多时间来进行逐点操作。这在这些分离的内核中没有必要;将它们融合到单个的内核中可以降低全局内存的传输数据量,也会明显的降低内核的启动开销。&
& & & &图表3:NVIDIA 可视化剖析器所输出显示的是在单核之中的一些操作。逐点操作原本要占用一多半的运行时间,在优化之后逐点操作仅占用一小部分。
& & & &到这里,我对单次迭代的性能感到非常满意:大多数的计算都是在GEMM之中,它们将可并行能力展露无遗。这种实现方式比基准方式快了大约5倍,不过依然有改进的余地。
for layer in layers:&&
& & &for iteration in iterations:&&&&
& & & & & &perform sgemm on input from last layer in stream A&&&&
& & & & &&&perform sgemm on input from last iteration in stream B&&&&
& & & & &&&wait for stream A and stream B&&&&&
& & & & & &perform 逐点操作&in one kernel
步骤2:优化多次迭代
& & & 在RNN 中进行单次迭代操作要重复多次。那么这些操作的运行效率就显得非常重要了,即使这需要预先付出一些代价。
优化4:预先转置权矩阵
& & & 当进行GEMM运算时,标准的BLAS API可以让你将两个输入矩阵中的一个进行转置。四种组合的转置/非转置矩阵中的某几种组合方式的运行速度或略快或略慢,这取决于将等式映射到计算中的方式,而更慢的方式有可能会被GEMM使用。通过对权矩阵进行预先转置操作,每一步都可以稍快一些,这是以转置作为代价而换来的,不过这个代价相当的小,所以如果在多次迭代中都要用到转置矩阵的话,那通常也都是值得的。&
优化5:合并输入GEMM
& & & &在很多案例中,所有的输入在RNN计算的开始阶段都已经就绪。这也就是说,矩阵对这些输入进行的操作可以立即开始。也就意味着它们可以被合并到更大的GEMM之中。在最初,这似乎是一件好事(在合并的GEMM中具有更多的并行能力),递归GEMM的传播依赖于出入矩阵的完成情况。因此带来了一个权衡问题:合并输入GEMM可以在操作中给予更高的并行能力,但也会阻碍递归GEMM的重叠。此时的最佳策略更多的依赖于RNN 超参数&(hyperparameters)。在这个案例中,合并两个输入GEMM是最佳方式。
& & & &for layer in layers:&
& & & & & &&transpose weight matrices&
& & & & & & for iteration in iterations / combination size:&&&&
& & & & & & & && perform sgemm on combined input from last layer in stream A&&&
& & & & & & & & &for sub-iteration in combination size:&&&&&&&&
& & & & & & & & & & &perform sgemm on input from last iteration in stream B&&&&&&&
& & & & & & & & & && wait for stream A&&&&&
& & & & & & & &&wait for stream B&&&&&
& & & & & & & &&for sub-iteration&&&&&&&
& & & & & & & & & & & perform pointwise operations in one kernel
步骤3:多层优化
& & & 最终的步骤要考虑各层之间的优化。再一次的,在这里可以发掘出相当多的并行能力。图表4展示的是RNN的关联图。给定层的第n次迭代只依赖该层的第n-1次迭代和前一层的第n次迭代,可能在你完成前一层之前,这一层就已经开始。这非常强大:如果有两个层,那就有两倍的并行能力。
图表4:操作波通过网络时的依赖关系图
& & & 从一层到四层,处理能力大约提升了1.7倍:从2.3 TFLOPS&提高到&3.9 TFLOPS。到此时,释放出来的并行能力所带来的收益已开始变得有限。跟最初的在给定时间内仅有四块运行的实现方式相比较,这种实现方式可以让128块同时运行。这足以让M40的所有资源都全部利用起来,达到将近70%的峰值浮点性能,速度比最初的实现方式提高了10倍以上。
& & & 下表展示的是我所列举的每一次优化方式所带来的成绩变化,以及相比于基准代码在速度方面的提升。
<span style="font-family:微软雅黑;font-size:12.
<span style="font-family:微软雅黑;font-size:12.
<span style="font-family:微软雅黑;font-size:12.x
流式化GEMM
<span style="font-family:微软雅黑;font-size:12.
<span style="font-family:微软雅黑;font-size:12.x
融合逐点操作
<span style="font-family:微软雅黑;font-size:12.
<span style="font-family:微软雅黑;font-size:12.x
矩阵预转置
<span style="font-family:微软雅黑;font-size:12.
<span style="font-family:微软雅黑;font-size:12.x
<span style="font-family:微软雅黑;font-size:12.
<span style="font-family:微软雅黑;font-size:12.x
<span style="font-family:微软雅黑;font-size:12.
<span style="font-family:微软雅黑;font-size:12.x
通过反向来传播梯度与正向传播非常类似。一旦梯度被传播,在所有迭代中的单次调用中的权重将会被更新:不再有任何递归依赖。这会得到一个非常大而有效的矩阵乘法。
要得到最佳的神经递归网络性能,你必须发掘出比等式所提供的实现方式多得多并行能力。在cuDNN中,我们将这些优化应用到了四种常见的RNN中,因此,如果你在你的序列学习应用中正在使用这些RNN,我强烈推荐你使用cuDNN 5。
获取更多相关信息:
·&&在arXiv上对这些方法有更为详细的说明。
·&到Github网站。
其他资源:
GPU Matlab
吉浦迅科技有限公司版权所有2009递归神经网络(RNN, Recurrent Neural Networks)介绍
递归神经网络(RNN, Recurrent Neural Networks)介绍
递归神经网络(Recurrent Neural Networks,RNNs)已经在众多自然语言处理(Natural Language Processing, NLP)中取得了巨大成功以及广泛应用。但是,目前网上与RNNs有关的学习资料很少,因此该系列便是介绍RNNs的原理以及如何实现。主要分成以下几个部分对RNNs进行介绍:
1. RNNs的基本介绍以及一些常见的RNNs(本文内容);
2. 基于Python和对RNNs进行实现,包括一些常见的RNNs模型;
3. 详细介绍RNNs中一些经常使用的训练算法,如Back Propagation Through Time(BPTT)、Real-time Recurrent Learning(RTRL)、Extended Kalman Filter(EKF)等学习算法,以及梯度消失问题(vanishing gradient problem)
4. 详细介绍Long Short-Term Memory(LSTM,长短时记忆网络);
5. 详细介绍Clockwork RNNs(CW-RNNs,时钟频率驱动递归神经网络)。
不同于传统的FNNs(Feed-forward Neural Networks,前向反馈神经网络),RNNs引入了定向循环,能够处理那些输入之间前后关联的问题。定向循环结构如下图所示:
该tutorial默认读者已经熟悉了基本的神经网络模型。如果不熟悉,可以点击:进行学习。
什么是RNNs
RNNs的目的使用来处理序列数据。在传统的神经网络模型中,是从输入层到隐含层再到输出层,层与层之间是全连接的,每层之间的节点是无连接的。但是这种普通的神经网络对于很多问题却无能无力。例如,你要预测句子的下一个单词是什么,一般需要用到前面的单词,因为一个句子中前后单词并不是独立的。RNNs之所以称为递归神经网路,即一个序列当前的输出与前面的输出也有关。具体的表现形式为网络会对前面的信息进行记忆并应用于当前输出的计算中,即隐藏层之间的节点不再无连接而是有连接的,并且隐藏层的输入不仅包括输入层的输出还包括上一时刻隐藏层的输出。理论上,RNNs能够对任何长度的序列数据进行处理。但是在实践中,为了降低复杂性往往假设当前的状态只与前面的几个状态相关,下图便是一个典型的RNNs:
From Nature
RNNs包含输入单元(Input units),输入集标记为
{x0,x1,...,xt,xt+1,...}
,而输出单元(Output units)的输出集则被标记为
{y0,y1,...,yt,yt+1.,..}
。RNNs还包含隐藏单元(Hidden units),我们将其输出集标记为
{s0,s1,...,st,st+1,...}
,这些隐藏单元完成了最为主要的工作。你会发现,在图中:有一条单向流动的信息流是从输入单元到达隐藏单元的,与此同时另一条单向流动的信息流从隐藏单元到达输出单元。在某些情况下,RNNs会打破后者的限制,引导信息从输出单元返回隐藏单元,这些被称为“Back Projections”,并且隐藏层的输入还包括上一隐藏层的状态,即隐藏层内的节点可以自连也可以互连。
上图将递归神经网络进行展开成一个全神经网络。例如,对一个包含5个单词的语句,那么展开的网络便是一个五层的神经网络,每一层代表一个单词。对于该网络的计算过程如下:
t,t=1,2,3...
步(step)的输入。比如,
为第二个词的one-hot向量(根据上图,
为第一个词);
PS:使用计算机对自然语言进行处理,便需要将自然语言处理成为机器能够识别的符号,加上在机器学习过程中,需要将其进行数值化。而词是自然语言理解与处理的基础,因此需要对词进行数值化,便是一种可行又有效的方法。何为词向量,即使用一个指定长度的实数向量v来表示一个词。有一种种最简单的表示方法,就是使用One-hot vector表示单词,即根据单词的数量|V|生成一个|V| * 1的向量,当某一位为一的时候其他位都为零,然后这个向量就代表一个单词。缺点也很明显:
由于向量长度是根据单词个数来的,如果有新词出现,这个向量还得增加,麻烦!(Impossible to keep up to date);
主观性太强(subjective)
这么多单词,还得人工打labor并且adapt,想想就恐
最不能忍受的一点便是很难计算单词之间的相似性。
现在有一种更加有效的词向量模式,该模式是通过神经网或者深度学习对词进行训练,输出一个指定维度的向量,该向量便是输入词的表达。如。
为隐藏层的第
步的状态,它是网络的记忆单元。
根据当前输入层的输出与上一步隐藏层的状态进行计算。
st=f(Uxt+Wst-1)
一般是非线性的激活函数,如或,在计算
时,即第一个单词的隐藏层状态,需要用到
,但是其并不存在,在实现中一般置为0向量;
步的输出,如下个单词的向量表示,
ot=softmax(Vst)
需要注意的是:
你可以认为隐藏层状态
是网络的记忆单元.
包含了前面所有步的隐藏层状态。而输出层的输出
只与当前步的
有关,在实践中,为了降低网络的复杂度,往往
只包含前面若干步而不是所有步的隐藏层状态;
在传统神经网络中,每一个网络层的参数是不共享的。而在RNNs中,每输入一步,每一层各自都共享参数
。其反应者RNNs中的每一步都在做相同的事,只是输入不同,因此大大地降低了网络中需要学习的参数;这里并没有说清楚,解释一下,传统神经网络的参数是不共享的,并不是表示对于每个输入有不同的参数,而是将RNN是进行展开,这样变成了多层的网络,如果这是一个多层的传统神经网络,那么
之间的U矩阵与
是不同的,而RNNs中的却是一样的,同理对于
也是一样的。
上图中每一步都会有输出,但是每一步都要有输出并不是必须的。比如,我们需要预测一条语句所表达的情绪,我们仅仅需要关系最后一个单词输入后的输出,而不需要知道每个单词输入后的输出。同理,每步都需要输入也不是必须的。RNNs的关键之处在于隐藏层,隐藏层能够捕捉序列的信息。
RNNs能干什么?
RNNs已经被在实践中证明对NLP是非常成功的。如词向量表达、语句合法性检查、词性标注等。在RNNs中,目前使用最广泛最成功的模型便是,该模型通常比vanilla RNNs能够更好地对长短时依赖进行表达,该模型相对于一般的RNNs,只是在隐藏层做了手脚。对于LSTMs,后面会进行详细地介绍。下面对RNNs在NLP中的应用进行简单的介绍。
语言模型与文本生成(Language Modeling and Generating Text)
给你一个单词序列,我们需要根据前面的单词预测每一个单词的可能性。语言模型能够一个语句正确的可能性,这是机器翻译的一部分,往往可能性越大,语句越正确。另一种应用便是使用生成模型预测下一个单词的概率,从而生成新的文本根据输出概率的采样。语言模型中,典型的输入是单词序列中每个单词的词向量(如 One-hot vector),输出时预测的单词序列。当在对网络进行训练时,如果
步的输出便是下一步的输入。
下面是RNNs中的语言模型和文本生成研究的三篇文章:
机器翻译(Machine Translation)
机器翻译是将一种源语言语句变成意思相同的另一种源语言语句,如将英语语句变成同样意思的中文语句。与语言模型关键的区别在于,需要将源语言语句序列输入后,才进行输出,即输出第一个单词时,便需要从完整的输入序列中进行获取。机器翻译如下图所示:
RNN for Machine Translation.
下面是关于RNNs中机器翻译研究的三篇文章:
语音识别(Speech Recognition)
语音识别是指给一段声波的声音信号,预测该声波对应的某种指定源语言的语句以及该语句的概率值。
RNNs中的语音识别研究论文:
图像描述生成 (Generating Image Descriptions)
和卷积神经网络(convolutional Neural Networks, CNNs)一样,RNNs已经在对无标自动生成中得到应用。将CNNs与RNNs结合进行图像描述自动生成。这是一个非常神奇的研究与应用。该组合模型能够根据图像的特征生成描述。如下图所示:
图像描述生成中的深度视觉语义对比.
如何训练RNNs
对于RNN是的训练和对传统的ANN训练一样。同样使用BP误差反向传播算法,不过有一点区别。如果将RNNs进行网络展开,那么参数
是共享的,而传统神经网络却不是的。并且在使用梯度下降算法中,每一步的输出不仅依赖当前步的网络,并且还以来前面若干步网络的状态。比如,在
时,我们还需要向后传递三步,已经后面的三步都需要加上各种的梯度。该学习算法称为Backpropagation Through Time (BPTT)。后面会对BPTT进行详细的介绍。需要意识到的是,在vanilla RNNs训练中,(即当前的输出与前面很长的一段序列有关,一般超过十步就无能为力了),因为BPTT会带来所谓的梯度消失或梯度爆炸问题(the vanishing/exploding gradient problem)。当然,有很多方法去解决这个问题,如LSTMs便是专门应对这种问题的。
RNNs扩展和改进模型
这些年,研究者们已经提出了多钟复杂的RNNs去改进vanilla RNN模型的缺点。下面是目前常见的一些RNNs模型,后面会对其中使用比较广泛的进行详细讲解,在这里进行简单的概述。
SRNs是RNNs的一种特例,它是一个三层网络,并且在隐藏层增加了上下文单元,下图中的
便是隐藏层,
便是上下文单元。上下文单元节点与隐藏层中的节点的连接是固定(谁与谁连接)的,并且权值也是固定的(值是多少),其实是一个上下文节点与隐藏层节点一一对应,并且值是确定的。在每一步中,使用标准的前向反馈进行传播,然后使用学习算法进行学习。上下文每一个节点保存其连接的隐藏层节点的上一步的输出,即保存上文,并作用于当前步对应的隐藏层节点的状态,即隐藏层的输入由输入层的输出与上一步的自己的状态所决定的。因此SRNs能够解决标准的多层感知机(MLP)无法解决的对序列数据进行预测的任务。
SRNs网络结构如下图所示:
Bidirectional RNNs(双向网络)的改进之处便是,假设当前的输出(第
步的输出)不仅仅与前面的序列有关,并且还与后面的序列有关。例如:预测一个语句中缺失的词语那么就需要根据上下文来进行预测。Bidirectional RNNs是一个相对较简单的RNNs,是由两个RNNs上下叠加在一起组成的。输出由这两个RNNs的隐藏层的状态决定的。如下图所示:
Deep(Bidirectional)RNNs与Bidirectional RNNs相似,只是对于每一步的输入有多层网络。这样,该网络便有更强大的表达与学习能力,但是复杂性也提高了,同时需要更多的训练数据。Deep(Bidirectional)RNNs的结构如下图所示:
ESNs(回声状态网络)虽然也是一种RNNs,但是它与传统的RNNs相差很大。ESNs具有三个特点:
它的核心结构时一个随机生成、且保持不变的储备池(Reservoir),储备池是大规模的、随机生成的、稀疏连接(SD通常保持1%~5%,SD表示储备池中互相连接的神经元占总的神经元个数N的比例)的递归结构;
其储备池到输出层的权值矩阵是唯一需要调整的部分;
简单的线性回归就可完成网络的训练。
从结构上讲,ESNs是一种特殊类型的递归神经网络,其基本思想是:使用大规模随机连接的递归网络取代经典神经网络中的中间层,从而简化网络的训练过程。因此ESNs的关键是中间的储备池。网络中的参数包括:
为储备池中节点的连接权值矩阵,
为输入层到储备池之间的连接权值矩阵,表明储备池中的神经元之间是连接的,
为输出层到储备池之间的反馈连接权值矩阵,表明储备池会有输出层来的反馈,
为输入层、储备池、输出层到输出层的连接权值矩阵,表明输出层不仅与储备池连接,还与输入层和自己连接。
表示输出层的偏置项。
对于ESNs,关键是储备池的四个参数,如储备池内部连接权谱半径SR(
SR=λmax=max{|W的特征指|}
,只有SR &1时,ESNs才能具有回声状态属性)、储备池规模N(即储备池中神经元的个数)、储备池输入单元尺度IS(IS为储备池的输入信号连接到储备池内部神经元之前需要相乘的一个尺度因子)、储备池稀疏程度SD(即为储备池中互相连接的神经元个数占储备池神经元总个数的比例)。对于IS,如果需要处理的任务的非线性越强,那么输入单元尺度越大。该原则的本质就是通过输入单元尺度IS,将输入变换到神经元激活函数相应的范围(神经元激活函数的不同输入范围,其非线性程度不同)。
ESNs的结构如下图所示:
GRUs也是一般的RNNs的改良版本,主要是从以下两个方面进行改进。一是,序列中不同的位置处的单词(已单词举例)对当前的隐藏层的状态的影响不同,越前面的影响越小,即每个前面状态对当前的影响进行了距离加权,距离越远,权值越小。二是,在产生误差error时,误差可能是由某一个或者几个单词而引发的,所以应当仅仅对对应的单词weight进行更新。GRUs的结构如下图所示。GRUs首先根据当前输入单词向量word vector已经前一个隐藏层的状态hidden state计算出update gate和reset gate。再根据reset gate、当前word vector以及前一个hidden state计算新的记忆单元内容(new memory content)。当reset gate为1的时候,new memory content忽略之前的所有memory content,最终的memory是之前的hidden state与new memory content的结合。
LSTMs与GRUs类似,目前非常流行。它与一般的RNNs结构本质上并没有什么不同,只是使用了不同的函数去去计算隐藏层的状态。在LSTMs中,i结构被称为cells,可以把cells看作是黑盒用以保存当前输入
之前的保存的状态
,这些cells更加一定的条件决定哪些cell抑制哪些cell兴奋。它们结合前面的状态、当前的记忆与当前的输入。已经证明,该网络结构在对长序列依赖问题中非常有效。LSTMs的网络结构如下图所示。对于LSTMs的学习,参见
LSTMs解决的问题也是GRU中所提到的问题,如下图所示:
如图所示[8]:
从上图可以看出,它们之间非常相像,不同在于:
new memory的计算方法都是根据之前的state及input进行计算,但是GRUs中有一个reset gate控制之前state的进入量,而在LSTMs里没有这个gate;
产生新的state的方式不同,LSTMs有两个不同的gate,分别是forget gate (f gate)和input gate(i gate),而GRUs只有一个update gate(z gate);
LSTMs对新产生的state又一个output gate(o gate)可以调节大小,而GRUs直接输出无任何调节。
CW-RNNs是较新的一种RNNs模型,其论文发表于2014年Beijing ICML。在中作者表示其效果较SRN与LSTMs都好。
CW-RNNs也是一个RNNs的改良版本,是一种使用时钟频率来驱动的RNNs。它将隐藏层分为几个块(组,Group/Module),每一组按照自己规定的时钟频率对输入进行处理。并且为了降低标准的RNNs的复杂性,CW-RNNs减少了参数的数目,提高了网络性能,加速了网络的训练。CW-RNNs通过不同的隐藏层模块工作在不同的时钟频率下来解决长时间依赖问题。将时钟时间进行离散化,然后在不同的时间点,不同的隐藏层组在工作。因此,所有的隐藏层组在每一步不会都同时工作,这样便会加快网络的训练。并且,时钟周期小的组的神经元的不会连接到时钟周期大的组的神经元,只会周期大的连接到周期小的(认为组与组之间的连接是有向的就好了,代表信息的传递是有向的),周期大的速度慢,周期小的速度快,那么便是速度慢的连速度快的,反之则不成立。现在还不明白不要紧,下面会进行讲解。
CW-RNNs与SRNs网络结构类似,也包括输入层(Input)、隐藏层(Hidden)、输出层(Output),它们之间也有向前连接,输入层到隐藏层的连接,隐藏层到输出层的连接。但是与SRN不同的是,隐藏层中的神经元会被划分为若干个组,设为
,每一组中的神经元个数相同,设为
,并为每一个组分配一个时钟周期
Ti∈{T1,T2,...,Tg}
,每一个组中的所有神经元都是全连接,但是组
的递归连接则需要满足
。如下图所示,将这些组按照时钟周期递增从左到右进行排序,即
T1&T2&...&Tg
,那么连接便是从右到左。例如:隐藏层共有256个节点,分为四组,周期分别是[1,2,4,8],那么每个隐藏层组256/4=64个节点,第一组隐藏层与隐藏层的连接矩阵为64*64的矩阵,第二层的矩阵则为64*128矩阵,第三组为64*(3*64)=64*192矩阵,第四组为64*(4*64)=64*256矩阵。这就解释了上一段的后面部分,速度慢的组连到速度快的组,反之则不成立。
CW-RNNs的网络结构如下图所示:
在传统的RNN中,按照下面的公式进行计算:
st=fs(Wst-1+Winxt)
ot=fo(Woutst)
为隐藏层神经元的自连接矩阵,
为输入层到隐藏层的连接权值矩阵,
是隐藏层到输出层的连接权值矩阵 ,
步的输入,
步隐藏层的输出,
步隐藏层的输出,
步的输出,
为隐藏层的激活函数,
为输出层的激活函数。
与传统的RNNs不同的是,在第
步时,只有那些满足
(tmodTi)=0
的隐藏层组才会执行。并且每一隐藏层组的周期
{T1,T2,...,Tg}
都可以是任意的。原文中是选择指数序列作为它们的周期,即
Ti=2i-1i∈[1,...,g]
将被划分为
个块。如下:
W=?????W1...Wg?????
Win=?????Win1...Wing?????
是一个上三角矩阵,每一个组行
被划分为列向量
{W1i,...,Wii,0(i+1)i,...,0gi}T
Wji,j∈[1,...,g]
表示第i个组到第j个组的连接权值矩阵。在每一步中,
只有部分组行处于执行状态,其它的为0:
Wi={Wi0,for(tmodTi)=0,otherwise
Wini={Wini0,for(tmodTi)=0,otherwise
为了使表达不混淆,将
。并且执行的组所对应的
才会有输出。处于非执行状态下的隐藏层组仍保留着上一步的状态。下图是含五个隐藏层组在
时的计算图:
在CW-RNNs中,慢速组(周期大的组)处理、保留、输出长依赖信息,而快速组则会进行更新。CW-RNNs的误差后向传播也和传统的RNNs类似,只是误差只在处于执行状态的隐藏层组进行传播,而非执行状态的隐藏层组也复制其连接的前面的隐藏层组的后向传播。即执行态的隐藏层组的误差后向传播的信息不仅来自与输出层,并且来自与其连接到的左边的隐藏层组的后向传播信息,而非执行态的后向传播信息只来自于其连接到的左边的隐藏层组的后向传播数据。
下图是原文对三个不同RNNs模型的实验结果图:
上图中,绿色实线是预测结果,蓝色散点是真实结果。每个模型都是对前半部分进行学习,然后预测后半部分。LSTMs模型类似滑动平均,但是CW-RNNs效果更好。其中三个模型的输入层、隐藏层、输出层的节点数都相同,并且只有一个隐藏层,权值都使用均值为0,标准差为0.1的高斯分布进行初始化,隐藏层的初始状态都为0,每一个模型都使用
进行学习与优化。
到目前为止,本文对RNNs进行了基本的介绍,并对常见的几种RNNs模型进行了初步讲解。下一步将基于Theano与Python实现一个RNNs语言模型并对上面的一些RNNs模型进行详解。这里有。
后面将陆续推出:
基于Python和对RNNs进行实现,包括一些常见的RNNs模型;
详细介绍RNNs中一些经常使用的训练算法,如Back Propagation Through Time(BPTT)、Real-time Recurrent Learning(RTRL)、Extended Kalman Filter(EKF)等学习算法,以及梯度消失问题(vanishing gradient problem)
详细介绍Long Short-Term Memory(LSTM,长短时记忆网络);
详细介绍Clockwork RNNs(CW-RNNs,时钟频率驱动递归神经网络)。
本系列将实现一个。该实现包含两个方面:一是能够得到任意语句在现实中成立的得分,其提供了判断语法与语义的正确性的度量方式。该模型是机器翻译中的典型应用。二是模型能够产生新的文本,这是一个非常棒的应用。比如,对莎士比亚的文章进行训练,能够产生一个新的类似莎士比亚的文本,目前,这个有趣的想法已经被实现了。
[1] Hinton G E. Learning Distributed Representations of Concepts[C]. Proceedings of the 8th Annual Conference of the Cognitive Science Society. .
[2] Elman, J. L. Finding structure in time. CRL Technical Report 8801, Center for Research in Language, University
of California, San Diego, 1988.
[3] Schuster M, Paliwal K K. Bidirectional recurrent neural networks[J]. Signal Processing, IEEE Transactions on, ): .
[4] Graves A, Mohamed A R, Hinton G. Speech Recognition with Deep Recurrent Neural Networks[J]. Acoustics Speech & Signal Processing . icassp. international Conference on,
[5] Jaeger H, Haas H. Harnessing nonlinearity: Predicting chaotic systems and saving energy in wireless communication[J]. Science, 67): 78-80.
[6] Cho K, Van Merrienboer B, Gulcehre C, et al. Learning Phrase Representations using RNN Encoder-Decoder for Statistical Machine Translation[J]. Eprint Arxiv, 2014.
[7] Hochreiter S, Schmidhuber J. Long short-term memory.[J]. Neural Computation, ):.
[8] Chung J, Gulcehre C, Cho K H, et al. Empirical evaluation of gated recurrent neural networks on sequence modeling[J]. arXiv preprint arXiv:, 2014.
[9] Jan Koutnik, Klaus Greff, Faustino Gomez, Juergen Schmidhuber. A Clockwork RNN[J]. Proceedings of The 31st International Conference on Machine Learning, pp. , 2014.
[10] Sutskever, Ilya, Martens, James, Dahl, George E., and Hinton, Geoffrey E. On the importance of initialization and momentum in deep learning. In Dasgupta, Sanjoy and Mcallester, David (eds.), Proceedings of the 30th International Conference on Machine Learning (ICML-13), volume 28, pp. .
转载请标明地址:
本文转载自 我和我追逐的梦~~~ , 原文链接: , 转载请保留本声明!
每一个你不满意的现在,都有一个你没有努力的曾经。
Copyright (C) 2015&&
&&Powered by&}

我要回帖

更多关于 时序图 递归 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信