乐读窝

深度学习

乐读窝 > 文学理论 > 深度学习

10.2 循环神经网络

书籍名:《深度学习》    作者:伊恩.古德费洛



基于第10.1节中的图展开和参数共享的思想,我们可以设计各种循环神经网络。

循环神经网络中一些重要的设计模式包括以下几种:

(1)每个时间步都有输出,并且隐藏单元之间有循环连接的循环网络,如图10.3所示。

图10.3 计算循环网络(将x值的输入序列映射到输出值o的对应序列)训练损失的计算图。损失L衡量每个o与相应的训练目标y的距离。当使用softmax输出时,我们假设o是未归一化的对数概率。损失L内部计算,并将其与目标y比较。RNN输入到隐藏的连接由权重矩阵U参数化,隐藏到隐藏的循环连接由权重矩阵W参数化以及隐藏到输出的连接由权重矩阵V参数化。式(10.8)定义了该模型中的前向传播。(左)使用循环连接绘制的RNN和它的损失。(右)同一网络被视为展开的计算图,其中每个节点现在与一个特定的时间实例相关联

(2)每个时间步都产生一个输出,只有当前时刻的输出到下个时刻的隐藏单元之间有循环连接的循环网络,如图10.4所示。

图10.4 此类RNN的唯一循环是从输出到隐藏层的反馈连接。在每个时间步t,输入为xt,隐藏层激活为h(t),输出为o(t),目标为y(t),损失为L(t)。(左)回路原理图。(右)展开的计算图。这样的RNN没有图10.3表示的RNN那样强大(只能表示更小的函数集合)。图10.3中的RNN可以选择将其想要的关于过去的任何信息放入隐藏表示h中并且将h传播到未来。该图中的RNN被训练为将特定输出值放入o中,并且o是允许传播到未来的唯一信息。此处没有从h前向传播的直接连接。之前的h仅通过产生的预测间接地连接到当前。o通常缺乏过去的重要信息,除非它非常高维且内容丰富。这使得该图中的RNN不那么强大,但是它更容易训练,因为每个时间步可以与其他时间步分离训练,允许训练期间更多的并行化,如第10.2.1节所述

(3)隐藏单元之间存在循环连接,但读取整个序列后产生单个输出的循环网络,如图10.5所示。

图10.5 关于时间展开的循环神经网络,在序列结束时具有单个输出。这样的网络可以用于概括序列并产生用于进一步处理的固定大小的表示。在结束处可能存在目标(如此处所示),或者通过更下游模块的反向传播来获得输出o(t)上的梯度

图10.3是非常具有代表性的例子,我们将会在本章大部分涉及这个例子。

任何图灵可计算的函数都可以通过这样一个有限维的循环网络计算,在这个意义上图10.3和式(10.8)的循环神经网络是万能的。RNN经过若干时间步后读取输出,这与由图灵机所用的时间步是渐近线性的,与输入长度也是渐近线性的(Siegelmann  and  Sontag,1991;Siegelmann,1995;Siegelmann  and  Sontag,1995;Hyotyniemi,1996)。由图灵机计算的函数是离散的,所以这些结果都是函数的具体实现,而不是近似。RNN作为图灵机使用时,需要一个二进制序列作为输入,其输出必须离散化以提供二进制输出。利用单个有限大小的特定RNN计算在此设置下的所有函数是可能的(Siegelmann  and  Sontag(1995)用了886个单元)。图灵机的“输入”是要计算函数的详细说明(specification),所以模拟此图灵机的相同网络足以应付所有问题。用于证明的理论RNN可以通过激活和权重(由无限精度的有理数表示)来模拟无限堆栈。

现在我们研究图10.3中RNN的前向传播公式。这个图没有指定隐藏单元的激活函数。假设使用双曲正切激活函数。此外,图中没有明确指定何种形式的输出和损失函数。假定输出是离散的,如用于预测词或字符的RNN。表示离散变量的常规方式是把输出o作为每个离散变量可能值的非标准化对数概率。然后,我们可以应用softmax函数后续处理后,获得标准化后概率的输出向量。RNN从特定的初始状态h(0)开始前向传播。从t=1到t=τ的每个时间步,我们应用以下更新方程:

