zoukankan      html  css  js  c++  java
  • [转] RNN 中为什么要采用 tanh,而不是 ReLU 作为激活函数?

    为什么CNN用ReLU

    Sigmoid的导数范围在[公式]内,如果采用Sigmoid作为激活函数,多个小于1的导数连续相乘容易引起梯度消失。

    tanh的导数范围在[公式]内,虽然导数可以达到1,但是在边缘区域仍然有梯度消失的问题。

    ReLU的正半轴不存在梯度消失问题,负半轴的存在可以带来一定的稀疏性,但是也会带来梯度消失问题,可以用LeakyReLU和PReLU等方法缓解。此外,ReLU的计算量远远小于Sigmoid和tanh。

    为什么RNN用tanh

    在LSTM和GRU中,内部的各种门多采用sigmoid激活函数,因为需要确定“0-1”的各种状态;而隐状态的激活函数多采用tanh。

    RNN的每个时间步的权重是相同的,bp过程相当于权重的连续相乘,因此比CNN更容易出现梯度消失和梯度爆炸,因此采用tanh比较多。tanh也会出现梯度消失和梯度爆炸,但是相比于Sigmoid好很多了。理论上ReLU+梯度裁切也可以。

    作者:何之源
    链接:https://www.zhihu.com/question/61265076/answer/186347780
    来源:知乎
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    来尝试回答下。其实题主的问题可以拆分成下面两个部分:

    • 为什么在CNN等结构中将原先的sigmoid、tanh换成ReLU可以取得比较好的效果?
    • 为什么在RNN中,将tanh换成ReLU不能取得类似的效果?

    先来简单讨论下第一个问题。设输入数据为 [公式] ,对 [公式] 的卷积操作就可以看做是 [公式] (如果不理解为什么,可以参考这个答案的前半部分:如何理解深度学习中的deconvolution networks?)。我们设第一层卷积的参数为 [公式] ,第二层卷积的参数是 [公式],依次类推。又设激活函数为 [公式] ,每一层卷积在经过激活函数前的值为 [公式] ,经过激活函数后的值为 [公式]

    按照上面的表示,在CNN中,输入 [公式] ,第一层的输出就是 [公式] ,第二层的输出就是 [公式] ,第三层的输出就是 [公式] 。设最终损失为 [公式] ,我们来尝试从第三层开始,用BP算法推导一下损失对参数 [公式] 的偏导数,看看会发生什么。

    为了简洁起见,略过求导过程,最后的结果为 [公式]我们常常说原始神经网络的梯度消失问题,这里的 [公式][公式] 就是梯度消失的“罪魁祸首”。例如sigmoid的函数,它的导数的取值范围是(0, 0.25],也就是说对于导数中的每一个元素,我们都有 [公式][公式] ,小于1的数乘在一起,必然是越乘越小的。这才仅仅是3层,如果10层的话, 根据[公式] ,第10层的误差相对第一层卷积的参数 [公式] 的梯度将是一个非常小的值,这就是所谓的“梯度消失”。

    ReLU函数的改进就是它使得 [公式][公式][公式]这样的话只要一条路径上的导数都是1,无论神经网络是多少层,这一部分的乘积都始终为1,因此深层的梯度也可以传递到浅层中。

    那为什么同样的方法在RNN中不奏效呢?其实这一点Hinton在它的IRNN论文里面(arxiv:[1504.00941] A Simple Way to Initialize Recurrent Networks of Rectified Linear Units)是很明确的提到的:

    也就是说在RNN中直接把激活函数换成ReLU会导致非常大的输出值。为了讲清楚这一点,我们先用同上面相似的符号把原始的RNN表示出来:

    [公式]

    [公式]

    在这个表示中,RNN每个阶段的输入是 [公式]和CNN每一层使用独立的参数 [公式] 不同,原始的RNN在每个阶段都共享一个参数 [公式]如果我们假设从某一层开始输入 [公式] 和偏置 [公式] 都为0,那么最后得到的输出就是 [公式]这在某种程度上相当于对参数矩阵 [公式] 作连乘,很显然,只要 [公式] 有一个大于1的特征值,在经过若干次连乘后都会导致结果是一个数值非常庞大的矩阵。

    另外一方面,将激活函数换成ReLU也不能解决梯度在长程上传递的问题。同样考虑 [公式][公式] 的导数。在CNN中,每一层的参数 [公式] 是互相独立的,然而RNN中 [公式] 参与了每个时间段的运算,因此 [公式][公式] 导数更复杂,写出来是 [公式] 。我们可以看下最后 [公式] 这部分,使用ReLU后,当梯度可以传递时,有 [公式] ,但这个式子中还是会有两个 [公式] 的连乘。在更长程上,就会有更多 [公式] 的连乘。对于CNN来说,这个部分是 [公式] 进行连乘,一方面它们都是稀疏矩阵,另一方面 [公式] 互不相同,很大程度上都能抵消掉梯度爆炸的影响。

    最后,IRNN在RNN上使用了ReLU,取得了比较好的结果,其中的原因在于,它对 [公式][公式] 取了比较特殊的初值: [公式] , [公式] 。这样在梯度的式子 [公式] 中W尽管会连乘,但是会类似于单位矩阵 [公式] 的连乘,不会引起太明显的梯度数值变化。另外一方面,也不会引起非常大的输出值(这点可以自行带入表达式验证)。

    以上,如果有哪里说的不对的,还烦请各位大佬批评指正。

     
    /* 人应该感到渺小,在宇宙面前,在美面前,在智慧面前; 而在人群中,应该意识到自己的尊严。*/
  • 相关阅读:
    Array的 map() 和 reduce()
    欧几里得算法求解最大公约数
    JavaScript Function
    JavaScript Hoisting(提升)
    activemq的事务消息
    Spring整合Activemq
    10张图带你深入理解Docker容器和镜像
    Thread类的interrupt方法
    简单工厂、工厂方法、抽象工厂笔记
    设计模式之观察者模式
  • 原文地址:https://www.cnblogs.com/Arborday/p/14957684.html
Copyright © 2011-2022 走看看