即使不是 NLPer,现实中依然会面对很多序列问题。
全文内容来自 Ian Goodfellow, Yoshua Bengio 和 Aaron Courville 3位大老爷的作品“Deep Learning”的其中1章“Sequence Modeling: Recurrent and Recursive Nets” 1。
1986年 Rumelhart 等人提出循环神经网络。循环网络与多层网络相比,会共享每层的权重,从而能够扩展和应用网络于不同长度的序列案例,以及泛化这些案例。当1片特定的信息可以在序列中多处出现时,这样的共享尤为重要。比如,有两句话:“I went to Nepal in 2009”和“In 2009, I went to Nepal.”如果要求模型提取叙述者哪一年去的 Nepal,不管是输入句子的第2处还是第6处,2009 都是应识别的信息片。传统全连接前向网络对每处输入的特征都有单独的参数,所以要单独学习输入句子每一处的所有语法。相比之下,循环网络在不同时间步间共享权重。
现在很多“神经网络”的字眼已被“网络”替换。且后面不会涉及神经元的内容,所以一概用“网络”。
相关的想法是1维时间序列间用卷积。卷积方法是延时神经网络的基础 (1988~1990)。卷积操作允许网络在时间轴上共享参数,但为浅层网络 (输出序列的每个节点输出为很多相邻节点输入的函数)。每个时间步上用相同的卷积核。
循环网络以不同的方式共享参数。节点输出为前面节点输出的函数,节点的输出由前面节点输出用相同的更新规则产生。通过很深的计算图来共享权重,从而形成循环。
为简化描述,RNN 看作对1个包含时间步索引 t (从 1 到 τ ) 的向量 x(t) 的序列的操作。实际上,循环网络通常操作小的序列块 (batch)。这里简化表示,剔除块索引。此外,时间步长的索引仅指序列中的位置,而不一定指现实世界中的时间通道。 RNN 也可以应用于2维空间数据 (如图像) 。甚至当数据涉及时间时,如果提供观察到的整个序列给网络,那么网络可能要有及时回顾过去的连接。
循环代表某变量的过去值对未来值的影响。用循环的计算图定义循环网络。
计算图是形成一系列计算结构 (如涉及映射输入和参数到输出和损失) 的1种方式。把1个循环/递归计算展开为1个有重复结构 (对应1连串事件) 的图,从而实现深度网络结构间的参数共享。
例如,考虑动态系统的经典形式:
上述系统是循环的,因为时刻 t 的状态 s 的定义回溯到时刻 t−1 的状态 s 的定义。
对于有限时间步 τ ,用定义 τ−1 次来展开成图。当 τ=3 (时间步) 时,有
再举1例,外部输入 x(t) 驱动的动态系统:
循环网络可用很多不同方式搭建。几乎任何函数都可看作1个前向网络,本质上任何涉及循环的函数都能当作1个循环网络 (RNN)。
为表明状态即为网络的隐藏单元,上述方程重写为:
典型的 RNN 增加从状态 h 读取信息的输出层来预测。
当训练循环网络来用过去预测未来时,网络通常学习去用状态 h(t) 作为与截止到 t 的过去输入序列的任务相关方面的有损总结 (lossy summary),因为该总结映射任意长度的序列 (x(t),x(t−1),x(t−2),...,x(2),x(1)) 到固定长度的向量 h(t) 。取决于训练要求,该总结可能有选择地更明确地保持过去序列的某些部分。比如,RNN 用于统计语言建模时,通常给定前面的句子去预测下一个单词,它可能没必要保存截至时间 t 的输入序列的所有信息,只保存足够预测剩下语句的信息即可。
画 RNN 有2种方式。
用函数 g(t) 表示 t 时间步后的展开循环:
函数 g(t) 的输入为整个过去的序列 (x(t),x(t−1),x(t−2),...,x(2),x(1)) ,输出为当前状态,但展开的循环结构分解 g(t) 为函数 f 的重复应用。展开有两种好处:
以上好处使得单个模型 f 能在所有时间步和所有序列长度上操作。学习单个模型可以泛化到训练集中未出现的序列长度,参数共享使模型估计用到更少的训练样本。
循环图和展开图各有用途。循环图简明;展开图清晰地描述计算过程,并有助于说明随时间前向 (计算输出和损失) 和反向 (计算梯度) 的信息流。
循环网络的重要设计模式包括:
上图左对应的 RNN 是通用的。理论上的 RNN 被证用 RNN 的激活函数和权重 (无限精度的有理数) 可模拟1个无限长的堆栈。
假定隐含单元选用双曲正切激活函数,输出为离散值,如预测单词或字符。离散变量的每个可能值的未归一化对数概率表示离散变量的输出 o ,输入给 softmax 回归,输出归一化的概率向量 y^ 。前向传播的起始状态指定为 h(0) 。从时间步 t=1 ~ τ ,用下面的更新方程:
其中, pmodel(y(t)|{x(1),...,x(τ)}) 为模型的输出向量 y^(t) 预测为 y(t) 的概率。该损失函数的梯度计算费时。见上图左,梯度计算涉及展开图上的从左往右的前向传播,紧随从右往左的反向传播。运行时间为 O(τ) ,因前向传播图本质上为序列,所以不能并行减少时间。先计算前1个时间步才能得到后面的每个时间步。前向计算的状态会被保存直到反向计算时重用,所以内存开销也为 O(τ) 。应用于代价为 O(τ) 的展开图的反向传播算法被称为穿过时间的反向传播 (BPTT)。隐含单元间的循环网络因此很强大但训练困难。
某1时间步的输出仅循环连接到下1时间步的隐含单元的网络是严格弱的,因为它缺少隐含单元到隐含单元的循环连接。比如,它不能模拟1个通用的图灵机。因为它缺少隐含层到隐含层间的循环,所以网络用于预测未来时,输出单元要求捕捉过去所有的信息。显式训练输出单元来匹配训练集合的目标不太可能捕获关于输入过去历史的必要信息,除非用户了解系统的全部状态且把它作为训练目标的一部分。
对时间步 t 的预测与其训练目标比较的任何损失函数来说,消除隐含单元到隐含单元的循环可解耦所有的时间步。单独计算每个时间步 t 的梯度可并行训练,不必先算前面时间步的输出,因为训练集已提供输出的完美值。
从输出到状态的循环连接模型可能用“老师强迫”训练。训练时,模型接受真实输出 y(t) 为时间步 t+1 的输入,老师强迫是遵从最大似然标准的过程。检查两个时间步的序列,条件最大似然标准为:
本例中,时间步 t=2 时,给定训练数据中的截至 t 的 x 序列和 y 值,训练模型来最大化 y(2) 的条件概率。训练时指定最大似然,而非输出自循环。
隐含单元间缺少连接的模型上用老师强迫可避免穿过时间的反向传播。老师强迫也能用于输出与状态循环连接的模型。然而,一旦隐含单元变成1个前面时间步的函数,BPTT算法是必要的。一些模型同时用老师强迫与 BPTT。
如果网络用于开环模式 (网络输出反馈给输入),严格老师强迫会出问题。训练时网络输入与测试时输入可以有很大差异。
训练时,同时用老师强迫的输入与未来几个时间步后预测的正确目标作输入。另外1种缓和训练与测试输入间的差异,随机选择泛化输出或实际数据作输入。该方式用课程学习策略,逐渐用更多的泛化值作输入。
“老师强迫”原意可这样理解:假设状态为学生的学习态度,输入为学生的作业,输出为尽可能好的期末考试成绩。老师没办法让学渣突然爱上学习,所以,一般会通过强迫学生写作业这样的外在手段来提高学生的成绩。
循环网络的梯度计算比较直接。展开的计算图上用泛化的反向传播算法即可。展开图上的反向传播应用被称为穿过时间的反向传播 (BPTT) 算法。反向传播得到的梯度接着可用作任何通用的基于梯度的技术来训练 RNN。
BPTT 为 RNN 方程 (上述 RNN 的正向传播) 计算梯度。以重要设计模式中的左图为例 (隐含层单元间循环连接),计算图的节点包括 U,V,W,b,c,x(t),h(t),o(t),L(t) 。
a. 沿时间步的正向梯度
递归地计算每个节点 N 的梯度损失 ∇NL 。首先:
并不是 L=L(t) , L 为所有时间步的 L(t) 的和。
假定 softmax 回归输入 o(t) 输出 y^ ,且损失是真实目标 y(t) 的负对数似然。时间步 t 上输出的梯度 ∇o(t)L ,对所有的 i,t :
b. 沿时间步的反向梯度
从序列末端开始,时间步 τ , h(τ) 仅派生了 o(τ) (不存在 h(τ+1) ),有:
其中, diag(1−(h(t+1))2) 为包含元素 1−(h(t+1)i)2 的对角矩阵。这是第 i 个隐含单元在时间步 t+1 的双曲正切的 Jacobian 矩阵。
h(t+1)=tanh(b+Wh(t)+Ux(t+1))
c. 单个时间步内的参数梯度
获得计算图的内部节点的梯度后,可获得参数节点上的梯度。因参数在许多时间步间共享,所以当微积分操作涉及这些参数时必须小心处理。用反向传播方法得到计算图中单个边 (edge) 的梯度。然而, ∇Wf 考虑 W 对基于计算图中所有边的 f 的分布。为方便解释,引入伪变量 W(t) (定义为 W 在时间步 t 的复制)。用 ∇W(t) 表示时间步 t 的权重分布的梯度。
{c,V}:o(t)=c+Vh(t)
{b,W,U}:h(t)=tanh(b+Wh(t−1)+Ux(t))
这样,内部参数的梯度为:
a. 图模型参数化
上例的循环网络的损失 L(t) 为训练目标 y(t) 与 o(t) 间的交叉熵。正如1个前向网络,原则上应使用1个循环网络中几乎所有的损失。应选择基于任务的损失。通常希望视 RNN 的输出为1个概率分布,且与该分布相关的交叉熵定义为损失。均方差是1个输出为正态分布的交叉熵。
训练 RNN 时,给定过去输入,最大对数似然来估计下1个序列元素 y(t) 的条件分布:
当过去的 y 值不影响下1时间步的预测时,有向图模型不包含从过去的 y(i)(i=1,...,t−1) 到当前 y(t) 的边;否则包含所有这样的边。直接参数化该图模型 (下图左) 效率低,输入和参数的数目增长快。RNN 具有相同的全连接,且参数化更高效。
考虑 RNN 为1个随机标量序列 Y={y(1),...,y(τ)} ,无输入 x ,时间步 t 的输入仅为时间步 t−1 的输出 (上图右)。这样,RNN 模型定义为1个关于变量 y 的有向图模型。用条件概率的链式规则参数化 y 的联合分布:
图模型的边表明变量与其它变量直接的依赖关系。删除节点间相互作用弱的边可使许多图模型的统计与计算更高效。如 Markov 假设 (图模型应仅包含 {y(t−k),...,y(t−1)} 至 y(t) 的边,而非包含所有过去的边)。然而,所有过去的输入应对序列的下一个元素有影响。当遥远过去的某个 y(i) 值对 y(t−1) 无影响,但却对 y(t) 产生影响时,RNN 更有用。
b. 图模型解释 RNN
视 RNN 为1个具有完整的图结构,可表示任意 y 值对间的直接依赖的图模型。排除隐含单元 h(t) 的 RNN 模型可解释为完整的图。
视隐含单元 h(t) 为随机变量得出 RNN 的概率图模型结构。概率图模型中包含隐含单元显示 RNN 极为有效地参数化观测值的联合分布。假定用表格表示任意1个离散量的联合分布 (每个元素给出事件发生的概率),如果 y 可取 k 个不同值,表格有 O(kτ) 个参数。相比之下,参数共享使 RNN 有 O(1) 个参数 (为序列长度的函数)。RNN 参数数目可能会被调整来控制模型容量,而不必按序列长度扩展。RNN 每个时间步上循环使用相同的 f 和 θ 。图模型中插入隐含单元 h(t) 节点解耦了过去与未来,为它们之间的中间量。遥远过去的某个变量 y(i) 可能通过影响 h 来影响 y(t) 。
有效参数化后的图模型难以预测序列中间的丢失值。减少参数数目后循环网络却难以优化参数。
循环网络的权重共享的前提是假设相同的参数可用于不同的时间步。给定时间步 t 的变量,时间步 t+1 的变量的条件概率分布是静态的,即前后时间步的关系与 t 无关。原则上, t 可用作每个时间步的额外输入,从而学习者能够在尽可能共享权重的同时发现任何的时变性。这已经强过每个时间步 t 对应1个条件概率分布。但出现新的时间步时,仍要推断网络新增时间步的时变性。
c. 序列长度
在对模型采样前,先确定序列长度:
当输出 y 为单词中的字符时,加1个特殊标志来结束1个序列。特殊字符产生时,采样过程终止。训练集中,每个训练样本的 x(τ) 后面添加特殊字符输入。
添加二值输出,决定每个时间步继续或终止产生序列。该方法更通用,不会局限于字符序列,还可用于实数序列等。新的输出单元为交叉熵损失训练出的 Sigmoid 单元,来最大化每个时间步上继续还是终止序列正确预测时的对数似然概率。
添加序列长度 τ ,用模型来预测 τ 。先采样 τ ,再采样 τ 长度的序列样本。该方法要求在每个时间步的循环更新处添加额外的输入,来提示是否接近1个序列的末端。该输入可以是序列长度 τ 或者 τ−t (剩余的时间步),从而避免 RNN 产生序列结束前突然终止的可能。强行分解序列的联合概率分布:
任何变量为 P(y;θ) 的模型都可解释为条件分布为 P(y|ω) ( ω=θ )的模型。如果 ω 为输入 x 的函数,那么 P(y|x) 能表示与 P(y|ω) 分布相同的模型。
I. 向量输入
前面讨论过 x(t) 序列 ( t=1,...,τ ) 为输入的 RNN。另1种方法,添加单个定长的向量 x (序列的元素) 为 RNN 的额外输入。为 RNN 提供额外输入的常用方法:
引入权重矩阵 R ,每个时间步上隐含单元的输入为 xTR 。 x 的选择决定了每个隐含单元新的偏置 xTR 是否有效。非条件模型 (无输入 x 或 x(t) ) 的参数 θ 变为 ω 后仍然保持不变,除了 ω 中的偏置参数现在变为输入 x 的函数。
前面讨论的输入为 {x(1),...,x(τ)} ,现在讨论的输入为 {xTR,...,xTR} 。
该 RNN 适用于给图像加标题 (输入为单幅图像,输出为描述图像的语句)。观测序列的元素 y(t) 既为当前时间步的输入,也为训练时前面时间步的目标。
II. 向量序列输入
RNN 输入为向量序列 {x(1),...,x(τ)} 时,假设输出 y(t) 条件独立,,则分解为 (见“图模型参数化”部分):
假设不条件独立,时间步 t 的输出连到时间步 t+1 的隐含单元。此时,模型能表示任意序列 y 的概率分布。给定序列 x 来描述另1个序列 y 分布的模型时,限制两个序列长度相同。
大标题 (“1., 2., 3. …”) 为原作者给的,以 RNN 类型来区分;小标题 (“I., II., III. …”) 是我给的,以 实际问题的输入类型区分。所以,唯独这里的小标题的索引会不连贯。
III. 完整向量序列输入
许多应用的预测输出 y(t) 可能取决于完整的输入序列。如语音识别中,当前音位的正确解释可能因协同发音取决于后几个音位,且甚至可能因单词间语境取决于后几个单词:须往过去或未来看得更远来区分当前单词的两个声学相似的解释。手写识别和其它序列到序列的学习类似。
1997 年 Schuster 和 Paliwal 发明双向 RNN。2005~2013 年间在手写体识别,语音识别和生物信息等方面的应用取得巨大成功。
双向 RNN 结合正向 RNN 和 反向 RNN。正向 RNN 从序列起点随时间移动至终点,反向 RNN 从序列终点随时间移动至起点。正反向 RNN 的状态分别为 h(t) 和 g(t) 。过去和未来都会影响输出单元 o(t) ,但输出对时间步 t 周围的输入最为敏感,且不必指定围绕时间步 t 的固定大小的窗口。
用4个 RNN 可扩展至2维输入 (如图像)。每个 RNN 沿1个方向 (上,下,左和右) 移动。输入 2D 网格上的每个点 (i,j) ,当每个 RNN 的输入序列足够长时,输出 O(i,j) 能捕获大部分局部信息。与卷积网络相比,RNN 用于图像的计算耗时,但可得到同一特征图上特征间远程的相互作用。与前者相比,该 RNN 的正向传播方程改成用卷积来计算每层自底向上的输入会更好。
前面讨论过从输入序列到定长向量,从定长向量到输出序列,从输入序列到与输入序列长度相同的输出序列。
“向量序列输入”部分提及的 RNN 是长度为 τ 的 RNN,即定长 RNN。这里排除输入和输出变为相同长度的子序列,因为若子序列可完整描述模型输入,可重新定义 τsub(<τ) ,此时新的 RNN 依然是定长序列的输入输出。
IV. 可变向量序列输入
应用于语音识别,机器翻译或问答等的 RNN 输入序列长度不必等于输出序列长度。输入语句长度和输出语句长度通常不相同,尽管两者可能相关。
RNN 的输入经常称为“上下文”。上下文 C 为概括输入序列 X=(x(1),...,x(nx)) 的1个向量或序列。
2014 年 Cho 等人首次提出输入和输出为可变长序列的最简 RNN 结构,同年 Sutskever 等人对该结构扩展,首次用该方法取得领先的翻译效果。前者 (编码到解码结构) 排序另1个机器翻译产生的建议,后者 (序列到序列结构) 用1个单独的 RNN 完成翻译。
编码 (encoder/reader/input) RNN 处理输入序列,输出上下文 C (通常为最后隐含状态的简单函数)。
解码 (decoder/writer/output) RNN 输入单个定长的向量 (见”向量输入”部分的 x ),输出语句 Y=(y(1),...,y(ny)) 。
该结构的创新处为 nx和ny 可变,而之前所述的结构有约束 nx=ny=τ 。
编码 RNN 的最后的状态 hnx的 输出 C 为解码 RNN 的输入。如果 C 为向量,解码 RNN 仅仅是1个向量到序列的 RNN (见”向量输入”部分)。
编码器的隐含单元数目与解码器的隐含单元数目可以不相等。
2015 年 Bahdanau 等人在机器翻译的上下文中观察到,编码 RNN 的上下文输出 C 的维度太小会难以合适地概括长序列,因此它们把 C 从1个定长向量改为变长序列。另外,引入学习关联序列 C 元素至输出序列元素的注意机制。
联合训练两个 RNN 来最大化训练集中所有 x−y 序列对的 log1P(y1,...,yny|x1,...,xnx) 均值。
大多数 RNN 计算分解为参数与相关变换的3步:
每部分关联1个权重矩阵。换句话说,展开网络时,每部分的矩阵对应1个浅变换。深 MLP 中的单层变换称为浅变换。典型的浅变换用1个学得的仿射变换 (紧随1个固定的非线性) 表示。
实验证据强烈建议对浅变换引入深度,一致认为需要足够的深度来满足映射要求。
2013 年 Graves 等人首次显示分解 RNN 状态进多层的巨大收益。下图 (a) 中分层的底层可视为转换原输入成隐含状态更高层的更合适的表示。
2014 年 Pascanu 等人让上述每部分有1个 MLP,如下图 (b)。根据对每部分分配足够容量来考虑整体的表示容量,但该方法添加深度后会因优化困难而可能影响训练。
总的来说,浅层结构优化更容易,添加额外的深度延长了变量从时间步 t 到时间步 t+1 的最短路径。比如,状态间用1个单隐含层的 MLP,则与常规 RNN 相比,任意两个不同时间步间变量的最短路径变为两倍。
然而,跳过隐含单元到隐含单元路径上的连接可缓解路径延长问题,见下图 (c)。
与图 (b) 相比,图 (c) 的隐含单元到隐含单元的路径上,多出了1个连接与 MLP 的单隐含层并联。
递归网络是循环网络的另1种泛化,但计算图的结构为1个深层树,而不是 RNN 的链式结构。
1990 年 Pollack 提出递归网络。在 NLP 和计算机视觉方面,递归网络成功用于处理送入神经网络的数据结构。
对序列长度为 τ 的循环网络,递归网络的深度 (构成非线性操作的数目) 从 τ 大幅减少至 O(logτ) ,有助于处理长期依赖 (long-term dependencies)。最好的树结构的设计问题尚未解决。1种选择为采用独立于数据的树结构 (如平衡二叉树)。某些领域中,外在方法能表现出合适的树结构。比如处理自然语句时,递归网络的树结构可固定为由自然语言解析器提供的语句解析树。学习器根据给定输入发现和推断出的树结构是理想的树结构。
递归网络的变种很多。1997 和 1998 年 Frasconi 等人用数据关联树结构,且用输入和输出关联树的节点。每个节点的计算不必是传统的人工神经计算 (所有输入的仿射变换,紧随1个单调的非线性)。比如,2013 年 Socher 发现建模概念 (连续向量表示) 间的关系时张量操作和双线性形式有用。
循环网络中,学习长期依赖的基本问题为许多层上传播的梯度往往会消失 (常见) 或爆炸 (少见,优化伤害大)。即使参数稳定 (可保存记忆,且梯度不爆炸),与短期作用相比,长期作用的权重指数衰减,依然难以解决问题。其它方法用更深的处理 (Hochreiter, 1991; Bengio 等, 1994; Pascanu 等, 2013)。
循环网络的多个时间步相同函数组合产生了极强的非线性。
循环网络的组成函数类似矩阵乘法。循环关系可表示为1个去掉非线性激活函数和输入 x 的简单循环网络:
循环网络中该问题尤为明显。假设权重 ω 为标量,权重自乘很多次后会根据 ω 的幅值消失或爆炸。然而,对每个时间步权重 w(t) 不同的非循环网络不成立。如果初始状态给定为1,则 t 时刻的状态为 ∏tw(t) 。假设 w(t) 从均值为 0 ,方差为 v 的分布 (独立同分布) 中随机产生。则该乘积的方差为 O(vn) 。为获得理想的方差 v∗ ,选择每个时间步的权重为 v=v∗−−√n 。因此,小心选择缩放的很深前向网络可以避免梯度消失或爆炸问题。
有人希望通过保留梯度在不消失和不爆炸的参数空间区域内,不幸的是,为保存对小扰动鲁棒的区域,RNN 一定会进入梯度消失的参数空间区域。具体地,长期作用的梯度指数级地小于短期作用的梯度。这并不意味着梯度不可学,只是要花很长的时间去学长期作用,因为短期作用出现的波动常会隐藏长期作用的信号。1994 年 Bengio 等人实验表明扩大捕获的依赖范围会使基于梯度的优化难度加大,对长度为10或20的序列,用 SGD 的 传统 RNN 训练权重的成功率快速减为0。
从 h(t−1) 到 h(t) 的循环权重与从 x(t) 到 h(t) 的输入权重为循环网络中最难学的参数。避免该问题的1种方法为让隐含单元捕获过去输入的历史,仅学习输出权重。该想法被称为回响状态网络 (ESN) 和 液态机 (liquid state machine)。与前者相比,后者用尖峰神经元 (二值输出) 替换连续值的隐含单元。两者都属于储备池计算 (reservoir computing),储备时序特征的隐含单元可捕捉不同方面的输入历史。
储备池计算循环网络与核机器相似:映射1个任意长度的序列 (截止至时间步 t 的输入历史) 至1个定长的向量 (循环状态h^{(t)}),可以用线性预测器 (典型地,线性回归)。训练标准可设计为输出权重的凸函数。比如,从隐含单元到输出的映射用线性回归,且训练标准为均方差,那么该标准为凸函数且可用简单的学习算法求解。
因此,如何设置输入和循环权重使循环网络的状态能够表示1套丰富的输入历史。存储池计算给出的答案为视循环网络为1个动态系统,且设置输入和循环权重使动态系统接近稳定。
使状态至状态的转换函数的 Jacobian 特征值接近1。(?) 1个循环网络的重要特征是 Jacobians J(t)=∂s(t)∂s(t−1) 的特征值谱。 J(t) 的谱半径定义为其特征值绝对值的最大值。
为理解谱半径的影响,考虑 t 不变时的 Jacobian 矩阵 J 的反向传播 (如当网络纯线性时)。假设 J 为对应特征 λ 的1个特征向量 v 。用梯度向量 g 开始,1步反传后得到 Jg , n 步反传得到 J(n)g 。换为 g 的扰动版本 g+δv 开始反传, n 步后得到 J(n)(g+δv) 。所以,从 g+δv 反传 n 步后多发散 J(n)δv 。如果 v 选为特征值为 λ 的 J 的单位特征向量, Jacobian 的乘法仅在每步乘以1个常数。两个反传的差值为 δ|λ|(n) 。 当 v 对应 λ 的最大值时,该扰动得到的差值最大。
当 λ>1 时, δ|λ(n)| 指数增大;当 λ<1 时, δ|λ(n)| 指数减小。
该例假定每步的 Jacobian 相同,对应1个线性的循环网络。引入非线性时,非线性的导数经过许多时间步后将接近0,避免大的谱半径引起的爆炸。
用重复的矩阵乘法的反传的一切,同样适用于1个线性网络的正向传播,状态 h(t+1)=h(t)TW 。
当线性映射 WT 总按 L2 模缩小 h ,那么该映射是收缩的,每个时间步后都会变小一点。因此,当我们用有限精度来保存状态向量时,会使网络容易遗忘历史信息。
Jacobian 矩阵告诉我们 h(t) 正向迭代或 h(t+1) 反向迭代时的微小变化。 W 和 J 不必为对称阵 (实数方阵),所以它们可以有复数特征值和特征向量,虚部对应潜在的震荡行为 (迭代使用相同的 Jacobian)。尽管 h(t) 或反传中 ht 的小变化为实值,但可用复数形式表示。迭代应用 Jacobian 矩阵时,复数绝对值大于1时的特征值对应指数增长,否则缩小。
带非线性的 Jacobian 在每个时间步都可无约束地变化,因此具有更复杂的动态特性。然而,1个起始的小差异,若干时间步后仍然会变为大差异。 与纯线性相比,非线性网络用诸如 tanh 这样压扁的非线性导致循环的动态特性有界。注意到,即使正向传播的动态特性有界,反向传播可能会保持动态特性无界。 比如,当 tanh 单元的序列插入纯线性网络的线性区,且用谱半径大于1的权重矩阵相连。然而,所有 tanh 单元同时为线性激活点的状况很少见。
回响状态网络只是修正权重的谱半径,但因如 tanh 这样饱和非线性的稳定效果,使权重不会爆炸。
最近,设置ESN中权重的技术可用于在1个可学习的循环网络 (随时间步反传的隐含层间的循环的权重) 中初始化权重,以便学习长期依赖。其中,结合稀疏初始化模式,谱半径为1.2时效果不错。
处理长期依赖的1种方式为设计多时间尺度上操作的模型。细粒度时间尺度上操作可处理更多细节,粗粒度时间尺度上操作可更有效将遥远的历史信息转换为当前信息。所以针对既细又粗的时间尺度来设计策略:其中包含跨时间步跳过连接,“泄露单元”累积不同时间常数的信号,删除某些连接来建立细粒度时间尺度。
为获取粗粒度,将遥远过去的变量与当前变量直接相连。受 1988 年 Lang 与 Hinton 在前向神经网络中插入延时的启发,1996 年 Lin 等人采用直连的方法。
梯度随时间步数的增加可能会指数地消失或爆炸。为缓解该问题, Lin 等人引入 d 个延时进循环连接。此时梯度指数消失可看成1个关于 τd (而非 τ ) 的函数。
对1个指数规律衰减的量,幅值变为其 1e 倍所需的时间 τ 称为时间常数。2 如果为 τd ,梯度会消失得更快。所以,应该改为 τd 吧~
因延时和单步连接,梯度依然会按 τ 指数地爆炸。所以,尽管该方法不可能很好地表示所有的长期依赖,但可捕获相对更长的依赖。
为使路径上的导数乘积接近1,线性自连接单元和连接权重接近1。
累积某值 v(t) (?) 的移动平均 μ(t) :用 μ(t)←αμ(t−1)+(1−α)v(t) 更新, α 为连接 μ(t−1) 到 μ(t) 的参数。当 α 接近1时,移动平均可记住过去的信息很长一段时间;当 α 接近0时,过去信息被迅速排除。线性自连接的隐含单元类似于移动平均,被称为泄露单元。
跳过 d 个时间步的连接可确保单元总能学习到 d 个时间步前的影响。另1种方式为用1个接近1的权重来线性自连接。线性自连接方法通过调整实数值 α (而非调整整型跳过的长度),效果更平滑和灵活。
用泄漏单元设置时间常数有两种基本策略。一种为手动固定值,比如,初始时刻从某分布中采样1次值。另一种为将时间常数设置为自由参数,然后学习它。不同时间尺度上的泄露单元有助于长期依赖。
解决长期依赖的另1种方式为多时间尺度上组织 RNN 的状态,让信息更容易在缓慢时间尺度上长距离地流动。
与前面跳过时间步的连接不同,删除连接涉及删除时间步长度为1的连接,且替换成更长的连接。 修改后的单元只能在更长时间尺度上操作,但也可选择聚焦到短项连接上。
使循环单元在不同的时间尺度上操作的方法很多。1种为令循环单元泄漏,但不同组的单元关联不同的固定时间尺度 (1992 年 Mozer 提出,2013 年 Pascanu 等人成功应用)。另1种为对不同组的单元用不同的更新频率,在不同的时间步上显式离散地更新。 这是 1996 年 Bengio 和 2014 年 Koutnik 的方法,在许多 Benchmark 数据集上效果不错。
实际应用中本文最有效的序列模型为门控 RNN,包括长短时记忆和基于门控循环单元的网络。
类似泄漏单元,门控 RNN 基于使随时间的路径上的导数不消失或爆炸。泄漏单元用手动选择的常数或参数作为连接权重。门控 RNNs 将连接权重泛化成每个时间步都可能改变。
泄漏单元使网络能够在很长的时间内累积信息 (如特定的特征或类型)。然而,用到累积的信息后,网络会遗忘过去的状态。比如,当子序列组成序列,且需要通过设置过去的状态为0来遗忘它。除了手动决定何时清除状态,希望网络能学习到何时去决定清除。
1997 年 Hochreiter 和 Schmidhuber 最早提出的长短时记忆的主要贡献是引入自循环来创建使信息长期流动的路径。
使自循环取决于上下文,而非固定不变。通过使自循环的权重可门控,累积的时间尺度能动态变化。此时,即使 LSTM 固定参数,累积的时间尺度可随着输入序列而改变,因为时间常数为模型的输出。LSTM 在很多应用中极为成功,如无约束手写体识别,语音识别,手写体生成,机器翻译,图像加标题和解析。
LSTM 的框图见上图。LSTM 循环网络单元间彼此循环连接,来替换普通循环网络的隐含单元。用1个常规人工神经单元计算输入特征。如果 Sigmoid 门允许,输入的特征值会累加给状态。状态单元有1个由遗忘门控制的线性自循环。输出门可关闭LSTM 循环网络的输出。所有的门单元都用 Sigmoid 非线性,而输入单元可用压扁的非线性 (如 tanh)。状态单元可用作门单元的额外输入。黑色方块为1个时间步的延时。
压扁的非线性的原文为“squashing nonlinearity”。通常指各种非线性的激活函数 3,这里用 tanh 为例。
对应的前向传播方程用浅层循环网络结构给出。更深的结构也有成功的应用。每个循环单元不再是仅对输入到循环单元的仿射变换按元素应用非线性,除了 RNN 外部循环,LSTM 循环网络有“LSTM 单元”,每个单元有1个内部自循环。每个“LSTM 单元”有与普通 RNN 相同的输入和输出,但有更多的参数且有1个控制信息流的门控单元。
最重要的部分是状态单元 s(t)i ,具有1个与泄漏单元相似的线性自循环。但遗忘门 (forget gate) 单元 f(t)i (时间步 t 的单元 i ) 用1个 Sigmoid 单元设置权重至 0 ~ 1 之间,来控制自循环的权重 (或相关时间常数):
用条件自循环权重 f(t)i来更新 LSTM 单元的内部状态。