其中的参数的偏置向量b和c连同权重矩阵U、V和W,分别对应于输入到隐藏、隐藏到输出和隐藏到隐藏的连接。这个循环网络将一个输入序列映射到相同长度的输出序列。与x序列配对的y的总损失就是所有时间步的损失之和。例如,L(t)为给定的x(1),…,x(t)后y(t)的负对数似然,则

其中pmodel(y(t)|{x(1),…,x(t)})需要读取模型输出向量中对应于y(t)的项。关于各个参数计算这个损失函数的梯度是计算成本很高的操作。梯度计算涉及执行一次前向传播(如在图10.3展开图中从左到右的传播),接着是由右到左的反向传播。运行时间是,并且不能通过并行化来降低,因为前向传播图是固有循序的;每个时间步只能一前一后地计算。前向传播中的各个状态必须保存,直到它们反向传播中被再次使用,因此内存代价也是。应用于展开图且代价为的反向传播算法称为通过时间反向传播(back-propagation  through  time,BPTT),将在第10.2.2节进一步讨论。因此隐藏单元之间存在循环的网络非常强大但训练代价也很大。我们是否有其他选择呢?



10.2.1 导师驱动过程和输出循环网络


仅在一个时间步的输出和下一个时间步的隐藏单元间存在循环连接的网络(见图10.4)确实没有那么强大(因为缺乏隐藏到隐藏的循环连接)。例如,它不能模拟通用图灵机。因为这个网络缺少隐藏到隐藏的循环,它要求输出单元捕捉用于预测未来的关于过去的所有信息。因为输出单元明确地训练成匹配训练集的目标,它们不太能捕获关于过去输入历史的必要信息,除非用户知道如何描述系统的全部状态,并将它作为训练目标的一部分。消除隐藏到隐藏循环的优点在于,任何基于比较时刻t的预测和时刻t的训练目标的损失函数中的所有时间步都解耦了。因此训练可以并行化,即在各时刻t分别计算梯度。因为训练集提供输出的理想值,所以没有必要先计算前一时刻的输出。

由输出反馈到模型而产生循环连接的模型可用导师驱动过程(teacher  forcing)进行训练。训练模型时,导师驱动过程不再使用最大似然准则,而在时刻t+1接收真实值y(t)作为输入。我们可以通过检查两个时间步的序列得知这一点。条件最大似然准则是

在这个例子中,同时给定迄今为止的x序列和来自训练集的前一y值,我们可以看到在时刻t=2时,模型被训练为最大化y(2)的条件概率。因此最大似然在训练时指定正确反馈,而不是将自己的输出反馈到模型,如图10.6所示。

图10.6 导师驱动过程的示意图。导师驱动过程是一种训练技术,适用于输出与下一时间步的隐藏状态存在连接的RNN。(左)训练时,我们将训练集中正确的输出y(t)反馈到h(t+1)。(右)当模型部署后,真正的输出通常是未知的。在这种情况下,我们用模型的输出o(t)近似正确的输出y(t),并反馈回模型

我们使用导师驱动过程的最初动机是为了在缺乏隐藏到隐藏连接的模型中避免通过时间反向传播。只要模型一个时间步的输出与下一时间步计算的值存在连接,导师驱动过程仍然可以应用到这些存在隐藏到隐藏连接的模型。然而,只要隐藏单元成为较早时间步的函数,BPTT算法是必要的。因此训练某些模型时要同时使用导师驱动过程和BPTT。

