深度学习—激活函数详解(Sigmoid、tanh、ReLU、ReLU6及变体P-R-Leaky、ELU、SELU、Swish、Mish、Maxout、hard-sigmoid、hard-swish)


由于深度学习模型中其它的层都是线性的函数拟合,即使是用很深的网络去拟合,其仍是避免不了线性的特性,没法进行非线性建模,而加入非线性激活函数单元,当线性函数的输出层通过非线性激活单元的时候,其输出呈现一种非线性的变化,这样通过多层的拟合,就能够完成对输入的非线性建模操做。同时还能够起到一种特征组合的做用。html

好的激活函数的特征通常应当是平滑的,并且对于负值有较好的处理。python


关于本文中的图形绘制请参考我这篇博客:最全面:python绘制Sigmoid、Tanh、Swish、ELU、SELU、ReLU、ReLU六、Leaky ReLU、Mish、hard-Sigmoid、hard-Swish等激活函数(有源码)web


饱和激活函数

  • 主要是Sigmoidtanh函数,又加上了hard-Sigmoid函数

Sigmoid函数

 啊

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

观察Sigmoid函数曲线,能够知道其输出分布在【0,1】区间,并且在输入值较大和较小的状况,其输出值变化都会比较小,仅仅当输入值接近为0时,它们才对输入强烈敏感。Sigmod单元的普遍饱和性会使得基于梯度的学习变得很是困难。由于这个缘由,如今已经不鼓励将它们做为前馈网络的隐藏单元。网络

观察Simod导数曲线,呈现一个相似高斯分布的驼峰装,其取值范围在【0,0.25】之间,而咱们初始化后的网络权值一般小于1,所以当层数增多时,小于0的值不断相乘,最后就会致使梯度消失的状况出现。而梯度爆炸则是当权值过大,致使其导数大于1,大于1的数不断相乘,发生梯度爆炸。
同时Sigmoid还有其余缺点,如输出不是以0为中心,而是0.5,这样在求解权重的梯度时,梯度老是正或负的,指数计算耗时。svg

总之不推荐使用sigmoid饱和激活函数。函数


tanh函数

公式:
在这里插入图片描述
不过sigmoid和tanh在RNN(LSTM、注意力机制等)结构上有所应用,做为门控或者几率值。性能

这里关于tanh为何比simoid收敛快有一个比较好的说法,引用了如下说法:学习

梯度消失问题程度
tanh′(x)=1−tanh(x)2∈(0,1)tanh′⁡(x)=1−tanh⁡(x)2∈(0,1)
sigmoid: s′(x)=s(x)×(1−s(x))∈(0,1/4)sigmoid: s′(x)=s(x)×(1−s(x))∈(0,1/4)
能够看出tanh(x)的梯度消失问题比sigmoid要轻.梯度若是过早消失,收敛速度较慢.
以零为中心的影响
若是当前参数(w0,w1)的最佳优化方向是(+d0, -d1),则根据反向传播计算公式,咱们但愿 x0 和 x1 符号相反。可是若是上一级神经元采用 Sigmoid 函数做为激活函数,sigmoid不以0为中心,输出值恒为正,那么咱们没法进行最快的参数更新,而是走 Z 字形逼近最优解。测试

在这里插入图片描述


hard-Sigmoid函数

公式:
在这里插入图片描述
解释:当 x < -2.5输出0,当 x > 2.5时,输出1,当 -2.5 < x & x < 2.5时,输出为 (2x+5) / 10,线性函数。
那么其导数,当 x < -2.5输出0,当 x > 2.5时,输出0,当 -2.5 < x & x < 2.5时,输出为 1 / 5优化

hard-Sigmoid函数时Sigmoid激活函数的分段线性近似。从公示和曲线上来看,其更易计算,所以会提升训练的效率,不过同时会致使一个问题:就是首次派生值为零可能会致使神经元died或者过慢的学习率。

  • Sigmoid函数和hard-Sigmoid函数对比图:

