摘要:
这一节主要讲RNN的发展过程,针对如何解决梯度消失和爆炸以及长期依赖问题所引出的一系列解决方法。一种处理长期依赖的方法是设计一个模型能够在不同时间粒度都能起作用,比如在细粒度上模型能够处理一些细节,在粗的时间粒度上能够将过去的信息传递到未来。 有很多不同的策略能够构建这样一个既有细粒度又有粗粒度的模型,包括对于相距比较远的两个时刻的状态除了有一条沿着时刻流动的状态外,额外添加一个直连的链接,能保证信息无损失地向前传递。“leaky units”能整合不同时刻的信号.
10.9.1 时间维度的跳跃连接
一种处理粗粒度时间的方法是将过去很久之前的状态直连到当前的时刻,这样能保证信息能传递很远,这种想法最早可以追溯到 Lin等(1996),而且这个想法类似于在前馈神经网络中嵌入延迟信息(Lang and Hinton,1988), 而在一般的RNN中,一般只在相邻两个时刻之间有循环连接,在更长的时间跨度上添加连接是可能的(Bengio,1991).
正如我们在Section 8.2.5中所介绍的那样,梯度可能关于时间步数呈指数消失或爆炸。 Lin et al(1996) 就利用在更长的时间跨度上添加循环连接来解决梯度消失或梯度爆炸问题。 现在指数减小的梯度与\(\frac{\tau}{d}\)相关而不是与\(\tau\),因为还存在延迟和单个连接,梯度还可能以\(\tau\)为系数发生爆炸,这使得学习算法能捕获更长的依赖关系,虽然并不是所有的时间跨度长的依赖能被用这种方式很好地表示。
10.9.2 泄露单元与一系列不同时间尺度
获得导数乘积接近1的另一种方式是设置线性自连接单元,而且这些连接的权重是1.
假设我们需要对\(\mu\)进行更新,其更新方式是滑动平均的更新方式,\(\mu^{t+1} = \alpha\mu^t+(1-\alpha)v^t\),参数\(\alpha\)就是从\(\mu^t\)到\(\mu^{t+1}\)的一个线性自连接的例子,当\(\alpha\)接近于1时,滑动平均值\(\mu\)记住了过去很长一段时间的信息,当\(\alpha\)接近于0时,过去时刻的信息会很快就被丢弃。线性自连接的隐藏单元的效果于这种滑动平均值的效果类似。这种隐藏单元就被称为泄露单元。
跨度为d的跳跃连接能确保d时刻之前的信息能传递到当前时刻,使用一个权重为1的线性自连接也能保证过去时刻的信息能传递到未来,不过是一种不同的方式而已。线性自连接的方法能通过调整数值\(\alpha\)值的大小,从而使得这种信息传递比较平滑,而不是调整整数值的跳跃长度。
这个想法由 Mozer(1992)和 EI Hihi以及Bengio(1996)等人提出。
一共有两种策略设置泄露单元使用的时间常数,一种策略是手动将其固定为常数,例如初始化时从某些分布采样它们的值。另一种策略是使时间常数称为自由变量,并学习出来,在不同时间尺度使用这样的渗透单元似乎能帮助学习长期依赖。
10.9.3 删除连接
另一种处理长期依赖的方法是在多个时间尺度组织RNN状态,信息在较慢的时间尺度上更容易长距离流动。
这个想法于之前讨论的时间维度上的跳跃连接不同,因为它涉及主动删除长度为1的连接并用更长的连接替换他们。以这种方式修改的单元被迫在长时间尺度上运作,而通过时间跳跃连接是添加边。收到这种新连接的单元,可以学习在长时间尺度上运作,但也可以选择专注于自己其他的短期连接。(后面还有一小部分没太懂,搞懂估计需要去看原始论文)。
10.10 长短时记忆和其他门控RNN
撰写此文时,在实际应用中最有效的序列模型是 门控RNN(gated RNNs). 这其中包括基于长短时记忆和基于门控循环单元的神经网络。
类似于泄露单元。门控RNN也是基于这样的一个想法:希望梯度在传播过程中不会发生梯度消失或梯度爆炸。泄露单元通过一个连接权重实现此功能,连接权重可以手动设置或者当作一个参数来学习。门控的RNN将这个连接权重进行了推广,在每个时刻连接权重都可能发生变化。泄露单元允许网络累计很长一段时间的信息,然而, 一旦这个信息已经被使用过了,或许网络就不再需要这个信息了,这时网络应该学会忘记这些信息。比如,如果一个序列是由一系列子序列组成,我们希望在子序列内利用泄露单元累计过去信息,而在不同的子序列之间,我们希望能有一个机制使得网络能忘记上一个子序列中的信息,我们希望神经网络能够自己学习什么时候应该忘记过去的信息,而不是由我们手动决定什么时候忘记过去的信息,这就是门控RNN所做的事情。
LSTM
(这一段翻译过来非常拗口,我就用我自己的语言表述一下),自循环使得梯度可以长时间沿着路径流动,后来一个关键的改进是自循环的权重由上下文决定,而不是固定的。再后来通过加入门控机制,使得累计的时间尺度可以动态地改变,在这种情况下,即使是参数固定的LSTM,其累计的时间尺度也可以动态改变,因为时间常数(对应于泄露单元的参数\(\alpha\))是模型本身的输出。
LSTM在很多领域都取得了成功。一个LSTM单元的结构如图10.16所示,其相对应的forward equation如下所示,现在给出的是一层RNN,深度RNN也已经被成功应用了(Graves et al. 2013; Pascanu et al. 2014a)。 LSTM 循环网络除了外部的RNN循环外,还具有内部的LSTM细胞循环,因此,LSTM不是简单地向输入和循环单元的仿射变换之后施加一个逐元素的非线性操作。与普通的循环网络类似,每个单元有相同的输入和输出,但也有更多的参数和控制信息流动的门控单元系统。其中最重要的组成成分是状态单元\(s_i^t\),这个状态单元有一个与前面的泄露单元类似的自循环。然而,这里的自循环的权重是通过忘记门单元 \(f_i^t\)来控制的。通过一个sigmoid函数设置该忘记门的值在0到1之间。
\[ f_i^{(t)} = \sigma(b_i^f + \sum_jU_{i,j}^fx_j^{(t)}+\sum_jW_{i,j}^fh_j^{(t-1)}) \]
这里\(x^t\)是当前时刻的输入向量,\(h^{t-1}\)是上一时刻LSTM cell的输出,\(b^f,U^f,W^f\)分别是忘记们的偏置项,输入权重以及循环权重。LSTM细胞内的隐藏状态是通过以下公式更新的,更新的时候要基于忘记门更新:
\[ s_i^t = f_i^ts_i^{t-1} + g_i^t\sigma(b_i + \sum_jU_{i,j}x_j^t+\sum_jW_{i,j}h_j^{t-1}) \]
这里\(b,U,W\)分别表示偏置项,输入的权重以及循环权重。 \(g_i^t\)是一个外部的输入门,其计算方式类似于上面的忘记门(通过一个sigmoid函数使得其输出范围是0-1):
\[ g_i^t = \sigma(b_i^g+\sum_jU_{i,j}^gx_j^t + \sum_jW_{i,j}^gh_j^{(t-1)}) \]
这个cell的输出 \(h_i^t\)也可以由输出门 \(q_i^t\)关闭:
\[ h_i^t = tanh(s_i^t)q_i^t \]
\[ q_i^t = \sigma(b_i^o + \sum_jU_{i,j}^ox_j^t + \sum_jW^o_{i,j}h_j^{t-1}) \]
LSTM已被证明能比简单的循环网络结构更能有效地学习序列问题中的长期依赖,LSTM不同的变种也已被广泛的研究和使用,这将在接下来的部分讨论。