深度学习第十章 循环神经网络
第10章 序列建模:循环和递归网络
循环神经网络(recurrent neural network)或RNN(Rumelhart et al., 1986c)是一类用于处理序列数据的神经网络。就像卷积网络是专门用于处理网格化数据X(如一个图像)的神经网络,循环神经网络是专门用于处理序列x(1),···,x(τ)的神经网络。正如卷积网络可以很容易地扩展到具有很大宽度和高度的图像,以及处理大小可变的图像,循环网络可以扩展到更长的序列(比不基于序列的特化网络长得多)。大多数循环网络也能处理可变长度的序列。
正如卷积网络可以很容易地扩展到具有很大宽度和高度的图像,以及处理大小可变的图像,循环网络可以扩展到更长的序列(比不基于序列的特化网络长得多)。大多数循环网络也能处理可变长度的序列。
从多层网络出发到循环网络,我们需要利用20世纪80年代机器学习和统计模型早期思想的优点:在模型的不同部分共享参数。参数共享使得模型能够扩展到不同形式的样本(这里指不同长度的样本)并进行泛化。如果我们在每个时间点都有一个单独的参数,不但不能泛化到训练时没有见过序列长度,也不能在时间上共享不同序列长度和不同位置的统计强度。
一个相关的想法是在一维时间序列上使用卷积。这种卷积方法是时延神经网络的基础(Lang and Hinton, 1988; Waibel et al., 1989; Lang et al., 1990)。卷积操作允许网络跨时间共享参数,但是浅层的。卷积的输出是一个序列,其中输出中的每一项是相邻几项输入的函数。参数共享的概念体现在每个时间步中使用的相同卷积核。循环神经网络以不同的方式共享参数。输出的每一项是前一项的函数。输出的每一项对先前的输出应用相同的更新规则而产生。这种循环方式导致参数通过很深的计算图共享。
有时,它仅表示序列中的位置。RNN也可以应用于跨越两个维度的空间数据(如图像)。当应用于涉及时间的数据,并且将整个序列提供给网络之前就能观察到整个序列时,该网络可具有关于时间向后的连接。
10.1 展开计算图计算图是形式化一组计算结构的方式,如那些涉及将输入和参数映射到输出和损失的计算。综合的介绍请参考第6.5.1节。本节,我们对展开(unfolding)递归或循环计算得到的重复结构进行解释,这些重复结构通常对应于一个事件链。展开(unfolding)这个计算图将导致深度网络结构中的参数共享。
循环神经网络可以通过许多不同的方式建立。就像几乎所有函数都可以被认为是前馈网络,本质上任何涉及循环的函数都可以视为一个循环神经网络。很多循环神经网络使用式(10.5)或类似的公式定义隐藏单元的值。为了表明状态是网络的隐藏单元,我们使用变量h代表状态重写式(10.4):
目前,展开图的大小取决于序列长度。我们可以用一个函数g(t)代表经t步展开后的循环:[插图]函数g(t)将全部的过去序列(x(t),x(t-1),x(t-2),···,x(2),x(1))作为输入来生成当前状态,但是展开的循环架构允许我们将g(t)分解为函数f的重复应用。因此,展开过程引入两个主要优点:(1)无论序列的长度,学成的模型始终具有相同的输入大小,因为它指定的是从一种状态到另一种状态的转移,而不是在可变长度的历史状态上操作。
这两个因素使得学习在所有时间步和所有序列长度上操作单一的模型f是可能的,而不需要在所有可能时间步学习独立的模型g(t)。学习单一的共享模型允许泛化到没有见过的序列长度(没有出现在训练集中),并且估计模型所需的训练样本远远少于不带参数共享的模型。
10.2 循环神经网络基于第10.1节中的图展开和参数共享的思想,我们可以设计各种循环神经网络。
循环神经网络中一些重要的设计模式包括以下几种:(1)每个时间步都有输出,并且隐藏单元之间有循环连接的循环网络,如图10.3所示。(2)每个时间步都产生一个输出,只有当前时刻的输出到下个时刻的隐藏单元之间有循环连接的循环网络,如图10.4所示。(3)隐藏单元之间存在循环连接,但读取整个序列后产生单个输出的循环网络,如图10.5所示。
图10.3中的RNN可以选择将其想要的关于过去的任何信息放入隐藏表示h中并且将h传播到未来。该图中的RNN被训练为将特定输出值放入o中,并且o是允许传播到未来的唯一信息。此处没有从h前向传播的直接连接。之前的h仅通过产生的预测间接地连接到当前。o通常缺乏过去的重要信息,除非它非常高维且内容丰富。这使得该图中的RNN不那么强大,但是它更容易训练,因为每个时间步可以与其他时间步分离训练,允许训练期间更多的并行化
关于各个参数计算这个损失函数的梯度是计算成本很高的操作。梯度计算涉及执行一次前向传播(如在图10.3展开图中从左到右的传播),接着是由右到左的反向传播。运行时间是[插图],并且不能通过并行化来降低,因为前向传播图是固有循序的;每个时间步只能一前一后地计算。前向传播中的各个状态必须保存,直到它们反向传播中被再次使用,因此内存代价也是[插图]。应用于展开图且代价为[插图]的反向传播算法称为通过时间反向传播(back-propagation through time, BPTT
10.2.1 导师驱动过程和输出循环网络
仅在一个时间步的输出和下一个时间步的隐藏单元间存在循环连接的网络(见图10.4)确实没有那么强大(因为缺乏隐藏到隐藏的循环连接)。
消除隐藏到隐藏循环的优点在于,任何基于比较时刻t的预测和时刻t的训练目标的损失函数中的所有时间步都解耦了。因此训练可以并行化,即在各时刻t分别计算梯度。因为训练集提供输出的理想值,所以没有必要先计算前一时刻的输出。
由输出反馈到模型而产生循环连接的模型可用导师驱动过程(teacher forcing)进行训练。训练模型时,导师驱动过程不再使用最大似然准则,而在时刻t+1接收真实值y(t)作为输入。我们可以通过检查两个时间步的序列得知这一点。
导师驱动过程的示意图。导师驱动过程是一种训练技术,适用于输出与下一时间步的隐藏状态存在连接的RNN。(左)训练时,我们将训练集中正确的输出y(t)反馈到h(t+1)。(右)当模型部署后,真正的输出通常是未知的。在这种情况下,我们用模型的输出o(t)近似正确的输出y(t),并反馈回模型
我们使用导师驱动过程的最初动机是为了在缺乏隐藏到隐藏连接的模型中避免通过时间反向传播。只要模型一个时间步的输出与下一时间步计算的值存在连接,导师驱动过程仍然可以应用到这些存在隐藏到隐藏连接的模型。然而,只要隐藏单元成为较早时间步的函数,BPTT算法是必要的。因此训练某些模型时要同时使用导师驱动过程和BPTT。
如果之后网络在开环(open-loop)模式下使用,即网络输出(或输出分布的样本)反馈作为输入,那么完全使用导师驱动过程进行训练的缺点就会出现。在这种情况下,训练期间该网络看到的输入与测试时看到的会有很大的不同。减轻此问题的一种方法是同时使用导师驱动过程和自由运行的输入进行训练,例如在展开循环的输出到输入路径上预测几个步骤的正确目标值。
10.2.2 计算循环神经网络的梯度计算循环神经网络的梯度是容易的。我们可以简单地将第6.5.6节中的推广反向传播算法应用于展开的计算图,而不需要特殊化的算法。由反向传播计算得到的梯度,并结合任何通用的基于梯度的技术就可以训练RNN。
0.2.3 作为有向图模型的循环网络目前为止,我们接触的循环网络例子中损失L(t)是训练目标y(t)和输出o(t)之间的交叉熵。与前馈网络类似,原则上循环网络几乎可以使用任何损失。但必须根据任务来选择损失。如前馈网络,通常我们希望将RNN的输出解释为一个概率分布,并且通常使用与分布相关联的交叉熵来定义损失。均方误差是与单位高斯分布的输出相关联的交叉熵损失,例如前馈网络中所使用的。
将整个序列y的联合分布分解为一系列单步的概率预测是捕获关于整个序列完整联合分布的一种方法。如果我们不把过去的y值反馈给下一步作为预测的条件,那么有向图模型不包含任何从过去y(i)到当前y(t)的边。在这种情况下,输出y与给定的x序列是条件独立的。如果我们反馈真实的y值(不是它们的预测值,而是真正观测到或生成的值)给网络,那么有向图模型包含所有从过去y(i)到当前y(t)的边。
解释RNN作为图模型的一种方法是将RNN视为定义一个结构为完全图的图模型,且能够表示任何一对y值之间的直接联系。图10.7是关于y值且具有完全图结构的图模型。该RNN完全图的解释基于排除并忽略模型中的隐藏单元h(t)。
即便使用高效参数化的图模型,某些操作在计算上仍然具有挑战性。例如,难以预测序列中缺少的值。循环网络为减少的参数数目付出的代价是优化参数可能变得困难。在循环网络中使用的参数共享的前提是相同参数可用于不同时间步的假设。也就是说,假设给定时刻t的变量后,时刻t+1变量的条件概率分布是平稳的(stationary),这意味着之前的时间步与下个时间步之间的关系并不依赖于t。
另一种选择是在模型中引入一个额外的Bernoulli输出,表示在每个时间步决定继续生成或停止生成。相比向词汇表增加一个额外符号,这种方法更普遍,因为它适用于任何RNN,而不仅仅是输出符号序列的RNN。例如,它可以应用于一个产生实数序列的RNN。新的输出单元通常使用sigmoid单元,并通过交叉熵训练。在这种方法中,sigmoid被训练为最大化正确预测的对数似然,即在每个时间步序列决定结束或继续。
y(t)的RNN如何对应于有向图模型。当然,如式(10.8)所示的RNN包含一个输入序列x(1),x(2),…,x(τ)。一般情况下,RNN允许将图模型的观点扩展到不仅代表y变量的联合分布也能表示给定x后y条件分布。如在第6.2.1.1节的前馈网络情形中所讨论的,任何代表变量P(y;θ)的模型都能被解释为代表条件分布P(y|ω)的模型,其中ω=θ。我们能像之前一样使用P(y|ω)代表分布P(y|x)来扩展这样的模型,但要令ω是关于x的函数。在RNN的情况,这可以通过不同的方式来实现。此处,我们回顾最常见和最明显的选择。
10.3 双向RNN目前为止,我们考虑的所有循环神经网络有一个“因果”结构,意味着在时刻t的状态只能从过去的序列x(1),···,x(t-1)以及当前的输入x(t)捕获信息。我们还讨论了某些在y可用时,允许过去的y值信息影响当前状态的模型。
双向循环神经网络(或双向RNN)为满足这种需要而发明(Schuster and Paliwal,1997)。它们在需要双向信息的应用中非常成功(Graves,2012),如手写识别(Graves et al.,2008; Graves and Schmidhuber, 2009)、语音识别(Graves and Schmidhuber, 2005; Graves et al., 2013)以及生物信息学(Baldi et al.,1999)。
顾名思义,双向RNN结合时间上从序列起点开始移动的RNN和另一个时间上从序列末尾开始移动的RNN。
10.4 基于编码-解码的序列到序列架构我们已经在图10.5看到RNN如何将输入序列映射成固定大小的向量,在图10.9中看到RNN如何将固定大小的向量映射成一个序列,在图10.3、图10.4、图10.10和图10.11中看到RNN如何将一个输入序列映射到等长的输出序列。
我们经常将RNN的输入称为“上下文”。我们希望产生此上下文的表示C。这个上下文C可能是一个概括输入序列X=(x(1),…,x(nx))的向量或者向量序列。
用于映射可变长度序列到另一可变长度序列最简单的RNN架构最初由Cho et al.(2014a)提出,之后不久由Sutskever et al.(2014)独立开发,并且第一个使用这种方法获得翻译的最好结果。前一系统是对另一个机器翻译系统产生的建议进行评分,而后者使用独立的循环网络生成翻译。这些作者分别将该架构称为编码-解码或序列到序列架构,如图10.12所示。这个想法非常简单:(1)编码器(encoder)或读取器(reader)或输入(input)RNN处理输入序列。编码器输出上下文C(通常是最终隐藏状态的简单函数)。(2)解码器(decoder)或写入器(writer)或输出(output)RNN则以固定长度的向量(见图10.9)为条件产生输出序列Y=(y(1),…,y(ny))。这种架构对比本章前几节提出的架构的创新之处在于长度nx和ny可以彼此不同,而之前的架构约束nx=ny=τ。在序列到序列的架构中,两个RNN共同训练以最大化logP(y(1),…,y(ny)|x(1),…,x(nx))(关于训练集中所有x和y对的平均)。编码器RNN的最后一个状态hnx通常被当作输入的表示C并作为解码器
如果上下文C是一个向量,则编码器RNN只是在第10.2.4节描述的向量到序列RNN。正如我们所见,向量到序列RNN至少有两种接受输入的方法。输入可以被提供为RNN的初始状态,或连接到每个时间步中的隐藏单元。这两种方式也可以结合。
此架构的一个明显不足是,编码器RNN输出的上下文C的维度太小而难以适当地概括一个长序列。这种现象由Bahdanau et al.(2015)在机器翻译中观察到。他们提出让C成为可变长度的序列,而不是一个固定大小的向量。此外,他们还引入了将序列C的元素和输出序列的元素相关联的注意力机制(attention mechanism)。
10.5 深度循环网络大多数RNN中的计算可以分解成3块参数及其相关的变换:(1)从输入到隐藏状态。(2)从前一隐藏状态到下一隐藏状态。(3)从隐藏状态到输出。
10.6 递归神经网络递归神经网络[插图]代表循环网络的另一个扩展,它被构造为深的树状结构而不是RNN的链状结构,因此是不同类型的计算图。递归网络的典型计算图如图10.14所示。递归神经网络由Pollack(1990)引入,而Bottou(2011)描述了这类网络的潜在用途——学习推论。递归网络已成功地应用于输入是数据结构的神经网络(Frasconi et al.,1997,1998),如自然语言处理(Socher et al.,2011a,c,2013a)和计算机视觉(Socher et al.,2011b)。
递归网络的一个明显优势是,对于具有相同长度τ的序列,深度(通过非线性操作的组合数量来衡量)可以急剧地从τ减小为O(logτ),这可能有助于解决长期依赖。一个悬而未决的问题是如何以最佳的方式构造树。一种选择是使用不依赖于数据的树结构,如平衡二叉树。在某些应用领域,外部方法可以为选择适当的树结构提供借鉴。例如,处理自然语言的句子时,用于递归网络的树结构可以被固定为句子语法分析树的结构(可以由自然语言语法分析程序提供)(Socher et al., 2011a, c)。理想的情况下,人们希望学习器自行发现和推断适合于任意给定输入的树结构,如(Bottou,2011)所建议。
递归网络想法的变种存在很多。例如,Frasconi et al.(1997)和Frasconi et al.(1998)将数据与树结构相关联,并将输入和目标与树的单独节点相关联。由每个节点执行的计算无须是传统的人工神经计算(所有输入的仿射变换后跟一个单调非线性)。例如,Socher et al.(2013a)提出用张量运算和双线性形式,在这之前人们已经发现当概念是由连续向量(嵌入)表示时,这种方式有利于建模概念之间的联系(Weston et al.,2010; Bordes et al.,2012)。
10.7 长期依赖的挑战学习循环网络长期依赖的数学挑战在第8.2.5节中引入。根本问题是,经过许多阶段传播后的梯度倾向于消失(大部分情况)或爆炸(很少,但对优化过程影响很大)。
个问题是针对循环网络的。在标量情况下,想象多次乘一个权重w。该乘积wt消失还是爆炸取决于w的幅值。然而,如果每个时刻使用不同权重w(t)的非循环网络,情况就不同了。如果初始状态给定为1,那么时刻t的状态可以由∏tw(t)给出。假设w(t)的值是随机生成的,各自独立,且有0均值v方差。乘积的方差就为[插图]。为了获得某些期望的方差v∗,我们可以选择单个方差为[插图]权重。因此,非常深的前馈网络通过精心设计的比例可以避免梯度消失和爆炸问题,如Sussillo(2014)所主张的。
RNN梯度消失和爆炸问题是由不同研究人员独立发现(Hochreiter, 1991a;Bengio et al., 1993,1994b)。有人可能会希望通过简单地停留在梯度不消失或爆炸的参数空间来避免这个问题。不幸的是,为了储存记忆并对小扰动具有鲁棒性,RNN必须进入参数空间中的梯度消失区域(Bengio et al., 1993,1994b)。具体来说,每当模型能够表示长期依赖时,长期相互作用的梯度幅值就会变得指数小(相比短期相互作用的梯度幅值)。这并不意味着这是不可能学习的,由于长期依赖关系的信号很容易被短期相关性产生的最小波动隐藏,因而学习长期依赖可能需要很长的时间
10.8 回声状态网络从h(t-1)到h(t)的循环权重映射以及从x(t)到h(t)的输入权重映射是循环网络中最难学习的参数。研究者(Jaeger,2003; Maass et al.,2002; Jaeger and Haas,2004; Jaeger,2007b)提出避免这种困难的方法是设定循环隐藏单元,使其能很好地捕捉过去输入历史,并且只学习输出权重。回声状态网络(echo state network)或ESN(Jaeger and Haas,2004; Jaeger,2007b),以及流体状态机(liquid state machines)(Maass et al.,2002)分别独立地提出了这种想法。后者是类似的,只不过它使用脉冲神经元(二值输出)而不是ESN中的连续隐藏单元。ESN和流体状态机都被称为储层计算(reservoir computing)(Lukoševičius and Jaeger,2009),因为隐藏单元形成了可能捕获输入历史不同方面的临时特征池。
如果线性映射[插图]在L2范数的测度下总是缩小h,那么我们说这个映射是收缩(contractive)的。当谱半径小于一,则从h(t)到h(t+1)的映射是收缩的,因此小变化在每个时间步后变得更小。当我们使用有限精度(如32位整数)来存储状态向量时,必然会使得网络忘掉过去的信息。
10.9 渗漏单元和其他多时间尺度的策略处理长期依赖的一种方法是设计工作在多个时间尺度的模型,使模型的某些部分在细粒度时间尺度上操作并能处理小细节,而其他部分在粗时间尺度上操作并能把遥远过去的信息更有效地传递过来。存在多种同时构建粗细时间尺度的策略。这些策略包括在时间轴增加跳跃连接,“渗漏单元”使用不同时间常数整合信号,并去除一些用于建模细粒度时间尺度的连接。
10.9.1 时间维度的跳跃连接增加从遥远过去的变量到目前变量的直接连接是得到粗时间尺度的一种方法。使用这样跳跃连接的想法可以追溯到Lin et al.(1996),紧接是向前馈网络引入延迟的想法(Lang and Hinton,1988)。在普通的循环网络中,循环从时刻t的单元连接到时刻t+1单元。构造较长的延迟循环网络是可能的
10.9.2 渗漏单元和一系列不同时间尺度获得导数乘积接近1的另一方式是设置线性自连接单元,并且这些连接的权重接近1。
10.9.2 渗漏单元和一系列不同时间尺度获得导数乘积接近1的另一方式是设置线性自连接单元,并且这些连接的权重接近1。我们对某些v值应用更新µ(t)←αµ(t-1)+(1-α)v(t)累积一个滑动平均值µ(t),其中α是一个从µ(t-1)到µ(t)线性自连接的例子。当α接近1时,滑动平均值能记住过去很长一段时间的信息,而当α接近0,关于过去的信息被迅速丢弃。线性自连接的隐藏单元可以模拟滑动平均的行为。
渗漏单元(leaky unit)。d时间步的跳跃连接可以确保单元总能被d个时间步前的那个值影响。使用权重接近1的线性自连接是确保该单元可以访问过去值的不同方式。线性自连接通过调节实值α更平滑灵活地调整这种效果,而不是调整整数值的跳跃长度。
10.9.3 删除连接处理长期依赖的另一种方法是在多个时间尺度组织RNN状态的想法(El Hihi and Bengio, 1996),信息在较慢的时间尺度上更容易长距离流动。这个想法与之前讨论的时间维度上的跳跃连接不同,因为它涉及主动删除长度为一的连接并用更长的连接替换它们。以这种方式修改的单元被迫在长时间尺度上运作。而通过时间跳跃连接是添加边。收到这种新连接的单元,可以学习在长时间尺度上运作,但也可以选择专注于自己其他的短期连接。强制一组循环单元在不同时间尺度上运作有不同的方式。一种选择是使循环单元变成渗漏单元,但不同的单元组关联不同的固定时间尺度。这由Mozer(1992)提出,并被成功应用于Pascanu et al.(2013a)。另一种选择是使显式且离散的更新发生在不同的时间,不同的单元组有不同的频率。这是El Hihi and Bengio(1996)和Koutnik et al.(2014)的方法。它在一些基准数据集上表现不错。
10.10 长短期记忆和其他门控RNN本书撰写之时,实际应用中最有效的序列模型称为门控RNN(gated RNN)。包括基于长短期记忆(long short-term memory)和基于门控循环单元(gated recurrent unit)的网络。
像渗漏单元一样,门控RNN想法也是基于生成通过时间的路径,其中导数既不消失也不发生爆炸。渗漏单元通过手动选择常量的连接权重或参数化的连接权重来达到这一目的。门控RNN将其推广为在每个时间步都可能改变的连接权重。
渗漏单元允许网络在较长持续时间内积累信息(诸如用于特定特征或类的线索)。然而,一旦该信息被使用,让神经网络遗忘旧的状态可能是有用的。例如,如果一个序列是由子序列组成,我们希望渗漏单元能在各子序列内积累线索,需要将状态设置为0以忘记旧状态的机制。我们希望神经网络学会决定何时清除状态,而不是手动决定。这就是门控RNN要做的事。
10.10.1 LSTM引入自循环的巧妙构思,以产生梯度长时间持续流动的路径是初始长短期记忆(long short-term memory, LSTM)模型的核心贡献(Hochreiter and Schmidhuber, 1997)。其中一个关键扩展是使自循环的权重视上下文而定,而不是固定的(Gers et al., 2000)。门控此自循环(由另一个隐藏单元控制)的权重,累积的时间尺度可以动态地改变。在这种情况下,即使是具有固定参数的LSTM,累积的时间尺度也可以因输入序列而改变,因为时间常数是模型本身的输出。
10.10.2 其他门控RNNLSTM架构中哪些部分是真正必需的?还可以设计哪些其他成功架构允许网络动态地控制时间尺度和不同单元的遗忘行为?最近关于门控RNN的工作给出了这些问题的某些答案,其单元也被称为门控循环单元或GRU(Cho et al., 2014c; Chung et al., 2014, 2015a; Jozefowicz et al., 2015; Chrupala et al., 2015)。与LSTM的主要区别是,单个门控单元同时控制遗忘因子和更新状态单元的决定。更新公式如下:
10.11 优化长期依赖我们已经在第8.2.5节和第10.7节中描述过在许多时间步上优化RNN时发生的梯度消失和爆炸的问题。由Martens and Sutskever(2011)提出了一个有趣的想法是,二阶导数可能在一阶导数消失的同时消失。二阶优化算法可以大致被理解为将一阶导数除以二阶导数(在更高维数,由梯度乘以Hessian的逆)。如果二阶导数与一阶导数以类似的速率收缩,那么一阶和二阶导数的比率可保持相对恒定。不幸的是,二阶方法有许多缺点,包括高的计算成本、需要一个大的小批量并且倾向于被吸引到鞍点。
10.11.1 截断梯度如第8.2.4节讨论,强非线性函数(如由许多时间步计算的循环网络)往往倾向于非常大或非常小幅度的梯度。如图8.3和图10.17所示,我们可以看到,目标函数(作为参数的函数)存在一个伴随“悬崖”的“地形”:宽且相当平坦区域被目标函数变化快的小区域隔开,形成了一种悬崖。
因为所有参数(包括不同的参数组,如权重和偏置)的梯度被单个缩放因子联合重整化,所以后一方法具有的优点是保证了每个步骤仍然是在梯度方向上的,但实验表明两种形式类似。虽然参数更新与真实梯度具有相同的方向梯度,经过梯度范数截断,参数更新的向量范数现在变得有界。这种有界梯度能避免执行梯度爆炸时的有害一步。事实上,当梯度大小高于阈值时,即使是采取简单的随机步骤往往工作得几乎一样好。如果爆炸非常严重,梯度数值上为Inf或Nan(无穷大或不是一个数字),则可以采取大小为v的随机一步,通常会离开数值不稳定的状态。
Pascanu et al.(2013a)提出可以将后向传播向量∇h(t)L考虑为恒值作为近似(为了计算正则化的目的,没有必要通过它们向后传播)。使用该正则项的实验表明,如果与标准的启发式截断(处理梯度爆炸)相结合,该正则项可以显著地增加RNN可以学习的依赖跨度。梯度截断特别重要,因为它保持了爆炸梯度边缘的RNN动态。如果没有梯度截断,梯度爆炸将阻碍学习的成功。
10.12 外显记忆智能需要知识并且可以通过学习获取知识,这已促使大型深度架构的发展。然而,知识是不同的并且种类繁多。有些知识是隐含的、潜意识的并且难以用语言表达——比如怎么行走或狗与猫的样子有什么不同。其他知识可以是明确的、可陈述的以及可以相对简单地使用词语表达——每天常识性的知识,如“猫是一种动物”,或者为实现自己当前目标所需知道的非常具体的事实,如“与销售团队会议在141室于下午3:00开始”。
神经网络擅长存储隐性知识,但是它们很难记住事实。被存储在神经网络参数中之前,随机梯度下降需要多次提供相同的输入,即使如此,该输入也不会被特别精确地存储。Graves et al.(2014)推测这是因为神经网络缺乏工作存储(working memory)系统,即类似人类为实现一些目标而明确保存和操作相关信息片段的系统。这种外显记忆组件将使我们的系统不仅能够快速“故意”地存储和检索具体的事实,也能利用它们循序推论。
产生确切整数地址的函数很难优化。为了缓解这一问题,NTM实际同时从多个记忆单元写入或读取。读取时,它们采取许多单元的加权平均值。写入时,它们对多个单元修改不同的数值。用于这些操作的系数被选择为集中在一个小数目的单元,如通过softmax函数产生它们。使用这些具有非零导数的权重允许函数控制访问存储器,从而能使用梯度下降法优化。关于这些系数的梯度指示着其中每个参数是应该增加还是减少,但梯度通常只在接收大系数的存储器地址上变大。
这些记忆单元通常扩充为包含向量,而不是由LSTM或GRU存储单元所存储的单个标量。增加记忆单元大小的原因有两个。原因之一是,我们已经增加了访问记忆单元的成本。我们为产生用于许多单元的系数付出计算成本,但我们预期这些系数聚集在周围小数目的单元。通过读取向量值,而不是一个标量,我们可以抵消部分成本。使用向量值的记忆单元的另一个原因是,它们允许基于内容的寻址(content-based addressing),其中从一个单元读或写的权重是该单元的函数。如果我们能够生产符合某些但并非所有元素的模式,向量值单元允许我们检索一个完整向量值的记忆。
如果一个存储单元的内容在大多数时间步上会被复制(不被忘记),则它包含的信息可以在时间上向前传播,随时间向后传播的梯度也不会消失或爆炸。
外显记忆的方法在图10.18说明,其中我们可以看到与存储器耦接的“任务神经网络”。虽然这一任务神经网络可以是前馈或循环的,但整个系统是一个循环网络。任务网络可以选择读取或写入的特定内存地址。外显记忆似乎允许模型学习普通RNN或LSTM RNN不能学习的任务。这种优点的一个原因可能是因为信息和梯度可以在非常长的持续时间内传播(分别在时间上向前或向后)。
无论是软(允许反向传播)或随机硬性的,用于选择一个地址的机制与先前在机器翻译的背景下引入的注意力机制形式相同(Bahdanau et al., 2015),这在第12.4.5.1节中也有讨论。甚至更早之前,注意力机制的想法就被引入了神经网络,在手写生成的情况下(Graves,2013),有一个被约束为通过序列只向前移动的注意力机制。在机器翻译和记忆网络的情况下,每个步骤中关注的焦点可以移动到一个完全不同的地方(相比之前的步骤)。