在这里插入图片描述

在这里插入图片描述


非饱和激活函数

  • Sigmod和tanh都是饱和激活函数,即二者在输入值较大或较小的时候对输入值再也不那么敏感。
    而以Relu及其变体为表明的一类非饱和激活函数在防止梯度消失方面具备无可比拟的优点,现现在基本不多在网络中使用Sigmod等饱和激活函数。

Relu(修正线性单元):

将全部的负值置为0,而其他的值不变。
缺点:一个很大的梯度流过一个Relu神经元,更新过梯度后,那么这个神经元对大部分数据都没有激活做用了,所以梯度就是0。会形成神经元的死亡。
在这里插入图片描述
在这里插入图片描述


Relu6(抑制其最大值):

  • 公式:

在这里插入图片描述
即当 x > 6时,其导数也为0。

  • 目的:

主要是为了在移动端float16的低精度的时候,也能有很好的数值分辨率,若是对ReLu的输出值不加限制,那么输出范围就是0到正无穷,而低精度的float16没法精确描述其数值,带来精度损失。

  • ReLU和ReLU6图表对比:

在这里插入图片描述

在这里插入图片描述


ELU(指数线性单元)

其将激活函数的平均值接近零,从而加快学习的速度。同时,还能够经过正值的标识来避免梯度消失的问题。根据一些研究,ELU的分类 精确度要高于Relu。

  • 融合了sigmoid和ReLU,左侧具备软饱和性,右侧无饱和性。

  • 右侧线性部分使得ELU可以缓解梯度消失,而左侧软饱可以让ELU对输入变化或噪声更鲁棒。

  • ELU的输出均值接近于零,因此收敛速度更快。

  • 在 ImageNet上,不加 Batch Normalization 30 层以上的 ReLU
    网络会没法收敛,PReLU网络在MSRA的Fan-in (caffe )初始化下会发散,而 ELU
    网络在Fan-in/Fan-out下都能收敛。

在这里插入图片描述
在这里插入图片描述


SELU

就是给ELU乘上一个系数,该系数大于1。
在这篇paper Self-Normalizing Neural Networks中,做者提到,SELU可使得输入在通过必定层数以后变为固定的分布。
之前的ReLU、P-ReLU、ELU等激活函数都是在负半轴坡度平缓,这样在激活的方差过大时可让梯度减少,防止了梯度爆炸,可是在正半轴其梯度简答的设置为了1。而SELU的正半轴大于1,在方差太小的时候可让它增大,可是同时防止了梯度消失。这样激活函数就有了一个不动点,网络深了以后每一层的输出都是均值为0,方差为1.

在这里插入图片描述
在这里插入图片描述


Leaky-Relu / R-Relu

Leaky ReLU和ReLU不一样的是,ReLU是将全部的负值设为零,而Leaky ReLU是给全部负值赋予一个非零斜率,即用一个负值部分除以大于1的数。(公式中a是大于1的一个常数)

在这里插入图片描述

在这里插入图片描述


P-Relu(参数化修正线性单元)

能够看做是Leaky ReLU的一个变体,不一样的是,P-ReLU中的负值部分的斜率是根据数据来定的,即a的值并非一个常数。

R-Relu(随机纠正线性单元)

R-ReLU也是Leaky ReLU的一个变体,只不过在这里负值部分的斜率在训练的时候是随机的,即在一个范围内随机抽取a的值,不过这个值在测试环节会固定下来。


Swish

paper : Searching for Activation Functions
beta是个常数或者能够训练的参数。其具备无上界有下界、平滑、非单调的特性。其在模型效果上优于ReLU。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

当β = 0时,Swish变为线性函数f(x)=x2f(x)=x2.
β → ∞, σ(x)=(1+exp(−x))−1σ(x)=(1+exp⁡(−x))−1为0或1. Swish变为ReLU: f(x)=2max(0,x)
因此Swish函数能够看作是介于线性函数与ReLU函数之间的平滑函数.


hard-Swish

paper: Searching for MobileNetV3

  • 公式:

在这里插入图片描述
在论文中,做者提到,虽然这种Swish非线性提升了精度,可是在嵌入式环境中,他的成本是非零的,由于在移动设备上计算sigmoid函数代价要大得多。

所以做者使用hard-Swishhard-Sigmoid替换了ReLU6SE-block中的Sigmoid层,可是只是在网络的后半段才将ReLU6替换为h-Swish,由于做者发现Swish函数只有在更深的网络层使用才能体现其优点。

首先是确定了Swish的重要性,而后指出在量化模式下,Sigmoid函数比ReLU6的计算代价大的多,因此才有了这个ReLU6版本的h-Swish

  • Swishhard-Swish图表对比:

加粗样式

在这里插入图片描述
关于hard-Swish的梯度图我不肯定有没有画错,若是有错误还请指正,谢谢。


Mish

Mish: A Self Regularized Non-Monotonic Neural Activation Function
这篇应该是笔者写时关于激活函数改进的最新一篇文章。

相比Swish有0.494%的提高,相比ReLU有1.671%的提高。

在这里插入图片描述
关于公式及其导数推导以下图所示:
在这里插入图片描述
Mish和Swish中参数=1的曲线对比:(第一张是原始函数,第二张是导数)
在这里插入图片描述
在这里插入图片描述
为何Mish表现的更好:

以上无边界(即正值能够达到任何高度)避免了因为封顶而致使的饱和。理论上对负值的轻微容许容许更好的梯度流,而不是像ReLU中那样的硬零边界。

最后,可能也是最重要的,目前的想法是,平滑的激活函数容许更好的信息深刻神经网络,从而获得更好的准确性和泛化。

要区别多是Mish函数在曲线上几乎全部点上的平滑度

Maxout

paper:Maxout Networks
与常规的激活函数不一样,Maxout是一个能够学习的分段线性函数。
其能够看作是在深度学习网络中加入了一层激活函数层,包含一个参数k,这一层相比ReLU,Sigmoid等,其在于增长了k个神经元,而后输出激活值最大的值。
其须要学习的参数就是k个神经元中的权值和偏置,这就至关于常规的激活函数一层,而Maxout是两层,并且参数个数增长了K倍。
其能够有效的原理是,任何ReLU及其变体等激活函数均可以当作分段的线性函数,而Maxout加入的一层神经元正是一个能够学习参数的分段线性函数。
优势:其拟合能力很强,理论上能够拟合任意的凸函数;
具备ReLU的全部优势,线性和非饱和性;
同时没有ReLU的一些缺点,如神经元的死亡;
缺点:致使总体参数的激增。

下图非自制:
在这里插入图片描述


关于激活函数统一说明

ELU在正半轴取输入x奸情了梯度弥散状况(正半轴导数到处为1),而这一点特性,基本上除了swish其余非饱和激活函数都具备这个特性。而只有ReLU在负半轴的输出没有复制,因此ReLU的输出均值必定是大于0的,而当激活值的均值非0时,会对下一层形成以bias,也就是下一层的激活单元会出现bias shift现象,经过不断的层数叠加,bias shift会变得很是大。而ELU可让激活函数的输出均值尽量接近0,相似于BN操做,可是计算复杂度更低。并且虽然Leaky ReLU和PReLU等都有负值,可是它们不保证在不激活的状态对噪声鲁棒,这里的不激活指的是负半轴。而ELU在输入取较小值时具备软饱和的特性,提高了对噪声的鲁棒性。Swish和ELU都是能够取负值,同时在负半轴具备软饱和的性能,提升了对噪声的鲁棒性,SELU效果比ELU效果还要更好。
在这里插入图片描述


参考连接

ELU激活函数的提出
激活函数(ReLU, Swish, Maxout)
激活函数ReLU、Leaky ReLU、PReLU和RReLU


2019.10.30. 但愿能帮到你。点赞是对我最大的承认。谢谢。