作者:灿视,来源:灿视学长,校准:xiaoxingxing,如有侵权,请联系作者删除!
一、为什么要使用激活函数
若网络中不用激活函数,那么每一层的输出都是输入的线性组合。无论神经网络有多少层,网络的输出都是输入的线性组合,这种网络就是原始的感知机(perceptron)。若网络没有激活函数,则每层就相当于矩阵相乘,深层神经网络,无非是多矩阵相乘。
激活函数给神经元引入了非线性因素,使得神经网络可以任意逼近任何非线性函数,这样神经网络就可以应用到众多的非线性模型中。网络使用非线性激活函数后,可以增加神经网络模型的非线性因素,网络可以更加强大,表示输入输出之间非线性的复杂的任意函数映射。
网络的输出层可能会使用线性激活函数,但隐含层一般都是使用非线性激活函数。
二、非零均值的问题(non-zero-centered)
部分激活函数是非零均值的,比如ReLU,Sigmoid等激活函数,它会造成网络收敛变慢,因为后一层的神经元将得到上一层输出的非0均值的信号作为输入,如果,其中
表示当前层的非激活输出,
为上一层的激活输出也是当前层的输入,在进行反向传播更新权重
时,对其求导得到梯度
,而
都是直接与
相关的,如果
是大于0的值,那么这时梯度方向完全取决于
,也就是激活函数求导,如果
恒正或者恒负,那么就会出现zig-zagging dynamics的问题,是的网络收敛变慢。
其中zig-zagging dynamics 的图像就如下面图像,相比于直接“奔向”最优点, 会更加“折腾”。
三、常见激活函数
下面开始我们介绍下常用的激活函数,其中对于部分激活函数,画图都是采用Pytorch中Functional的默认参数来进行绘制的。
Sigmoid激活函数
Sigmoid激活函数公式如下:
Sigmoid函数用于隐藏层神经元输出,取值范围(0,1),将一个实数映射到(0,1)区间,也可以用来做二分类或者生成Attention Mask。
Sigmoid激活函数的缺点:
- 激活函数计算量大,反向传播求梯度时,求导涉及到除法。
- 反向传播时,很容易出现梯度消失的情况,从而无法完成深层网络的训练,因此不建议在中间层使用sigmoid激活函数。
- Sigmoid函数运算量大。如我们用Flops(每秒浮点操作次数)来衡量模型的计算量指标。则ReLU运算量是1 ,而Sigmoid包括了减、取幂、加、除共4 Flops。其次,指数运算,复杂度就更高。
Sigmoid激活函数梯度消失的原因如下:
反向传播中,需要对激活函数求导,sigmoid的求导如下:
Sigmoid激活函数原函数及导数图形如下:由图可知,导数从0 开始很快就又趋近于0 了,易造成“梯度消失”现象。
Tanh激活函数
Tanh激活函数的公式如下,也称为双切正切函数,取值范围为[-1,1]。
而Tanh函数的反传公式为:
Tanh函数的缺点同sigmoid函数的缺点类似,当x很大或者很小时,接近于0,会导致梯度很小,权重更新非常缓慢,即梯度消失问题。从下面图像也可以看出,靠近图像两端越平缓,梯度越小。
Tanh激活函数图像以及梯度图像如下:
Tanh 在特征相差明显时的效果会相对更好,在循环过程中会不断扩大特征效果。与 sigmoid的区别是,tanh 是零均值的,因此实际应用中 tanh会比sigmoid更好,不过需要具体尝试。
ReLU激活函数
ReLU(Rectified Liner Unit)激活函数主要用于隐层神经元输出,公式为,函数图像与其求导的导数图像如图所示:
- ReLU激活函数的特点是:输入信号小于0时,输出都是0,输入信号大于0时,输出等于输入。
- ReLU激活函数的优点是使用 ReLU时SGD 的收敛速度会比使用的 Sigmoid或Tanh快很多。
- ReLU的缺点是神经网络训练的时候很“脆弱”,很容易就会出现神经元死亡。
例如,一个非常大的梯度流过一个 ReLU神经元,更新过参数之后,这个神经元再也不会对任何数据有激活现象了,那么这个神经元的梯度就永远都会是0。(Dead ReLU Problem)。
- 非零均值,所以一般会在ReLU后加BN。
SoftMax激活函数
多用于多分类神经网络输出,公式为:
主要用于将分类输出最后归一化到[0,1],。当然也可以也Sigmoid一样,用于Attention Mask,学习特征的权重矩阵。
Softplus激活函数
公式如下:
将ReLU与Softplus放在一起对比的话,则如图像所示:
可以看出Softplus可以看作ReLU的平滑,其中加1是为了保证非负性。Softplus可以看作强制非负校正函数和max(0,x)的平滑版本。
Mish激活函数
Mish函数的公式如下:
在pytorch中Mish激活函数代码如下:
x = x*(torch.tanh(F.softplus(x)))
函数图像如下:
Mish函数无上边界(即正值可以达到任何高度)避免了由于封顶而导致的饱和。理论上对轻微的负值允许更好的梯度流,而不是像ReLU中那样的硬零边界。
最后,可能也是最重要的,平滑的激活函数允许更好的信息深入神经网络,从而得到更好的准确性和泛化。
Leaky ReLU和PReLU
Leaky ReLU的公式如下:
是一个
区间内的固定参数,与ReLU相比,Leaky ReLU给所有负值赋予一个非零斜率
,这样保留了一些负轴的值,使得负轴的信息不会全部丢失。
而PReLU可以看作是Leaky ReLU的一个变体。在PReLU中,负值部分的斜率是根据网络学习来定的,而非预先定义。作者称,在ImageNet分类(2015,Russakovsky等)上,PReLU是超越人类分类水平的关键所在。
如 Leaky ReLU与PReLU主要的特点是:(1)计算简单,有效 (2)比Sigmoid与Tanh收敛更快 (3) 解决了Dead ReLU 的问题。
RReLU激活函数
RReLU(Randomized leaky rectified linear unit)也是 Leaky ReLU的一个变体。在RReLU中,是一个在一个给定的范围内随机抽取的值,这个值在测试环节就会固定下来.
RReLU的亮点在于,在训练环节中,是从一个均匀的分布中随机抽取的数值。形式上来说,我们能得到以下结果:
其中
该函数图像如下:
ELU激活函数
ELU(Exponential Linear Unit)同样是针对ReLU的负数部分进行的改进,ELU激活函数对小于零的情况采用类似指数计算的方式进行输出:
或者表达为:
对于ELU有这些特点:
-
ELU由于其正值特性,可以像ReLU,Leaky ReLU,PReLU 一样缓解梯度消失的问题。 -
相比ReLU,ELU存在负值,可以将激活单元的输出均值往0推近,达到接近BN的效果同时减少了计算量。
Swish激活函数
激活函数公式如下:
其函数图像:
其中是常数或可训练的参数。Swish函数具备无上界有下界、平滑、非单调的特性。通过实验证明,对于深层模型, Swish的效果是优于ReLU的。
当时,Swish激活函数称为线性函数
。
当,
为0或者1。Swish变为ReLU:
,以Swish函数可以看作是介于线性函数与ReLU函数之间的平滑函数。
SELU激活函数
SELU是给ELU乘上系数,即
文章中主要证明是当取得时,在网络权重服从标准正态分布的条件下,各层输出的分布会向标准正态分布靠拢,这种”自我标准化”的特性可以避免梯度消失于梯度爆炸,证明过程各位感兴趣的可以去看看90多页的原文。
函数图像如下:
GELU激活函数
受启发于Dropout、ReLU等机制的影响,都意在将不重要的信息设置为0。对于输入的值,我们可以理解成是将输入的值乘以了一个0或者1。即对于每一个输入,其服从标准正态分布
,它也会乘以一个伯努利分布
,其中
.
GELU(Gaussian error linear units)的表达式为.
而上述函数是无法直接计算的,因此可以用另外的方式来进行逼近,论文得到的表达式为:
或:
在Bert,Transformer 中使用该激活函数,作者经过实验证明比ReLU等要好。原点可导,不会有Dead ReLU 问题。
其函数图像如下:
参考:
-
https://zhuanlan.zhihu.com/p/48776056 -
https://blog.csdn.net/u011984148/article/details/101444274 -
https://blog.csdn.net/weixin_39945445/article/details/111010529 -
https://blog.csdn.net/dulingtingzi/article/details/80319997 -
https://blog.csdn.net/qq_29831163/article/details/89887655
👍