如果之后网络在开环(open-loop)模式下使用,即网络输出(或输出分布的样本)反馈作为输入,那么完全使用导师驱动过程进行训练的缺点就会出现。在这种情况下,训练期间该网络看到的输入与测试时看到的会有很大的不同。减轻此问题的一种方法是同时使用导师驱动过程和自由运行的输入进行训练,例如在展开循环的输出到输入路径上预测几个步骤的正确目标值。通过这种方式,网络可以学会考虑在训练时没有接触到的输入条件(如自由运行模式下,自身生成自身),以及将状态映射回使网络几步之后生成正确输出的状态。另一种方式(Bengio  et  al.,2015b)是通过随意选择生成值或真实的数据值作为输入以减小训练时和测试时看到的输入之间的差别。这种方法利用了课程学习策略,逐步使用更多生成值作为输入。



10.2.2 计算循环神经网络的梯度


计算循环神经网络的梯度是容易的。我们可以简单地将第6.5.6节中的推广反向传播算法应用于展开的计算图,而不需要特殊化的算法。由反向传播计算得到的梯度,并结合任何通用的基于梯度的技术就可以训练RNN。

为了获得BPTT算法行为的一些直观理解,我们举例说明如何通过BPTT计算上述RNN公式(式(10.8)和式(10.12))的梯度。计算图的节点包括参数U、V、W、b和c,以及以t为索引的节点序列x(t)、h(t)、o(t)和L(t)。对于每一个节点N,我们需要基于N后面的节点的梯度,递归地计算梯度▽NL。我们从紧接着最终损失的节点开始递归:

在这个导数中,假设输出o(t)作为softmax函数的参数,我们可以从softmax函数可以获得关于输出概率的向量。我们也假设损失是迄今为止给定了输入后的真实目标y(t)的负对数似然。对于所有i、t,关于时间步t输出的梯度如下:

我们从序列的末尾开始,反向进行计算。在最后的时间步τ,h(τ)只有o(τ)作为后续节点,因此这个梯度很简单:

然后,我们可以从时刻t=τ-1到t=1反向迭代,通过时间反向传播梯度,注意h(t)(t<τ)同时具有o(t)和h(t+1)两个后续节点。因此,它的梯度由下式计算

其中表示包含元素的对角矩阵。这是关于时刻t+1与隐藏单元i关联的双曲正切的Jacobian。

一旦获得了计算图内部节点的梯度,我们就可以得到关于参数节点的梯度。因为参数在许多时间步共享,我们必须在表示这些变量的微积分操作时谨慎对待。我们希望实现的等式使用第6.5.6节中的bprop方法计算计算图中单一边对梯度的贡献。然而微积分中的▽W  f算子,计算W对于f的贡献时将计算图中的所有边都考虑进去了。为了消除这种歧义,我们定义只在t时刻使用的虚拟变量W(t)作为W的副本。然后,可以使用表示权重在时间步t对梯度的贡献。

使用这个表示,关于剩下参数的梯度可以由式(10.22)~式(10.28)给出:



因为计算图中定义的损失的任何参数都不是训练数据x(t)的父节点,所以我们不需要计算关于它的梯度。



10.2.3 作为有向图模型的循环网络


目前为止,我们接触的循环网络例子中损失L(t)是训练目标y(t)和输出o(t)之间的交叉熵。与前馈网络类似,原则上循环网络几乎可以使用任何损失。但必须根据任务来选择损失。如前馈网络,通常我们希望将RNN的输出解释为一个概率分布,并且通常使用与分布相关联的交叉熵来定义损失。均方误差是与单位高斯分布的输出相关联的交叉熵损失,例如前馈网络中所使用的。

当使用一个预测性对数似然的训练目标,如式(10.12),我们将RNN训练为能够根据之前的输入估计下一个序列元素y(t)的条件分布。这可能意味着,我们最大化对数似然

或者,如果模型包括来自一个时间步的输出到下一个时间步的连接,

将整个序列y的联合分布分解为一系列单步的概率预测是捕获关于整个序列完整联合分布的一种方法。如果我们不把过去的y值反馈给下一步作为预测的条件,那么有向图模型不包含任何从过去y(i)到当前y(t)的边。在这种情况下,输出y与给定的x序列是条件独立的。如果我们反馈真实的y值(不是它们的预测值,而是真正观测到或生成的值)给网络,那么有向图模型包含所有从过去y(i)到当前y(t)的边。

举一个简单的例子,让我们考虑对标量随机变量序列={y(1),…,y(τ)}建模的RNN,也没有额外的输入x。在时间步t的输入仅仅是时间步t-1的输出。该RNN定义了关于y变量的有向图模型。我们使用链式法则(用于条件概率的(3.6))参数化这些观察值的联合分布:

其中当t=1时竖杠右侧显然为空。因此,根据这样一个模型,一组值{y(1),…,y(τ)}的负对数似然为

其中

图模型中的边表示哪些变量直接依赖于其他变量。许多图模型的目标是省略不存在强相互作用的边以实现统计和计算的效率。例如,我们通常可以作Markov假设,即图模型应该只包含从{y(t-k),…,y(t-1)}到y(t)的边,而不是包含整个过去历史的边。然而,在一些情况下,我们认为整个过去的输入会对序列的下一个元素有一定影响。当我们认为y(t)的分布可能取决于遥远过去(在某种程度)的y(i)的值,且无法通过y(t-1)捕获y(i)的影响时,RNN将会很有用。

解释RNN作为图模型的一种方法是将RNN视为定义一个结构为完全图的图模型,且能够表示任何一对y值之间的直接联系。图10.7是关于y值且具有完全图结构的图模型。该RNN完全图的解释基于排除并忽略模型中的隐藏单元h(t)。

图10.7 序列y(1),y(2),…,y(t),·  ·  ·的全连接图模型。给定先前的值,每个过去的观察值y(i)可以影响一些y(t)(t>i)的条件分布。当序列中每个元素的输入和参数的数目越来越多,根据此图直接参数化图模型(如式(10.6)中)可能是非常低效的。RNN可以通过高效的参数化获得相同的全连接,如图10.8所示

更有趣的是,将隐藏单元h(t)视为随机变量,从而产生RNN的图模型结构(1)。在图模型中包括隐藏单元预示RNN能对观测的联合分布提供非常有效的参数化。假设我们用表格表示法来表示离散值上任意的联合分布,即对每个值可能的赋值分配一个单独条目的数组,该条目表示发生该赋值的概率。如果y可以取k个不同的值,表格表示法将有个参数。对比RNN,由于参数共享,RNN的参数数目为且是序列长度的函数。我们可以调节RNN的参数数量来控制模型容量,但不用被迫与序列长度成比例。式(10.5)展示了所述RNN通过循环应用相同的函数f以及在每个时间步的相同参数θ,有效地参数化的变量之间的长期联系。图10.8说明了这个图模型的解释。在图模型中结合h(t)节点可以用作过去和未来之间的中间量,从而将它们解耦。遥远过去的变量y(i)可以通过其对h的影响来影响变量y(t)。该图的结构表明可以在时间步使用相同的条件概率分布有效地参数化模型,并且当观察到全部变量时,可以高效地评估联合分配给所有变量的概率。

图10.8 在RNN图模型中引入状态变量,尽管它是输入的确定性函数,但它有助于我们根据式(10.5)获得非常高效的参数化。序列中的每个阶段(对于h(t)和y(t))使用相同的结构(每个节点具有相同数量的输入),并且可以与其他阶段共享相同的参数

即便使用高效参数化的图模型,某些操作在计算上仍然具有挑战性。例如,难以预测序列中缺少的值。

循环网络为减少的参数数目付出的代价是优化参数可能变得困难。

在循环网络中使用的参数共享的前提是相同参数可用于不同时间步的假设。也就是说,假设给定时刻t的变量后,时刻t+1变量的条件概率分布是平稳的(stationary),这意味着之前的时间步与下个时间步之间的关系并不依赖于t。原则上,可以使用t作为每个时间步的额外输入,并让学习器在发现任何时间依赖性的同时,在不同时间步之间尽可能多地共享。相比在每个t使用不同的条件概率分布已经好很多了,但网络将必须在面对新t时进行推断。

