作者:华校专
作者信息:
华校专,曾任阿里巴巴资深算法工程师、智易科技首席算法研究员,现任腾讯高级研究员,《Python 大战机器学习》的作者。
编者按:
算法工程师必备系列更新啦!继上次推出了算法工程师必备的数学基础后,小编继续整理了必要的机器学习知识,全部以干货的内容呈现,哪里不会学哪里,老板再也不用担心你的基础问题!
循环神经网络recurrent neural network:RNN :用于处理序列数据 的神经网络,其中 表示第 i 个样本。 是一个序列 ,序列的长度可以是固定的、也可以是变化的。
recurrent neural network:RNN
循环神经网络是一种共享参数的网络:参数在每个时间点上共享。
传统的前馈神经网络在每个时间点上分配一个独立的参数,因此网络需要学习每个时间点上的权重。而循环神经网络在每个时间点上共享相同的权重。
循环网络中使用参数共享的前提是:相同参数可以用于不同的时间步。即:前一个时间步和后一个时间步之间的关系与时刻 t 无关。
就像几乎所有函数都可以被认为是前馈神经网络,几乎任何涉及循环的函数都可以被认为是循环神经网络。
考虑动态系统的经典形式: 。其中: 称作系统的状态, 为参数。
对于有限的时间步 ,应用 次定义可以展开这个图:
利用有向无环图来表述:
假设 为 t 时刻系统的外部驱动信号,则动态系统的状态修改为: 。
2.当训练RNN根据过去预测未来时,网络通常要将 作为过去序列信息的一个有损的representation 。
RNN
representation
attention
3.网络的初始状态 的设置有两种方式:
固定为全零。这种方式比较简单实用。这种情况下,模型的反向梯度计算不需要考虑 ,因为 全零导致对应参数的梯度贡献也为 0 。
使用上一个样本的最后一个状态,即: 。这种场景通常是样本之间存在连续的关系(如:样本分别代表一篇小说中的每个句子),并且样本之间没有发生混洗的情况。此时,后一个样本的初始状态和前一个样本的最后状态可以认为保持连续性。另外注意:模型更新过程中
4.展开图的两个主要优点:
这些优点直接导致了:
基于图展开和参数共享的思想,可以设计不同模式的循环神经网络。根据输入序列的长度,RNN 网络模式可以划分为:输入序列长度为0、输入序列长度为1 、输入序列长度为 。
0
1
设样本集合为 ,其中每个样本为:
对应的网络输出为: 。
设真实标记 为真实类别标签,网络的输出 为预测为各类别的概率分布(经过 softmax 归一化的概率)。则该样本的损失函数为:
softmax
其中 为第 t 个时间步的损失函数。通常采用负的对数似然作为损失函数,则有:
其中 K 为类别的数量,为 的第 k 个分量, 为示性函数:
如果将真实类别 标记扩充为概率分布 ,其中真实的类别 位置上其分量为 1,而其它位置上的分量为 0。则 就是真实分布 和预测分布 的交叉熵:
数据集的经验损失函数为:
.
对于输入序列长度为1的样本, 。
对于输入序列长度大于1的样本, ,其中 为第 i 个样本的序列长度。设样本对应的真实标记集合为 ,其中每个样本的标记为:
对于输出序列长度为1的样本, 。对应的网络输出为: 。
对于输出序列长度大于1的样本, ,其中 为第 i 个样本的序列长度。
输入序列长度为0:此时网络没有外部输入,网络将当前时刻的输出作为下一个时刻的输入(需要提供一个初始的输出作为种子)。
如文本生成算法:首先给定 作为种子,然后通过 t 时刻为止的单词序列来预测 t+1 时刻的单词;如果遇到某个输出为停止符,或者句子长度达到给定阈值则停止生成。
在这个任务中,任何早期输出的单词都会对它后面的单词产生影响。
2.在零长度输入序列的RNN 网络中,过去的输出序列 通过影响 来影响当前的输出 ,从而解耦 和 。
3.该模型的数学表示为:
其中 表示模型第 t 步输出 的第 k 个分量。
单个样本的损失为:
更新方程
其中输出到隐状态的权重为 ,隐状态到输出的权重为 ,隐状态到隐状态的权重为 , 为输入偏置向量和输出偏置向量。
输入序列长度为1 :模型包含单个 作为输入。此时有三种输入方式:输入 作为每个时间步的输入、输入 作为初始状态 、以及这两种方式的结合。
输入 作为每个时间步的输入:
模型的数学表示:
单个样本的损失:
更新方程:
其中输入到隐状态的权重为 ,输出到隐状态的权重为 ,隐状态到输出的权重为 ,隐状态到隐状态的权重为 , 为输入偏置向量和输出偏置向量。
输入 作为初始状态 :
在图注任务中,单个图像作为模型输入,模型生成描述图像的单词序列。图像就是输入 ,它为每个时间步提供了一个输入。通过图像和 t 时刻为止的单词序列来预测 t+1 时刻的单词。
输出 有两个作用:用作 t+1 时刻的输入来预测 ;用于 t 时刻计算损失函数 。
当输入 作为初始状态 时,每个时间步也没有额外的输入。它与零输入RNN 网络的区别在于:
零输入RNN 的初始输出 是需要给定的,而这里的初始状态 是给定的。
多长度输入序列的RNN 包含了多输出&隐-隐连接RNN、多输出&输出-隐连接RNN、单输出&隐-隐连接RNN 等网络类型。
多输出&隐-隐连接RNN
多输出&输出-隐连接RNN
单输出&隐-隐连接RNN
2.多输出&隐-隐连接循环网络:每个时间步都有输出,并且隐单元之间有循环连接。
2.多输出&隐-隐连接
其中输入到隐状态的权重为 ,隐状态到输出的权重为 ,隐状态到隐状态的权重为 , 为输入偏置向量和输出偏置向量。
该网络将一个输入序列映射到相同长度的输出序列。
3.多输出&输出-隐连接循环网络:每个时间步都有输出,只有当前时刻的输出和下个时刻的隐单元之间有循环连接。
3.多输出&输出-隐连接
其中输入到隐状态的权重为 ,隐状态到输出的权重为 ,输出到隐状态的权重为 , 为输入偏置向量和输出偏置向量。
4.单输出&隐-隐连接 循环网络:隐单元之间存在循环连接,但是读取整个序列之后产生单个输出。
4.单输出&隐-隐连接
单输出&隐-隐连接RNN将一个输入序列映射到单个输出。
5.多输出&输出-隐连接 循环网络比较于多输出&隐-隐连接循环网络,该网络的达能力更小。
5.多输出&输出-隐连接
多输出&隐-隐连接
多输出&输出-隐连接
6.多输出&输出-隐连接循环网络虽然表达能力不强,但是更容易训练:通过使用前一个时间步的真实标记 来代替输出 ,使得每个时间步可以与其他时间步分离训练,从而允许训练期间更多的并行化。
6.多输出&输出-隐连接
对于输入序列长度为零或者为1的RNN模型,必须有某种办法来确定输出序列的长度。有三种方法来确定输出序列的长度:
当输出是单词时,可以添加一个特殊的标记符。当输出遇到该标记符时,输出序列终止。此时需要改造训练集,对训练数据的每个输出序列末尾手工添加这个标记符。
在模型中引入一个额外的二元输出单元,该输出单元用于指示:当前时间步是继续生成输出序列,还是停止生成。
这种办法更普遍,适用于任何RNN 。
该二元输出单元通常使用sigmoid单元,被训练为最大化正确地预测到每个序列结束的对数似然。
sigmoid
在模型中引入一个额外的输出单元,该输出单元预测输出序列的长度 本身。
这种方法需要在每个时间步的循环更新中增加一个额外输入,从而通知循环:是否已经到达输出序列的末尾。
其原理是基于条件概率: 。
以 多输出&隐-隐RNN为例,设:输入到隐状态的权重为 ,隐状态到输出的权重为 ,隐状态到隐状态的权重为 , 为输入偏置向量和输出偏置向量;激活函数为双曲正切激活函数 。
多输出&隐-隐RNN
设网络从特定的初始状态 开始前向传播,从 到 的每个时间步,则有更新方程:
多输出&隐-隐RNN 的单个样本损失函数为: 。该损失函数的梯度计算代价较高:
tanh
ReLU
back-propagation through time:BPTT:通过时间反向传播算法,其算法复杂度为 。
back-propagation through time:BPTT
由 BPTT 计算得到梯度,再结合任何通用的、基于梯度的技术就可以训练 RNN 。
BPTT
计算图的节点包括参数 ,以及以 t 为索引的节点序列 以及 。
根据 ,则有: 。
令节点 ,则有: 。则有:
根据定义 ,得到:
当 时, 同时具有 两个后续节点,因此有:
4.一旦获得了隐单元及输出单元的梯度,则可以获取参数节点的梯度。
注意:由于参数在多个时间步共享,因此在参数节点的微分操作时必须谨慎对待。微分中的算子 在计算 对于 f 的贡献时,将计算图的所有边都考虑进去了。但是事实上:有一条边是 t 时间步的 ,还有一条边是 t+1 时间步的 ,。为了消除歧义,使用虚拟变量 作为 的副本。用 表示参数 在时间步 t 对于梯度的贡献。将所有时间步上的梯度相加,即可得到 。
5.根据定义 。则有:
考虑到 对于每个输出 都有贡献,因此有:
记:
6.根据定义 ,即:
考虑到 对于每个隐向量 都有贡献,因此有:
多输出&输出-隐连接RNN模型可以使用 teacher forcing 算法进行训练。
teacher forcing
teacher forcing训练的本质原因是:当前隐状态与早期隐状态没有直接连接。虽然有间接连接,但是由于 已知,因此这种连接被切断。
长期依赖的问题是深度学习中的一个主要挑战,其产生的根本问题是:经过许多阶段传播之后,梯度趋向于消失或者爆炸。
考虑一个没有非线性、没有偏置非常简单的循环结构: 。则有:
设 可以正交分解时: 。其中 为正交矩阵, 为特征值组成的三角阵。则:
前向传播:
对于特征值的幅度不到 1 的特征值对应的 的部分将随着 t 衰减到 0 。
对于特征值的幅度大于 1 的特征值对应的 的部分将随着 t 指数级增长。
反向传播:
对于特征值幅度不到1的梯度的部分将随着 t 衰减到 0 。
对于特征值幅度大于1的梯度的部分将随着 t 指数级增长 。
若考虑非线性和偏置,即: ,有:
前向传播:由于每一级的 的幅度被 函数限制在 (-1,1) 之间,因此前向传播并不会指数级增长。这也是为什么 RNN 使用 tanh 激活函数,而不使用 relu 的原因。
(-1,1)
relu
反向传播:由于隐状态的幅度被 函数限制在 (-1,1) 之间,因此 对 进行了一定程度上的缩小。 越大,结果越小。
如果 的特征值经过这样的缩小之后,在每个时刻都远小于1(因为每个时刻缩小的比例会变化),则该梯度部分将衰减到 0 。
如果 的特征值经过这样的缩小之后,在每个时刻都远大于1,则该梯度部分将指数级增长。
如果 的特征值经过这样的缩小之后,在不同的时刻有时候小于1有时候大于1(因为每个时刻缩小的比例会变化),则该梯度部分将比较平稳。
对于非循环神经网络,长期依赖的情况稍好。
缓解长期依赖的一个策略是:设计多个时间尺度的模型:在细粒度的时间尺度上处理近期信息、在粗粒度时间尺度上处理远期的信息。
得到粗粒度时间尺度的一种方法是跳跃连接:增加从远期的隐变量到当前隐变量的直接连接。
普通的RNN中循环从时刻 t 隐变量连接到了时刻 t+1 隐变量,跳跃连接会增加一条从时刻 t 到时刻 t+d 隐变量的连接。注意:是增加而不是替代。
引入了 d 延时的循环连接可以减轻梯度消失的问题。现在梯度指数降低的速度与 相关,而不是与 相关。这允许算法捕捉到更长时间的依赖性。但是这种做法无法缓解梯度指数级爆炸的问题。
得到粗粒度时间尺度的另一种方法是删除连接:主动删除时间跨度为 1 的连接,并用更长的连接替换。
删除连接与跳跃连接的区别:
缓解梯度爆炸和梯度消失的一个方案是:尽可能的使得梯度接近1。这可以通过线性自连接单元来实现。
如:(其中 为隐单元, 为输入)
拥有类似行为的隐单元称作渗漏单元。
渗漏单元与跳跃连接的区别:
渗漏单元和跳跃连接的 参数有两种设置方式:
可以使得不同的循环单元在不同时间尺度上工作:
对于长期依赖问题中的梯度爆炸,最常用的解决方案是梯度截断。
梯度截断有两种方案,设梯度 :
第二种方案可以确保截断后的梯度仍然是在正确的梯度方向上。但是实践表明:两种方式的效果相近。因为逐元素的梯度截断时,梯度更新的方向不仅不再是真实梯度方向,甚至也不是mini-batch的梯度方向。但是它仍然是一个使得目标值下降的方向。
mini-batch
当梯度大小超过了阈值时,即使采用简单的随机步骤,效果往往也非常好。即:随机采用大小为 v 的向量来作为梯度。因为这样通常会使得梯度离开数值不稳定的状态。
如果在mini-batch 梯度下降中应用了梯度范数截断,则真实梯度的方向不再等于所有mini-batch梯度的平均。
对于一个mini-batch ,梯度范数截断不会改变它的梯度方向。对于许多个mini-batch,使用梯度范数截断之后,它们的平均值并不等同于真实梯度的范数截断。
因此使用范数截断的mini-batch 梯度下降,引入了额外的梯度误差。这种误差有助于随机梯度下降算法逃离局部极小值。
梯度截断有助于解决梯度爆炸,但是无助于解决梯度消失。为解决梯度消失,有两种思路:
LSTM
正则化引导信息流:希望梯度向量 在反向传播时能维持其幅度。即:希望 与 尽可能一样大。
考虑到
Pascanu et al. 给出了以下正则项:
Pascanu et al.
文章须知
文章作者:华校专
责任编辑:周岩 Logic 破茧
审核编辑:阿春
微信编辑:破茧
本 文由『运筹OR帷幄』原创发布
原文链接:http://www.huaxiaozhuan.com/%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0/chapters/6_RNN.html
往期 精彩回顾 适合初学者入门人工智能的路线及资料下载(图文+视频)机器学习入门系列下载中国大学慕课《机器学习》(黄海广主讲)机器学习及深度学习笔记等资料打印《统计学习方法》的代码复现专辑 机器学习交流qq群955171419,加入微信群请扫码: