论文分享-->Independently Recurrent Neural Network (IndRNN): Building A Longer and Deeper RNN

本周开始,我将一周分享和总结三篇关于自然语言处理方面的论文及其开源代码(如果有的话),以期在三个月后的校招面试中能招架住面试官的各种提问。

本篇论文中了 CVPR 2018 ,提出了一种新型的 RNN 模型,论文实验显示相对于传统的 RNN 以及 LSTM GRU ,它在更长步长的数据集上有更好的表现,克服了传统 RNN 的一些缺点,具体总结分析请看下面。

传统 RNN 以及 LSTM GRU 缺陷

  1. 传统的 RNN 由于梯度消散或者梯度爆炸的原因,导致其无法很好的应对步长较长的输入。

    ht=σ(Wxt+Uht1+b)

    这里需要注意 RNN 共享一组参数 WUb ,也就是不同的 time_step 、样本,所对应的 WUb 是相同的,极大的减小了需要训练的和预估的参数。

    shape 分析(不考虑 batch_size ):
    M 表示 input x 的特征数或者其经过 word embedding 后的输入宽度; N 表示一个 cell 内神经元个数。
    ht shape[N] W shape[N,M] xt shape[M] U shape[N,N] ht1 shape[N] b shape[N]
    我们以损失函数对参数求导,然后在反向更新参数,然而这个求导的过程是一个一层一层累积的过程,随着层数的增加的,梯度消散或爆炸的现象也将越来越严重。具体的数学公式推导请看 RNN,LSTM数学推导

  2. LSTM 在一定程度上解决了梯度消散或爆炸的现象,使得能较好的处理较长的序列,但是由于使用了 sigmoidtanh saturate 激活函数,使得梯度在层之间的消散或者爆炸现象较严重。

    我们知道 sigmoid tanh saturate 激活函数会产生梯度消散或爆炸的现象,那么为什么我们在 LSTM 等网络中还使用这种激活函数呢?
    我个人的理解是:在LSTM中,激活函数并不是仅仅用来激活,刷选过滤信息,激活函数还有一个更重要的目的要实现,就是要使得记忆细胞在沿着传送带不断传送之前的记忆时,还需要保证信息不会膨胀,要保证信息量在一定范围内。那么这就必须使用sigmoid函数作为激活函数,reLu函数做不到这一点。当然有论文实验( Path\-normalized optimization of recurrent neural networks with relu activations )证明可以使用 RELU 作为激活函数,具体效果如何可细看这篇论文,这里不再深究。

    正是由于这个原因使得我们很少见到 RNN LSTM 等像 CNN 那样堆叠多层的模型,在 CNN 中,我们可以利用 relu resNet 等方法使得模型可以堆叠很深很深,也已有论文( Exploring the depths of recurrent neural networks with stochastic residual learning )实验证明,在深层的 RNN LSTM 的网络中搭建 resNet ,其实验效果并无多大提高。

  3. 可解释性差,我们由上面的 RNN 公式,其中 Uht1 矩阵乘法,其中 ht1 表示上一个每个神经元的输出, ht 表示当前时刻每个神经元的输出,由公式可知,上一个时刻的神剧原与当前时刻的神经元是交织纠缠在一起的,也就是在 RNN LSTM 中相同层内的神经元是相互纠缠在一起,很难独立解释他们的行为。

好了,作者不断在论文中讲传统 RNN LSTM 的缺点,是时候放大招了,看看作者提出了什么样的所谓”新型”的 RNN 来解决和避免这些缺点的。

IndRNN

首先看看 IndRNN 的数学公式:

ht=σ(Wxt+Uht1+b)

对,就是这么简单,就是将 RNN 数学公式中的 Uht1 改成了 Uht1 ,更简单的说就是将矩阵乘法改成 矩阵点成(我是这样叫的,就是两矩阵之间对应位置元素相乘而已,没什么大不了的), 这里面各个矩阵的 shape 基本没有什么变化,就是 U shape [N,N] 变成了向量 [N] ,使其能符合矩阵点乘的形式,那么这么做有什么好处呢?且听下面分析。

我们从上面的 IndRNN 数学公式可知,每一个时刻的 cell 内的某个神经元只与其他时刻的 cell 中对应的神经元有关,与其他神经元无关,于是第 n 个隐藏层神经元可以表示如下:

hn,t=σ(Wnxt+Unhn,t1+bn)

这里面 Wn 表示 W 矩阵的第 n 行, Un 表示 U 矩阵的第 n 行,其他的类似。

  1. 梯度在反向回传的时候,可以被调整,使其更有效的处理梯度消散或爆炸现象。是不是很迷茫?一脸懵逼?作者说可以被调整,然后就有效?什么鬼?来来,走一遍数学公式验证下。

    我们假设在第 T 步,需要优化的目标为 Jn ,那么当梯度回传到第 t 步时,其计算结果如下:

    Jnhn,t=Jnhn,Thn,Thn,t=Jnhn,Tk=tT1hn,k+1hn,k=Jnhn,Tk=tT1σn,k+1un=Jnhn,TuTtnk=tT1σn,k+1

    由上面的推导结果可知,梯度回传结果只与 u 和激活函数的导数有关,激活函数的导数在一定范围内改变(例如大部分激活函数, sigmoidtanhrelu 导数只在(0,1)),我们可以调整的只有 u (本身u就是模型参数),这就好办了,这就意味着只要调整调整 u 即可控制和调整反向传播时梯度变化。

    我们可以轻而易举的将 uTtnT1k=tσn,k+1  调整至适当的范围内。
    举例来说,我们希望梯度在反向传播时,不管梯度传递到哪一步,其获取的最小的有效梯度一定要大于 ϵ ,那么我们在定义 U 矩阵时,可以使:

    unϵk=tT1σn,k+1Tt
    这样不就可以了嘛,对吧?
    更进一步的说,上面因为定义了最小值,可以防止梯度消散,那么怎么防止梯度爆炸呢?同理嘛,可以定义:
    unϵk=tT1σn,k+1Tt,γk=tT1σn,k+1Tt

    这样就定义了梯度回传时的最大值和最小值了。
    有人可能要问了,上公式中的 k=tT1σn,k+1 是不知道的?这个问题。。。你想想 sigmoidtanhrelu 不都是在一定范围内变化吗?例如 relu 导数不是0就是1,当我们选用 relu 时,其:
    un[0,γTt]

    由上面的 IndRNN 数学公式可知,当 un=0 时表示该神经元有输入 xt 而无记忆信息输入。这是一个学习的过程,不同的神经元有不同长度的记忆信息保存。不过这一步我觉得可以使用 Leaky Relu ,这样就是避免了传递的梯度为0了。在开源的代码中,他是建议矩阵 u 最大值设置为 pow(2,1/timesteps)

  2. IndRNN 能保存更长的记忆,实验表面, IndRNN 能处理步长超过 5000 的序列,而 LSTM 最多只能处理步长 1000 的序列。关于这一点论文中并无过多证明。

  3. IndRNN 可以更好的与 non saturate 函数结合起来工作,例如 relu ,并且更具鲁棒性。论文中对比了传统 RNN IndRNN 反向传导的数学公式,得出传统 RNN 在反传梯度时变化更大,不容易控制,稳定性差,而 IndRNN 的梯度只是与 u 有关,波动性不大。

  4. IndRNN 可以进行多层堆叠,并且可以有效的利用 resNet 机制,使得可以搭建更深的网络。关于这一点,论文花了一部分篇幅证明了传统的两层 RNN ,注意激活函数必须是线性的,可以看做是两层 IndRNN 的一种特例,但是这和可以多层堆叠貌似没啥关系。然后又在理论上说,对输入做个卷积操作,加 batchnormlizationresNet IndRNN 就可以搭建的更深?具体操作可以参考论文中的语言模型的实验,不过我个人看来,像这种序列模型,搭建更深没啥意义,而在图像上深层 CNN 模型已经表现够好了。

  5. 每层中各个神经元相互独立,解释性强,这点上面数学已经证明,而不同层之间的神经元才有所交织。因为下层的神经元的输出 ht 作为上层神经元的输入 Xt

猜你喜欢

转载自blog.csdn.net/mr_tyting/article/details/80062797