为了完整描述将RNN作为图模型的观点,我们必须描述如何从模型采样。我们需要执行的主要操作是简单地从每一时间步的条件分布采样。然而,这会导致额外的复杂性。RNN必须有某种机制来确定序列的长度。这可以通过多种方式实现。

在当输出是从词汇表获取的符号的情况下,我们可以添加一个对应于序列末端的特殊符号(Schmidhuber,2012)。当产生该符号时,采样过程停止。在训练集中,我们将该符号作为序列的一个额外成员,即紧跟每个训练样本x(τ)之后。

另一种选择是在模型中引入一个额外的Bernoulli输出,表示在每个时间步决定继续生成或停止生成。相比向词汇表增加一个额外符号,这种方法更普遍,因为它适用于任何RNN,而不仅仅是输出符号序列的RNN。例如,它可以应用于一个产生实数序列的RNN。新的输出单元通常使用sigmoid单元,并通过交叉熵训练。在这种方法中,sigmoid被训练为最大化正确预测的对数似然,即在每个时间步序列决定结束或继续。

确定序列长度τ的另一种方法是将一个额外的输出添加到模型并预测整数τ本身。模型可以采出τ的值,然后采τ步有价值的数据。这种方法需要在每个时间步的循环更新中增加一个额外输入,使得循环更新知道它是否是靠近所产生序列的末尾。这种额外的输入可以是τ的值,也可以是τ-t即剩下时间步的数量。如果没有这个额外的输入,RNN可能会产生突然结束序列,如一个句子在最终完整前结束。此方法基于分解

直接预测τ的例子见Goodfellow  et  al.(2014d)。



10.2.4 基于上下文的RNN序列建模


上一节描述了没有输入x时,关于随机变量序列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的情况,这可以通过不同的方式来实现。此处,我们回顾最常见和最明显的选择。

之前,我们已经讨论了将t=1,…,τ的向量x  (t)序列作为输入的RNN。另一种选择是只使用单个向量x作为输入。当x是一个固定大小的向量时,我们可以简单地将其看作产生y序列RNN的额外输入。将额外输入提供到RNN的一些常见方法是:

(1)在每个时刻作为一个额外输入,或

(2)作为初始状态h(0),或

(3)结合两种方式。

第一个也是最常用的方法如图10.9所示。输入x和每个隐藏单元向量h(t)之间的相互作用是通过新引入的权重矩阵R参数化的,这是只包含y序列的模型所没有的。同样的乘积在每个时间步作为隐藏单元的一个额外输入。我们可以认为x的选择(确定值),是有效地用于每个隐藏单元的一个新偏置参数。权重与输入保持独立。我们可以认为这种模型采用了非条件模型的θ,并将ω代入θ,其中ω内的偏置参数现在是输入的函数。

图10.9 将固定长度的向量x映射到序列Y上分布的RNN。这类RNN适用于很多任务(如图注),其中单个图像作为模型的输入,然后产生描述图像的词序列。观察到的输出序列的每个元素y(t)同时用作输入(对于当前时间步)和训练期间的目标(对于前一时间步)

RNN可以接收向量序列x(t)作为输入,而不是仅接收单个向量x作为输入。式(10.8)描述的RNN对应条件分布P(y(1),…,y(τ)|x(1),…,x(τ)),并在条件独立的假设下这个分布分解为

为去掉条件独立的假设,我们可以在时刻t的输出到时刻t+1的隐藏单元添加连接,如图10.10所示。该模型就可以代表关于y序列的任意概率分布。这种给定一个序列表示另一个序列分布的模型的还是有一个限制,就是这两个序列的长度必须是相同的。我们将在第10.4节描述如何消除这种限制。

图10.10 将可变长度的x值序列映射到相同长度的y值序列上分布的条件循环神经网络。对比图10.3,此RNN包含从前一个输出到当前状态的连接。这些连接允许此RNN对给定x的序列后相同长度的y序列上的任意分布建模。图10.3的RNN仅能表示在给定x值的情况下,y值彼此条件独立的分布