激活函数在逻辑回归、感知机、神经网络系列模型中有着重要的作用,是神经网络最重要的组成成分之一。如果把神经网络模型比作一台机器,那么激活函数就起着类似信号处理器的作用,把输入的数据进行处理然后准备输出。
在一般的神经网络中,激活函数负责把上一层输出的数据(一般是向量或矩阵)计算后的结果进行处理,得到新的一组数(即新的输出),对应就是下面蓝色与红色之间的直箭头部分。
例如,对与上面的三层神经元(一般会把蓝色和红色合并成一个节点,这里兔兔为了展示方便,画成两个圆)。我们以中间层为例。中间的左半部分三个蓝色是上一层计算得到的结果,每一个圆代表一个数,所以这一层左半部分的三个数可以用向量表示,即
。红蓝之间的激活函数为
,那么经过激活函数处理后得到的右边红色部分就是
, 对应右边三个圆。
一般在深度神经网络中把红色和蓝色是合并成一个节点,激活函数在层内进行。
激活函数的作用,一方面是因为如果没有激活函数的限制,数据逐层传递,最终数越来越大,类似爆炸一样,所以需要激活函数每次把结果限制在一定范围内;另一方面,激活函数起到类似神经元的作用,负责信号(或数据)的控制,来决定该神经元是否激活,从而使得模型学习效果更好。所以对于一个神经网络,选取合适的激活函数是十分重要的。
常见激活函数种类
(1)sigmoid激活函数
sigmoid函数形式为:
其导数为:
函数图像如下:
sigmoid函数在神经网络中十分常用,它的定义域是R,输出在0~1之间,所以可以将预测概率作为输出模型;而且函数梯度平滑,避免跳跃的输出值;函数可微,能够求导;输出限定在0~1,因此它对每个神经元输出做了归一化。但是sigmoid函数缺点也比较明显,例如:随着神经网络层的增加,sigmoid 函数往往会导致梯度消失,此时模型效果就会不好;函数输出不是以0为中心,会在训练中降低权重更新的效率;该函数执行指数运算,计算机运行速度慢。
(2)Tanh(双曲正切)激活函数
这个函数在高等数学中比较常见,形式是
。在这里,我们把式子稍微处理一下,分子分母同时乘
,再分离一下,就得到该激活函数的形式:
其导数为:
其函数图像如下:
Tanh函数与sigmoid函数很像,定义域也是R,但是它是以0为中心的,输出间隔为1,所以比sigmoid函数更具优势。但是当输入比较大或较小时,梯度很小,不利于权重的更新。在Tanh函数中,负数被强映射为负数,而0输入映射为0。在一般二元分类问题中,Tanh函数通常用于隐藏层中,sigmoid用于输出层中,有时也需要具体问题具体分析。
(3)ReLU激活函数
该函数是一个分段函数,当x大于等于0时函数为
,小于0时函数为
。所以该激活函数形式为:
该函数的导数为:
其函数图像如下:
该函数在深度学习中应用比较广泛,目前较为流行,其优点为:输入为正数时,没有梯度饱和的情况,而且与前两个函数相比,该函数计算速度很快。但其缺点也比较明显:它是输出为0或正数,不是以0为中心的函数,就会出现和sigmoid 函数同样的问题;而且当输入为负数时,梯度变成了0,这个问题也称为Dead ReLU问题,在神经网络正向传播中该问题没有任何影响,但是在反向传播修正参数时,如果输入是负数,那么梯度为0,也就无法修正参数了。
(4)Leaky ReLU激活函数
针对上面的Dead ReLU问题,应用Leaky ReLU便可以解决。Leaky ReLU函数是一种专门设计用于解决 Dead ReLU问题的一种激活函数。
该函数的形式为:
该函数的导数为:
其中a通常大于0小于1,函数图像如下:
这里兔兔是让a=0.2得到的图像,实际应用a通常为0.01作用。
由于该函数在小于0的情况下也有梯度,为a,所以解决了Dead ReLU问题。虽然从理论上来说,Leak ReLU函数具有ReLU所有优点,也不会出现Dead ReLU问题,但是实际应用中,我们并没有完全发现Leaky ReLU比ReLU效果更好。
(5)ELU激活函数
ELU激活函数也 解决了ReLU问题,该函数形式为:
该函数的导数为:
函数图像为:
该函数具有很多的优点:ELU函数有负值,会使激活的平均值接近0,其梯度更接近自然梯度,从而可以使学习更快;而且该函数以0 为中心,输出平均值接近0;ELU在较小的输入下会饱和至负值,从而减少前向传播的变异信息。
(6)PReLU(Parametric ReLU)激活函数
该函数也是对ReLU的一种改进,函数形式为:
函数导数为:
该函数图像与Leaky ReLU图像相同。
虽然PReLU在形式上与Leaky ReLU很像,当alpha在0~1之间就是Leaky ReLU函数,α=0时就变成了ReLU,但是该函数与前两者有本质区别:这里的alpha是未知的,是在模型训练中(如梯度下降)的过程中训练学习得到的参数,也就是说在模型训练过程中还要求函数对α的偏导。所以在PReLU中,α是可学习参数。
(7)softmax激活函数
softmax激活函数常用于多分类问题,例如用逻辑回归进行多分类,或是深度神经网络用于多分类问题等。该函数与前面的不同,它是一个多元函数,自变量为n个,输出也有n个,该函数的形式为:
这里x为列向量
,xi表示第i个自变量。
,
。所以softmax也可以表示如下:
该函数的导数为:
或者表示为:
其中
表示哈达玛积,为矩阵或向量对应位置元素相乘,符号也可以用
表示。导数推导过程可以用上面右侧向量中每一个
对xi求偏导,求导结果放在对应的向量第i行,最终整理简化就是上面的结果。
兔兔以2个自变量为例,图像如下图所示:
自变量x1,x2对应x轴、y轴,z1,z2对应两个曲面,softmax函数得到的所有值的和为1。
softmax函数分母结合了原始输出值的所有因子,所有softmax函数获得的各种概率值是彼此相关的。softmax的缺点为:负输入的梯度为0,这样就会出现在反向传播中权重不会更新,也就是产生永不激活的死亡神经元,类似于ReLU的Dead ReLU问题。
(8)Swish激活函数
该函数的形式为:
该函数的导数为:
函数图像为:
Swish函数设计受LSTM和高速网络中gating的sigmoid函数的启发,该函数优点为:无界性,有助于防止慢速训练期间梯度接近0并导致饱和;函数的平滑度在优化和泛化中起到重要作用。
(9)softplus激活函数
该函数的形式为:
函数导数为:
函数图像为:
该函数类似于ReLU,但是比较平滑,与ReLU一样有单侧抑制。
(10)Step Function激活函数
这个就是高数中常见的阶跃函数,该函数形式为:
导数始终是0。
图像如下所示:
由于该函数导数是0,所以在反向传递中很不利于参数更新。
(11)softsign激活函数
该函数的形式为:
函数导数为:
函数图像如下:
(12)Log of sigmoid 激活函数
该函数的形式为:
即sigmoid 函数的对数。导数为:
函数图像如下:
(13)sinc激活函数
该激活函数形式为:
导数为:
函数图像:
(14)Mish激活函数
该激活函数的形式为:
函数导数为:
函数图像为:
(15)Maxout激活函数
关于Maxout函数,其实是比较特殊的。前面的所有激活函数都是在神经元层内进行,并且激活函数处理前后数的个数的不变的,就像文章前面图画的那样,红色与蓝色个数是相同的。而Maxout函数是改变了处理前后的数的个数,其原因是在神经元层内又加了一层神经元,如果原来的神经元是隐层,那么Maxout函数就是在这个隐层中加入隐隐藏层。所以更准确来说,Maxout更像是神经元的一种连接方式,如全连接、卷积、池化等,但是又有着激活函数的特点,有点儿介于神经元连接方式与激活函数之间,所以兔兔之后会把Maxout激活函数作为一种连接方式单独讲解。
其它激活函数
激活函数的种类是非常多的,上面的15种是比较常用的,其它的激活函数还有SELU、Tanhshrink、Hardshrink、Softshrink、E-Swish、Hardtanh、GELU、CELU、ReLU6、Aria-2、RReLU、SQNL、Bent's Identity、Hard ELish、Soft Clipping、LeCun's Tanh、SineReLU、Flatten T-Swish、ISRU、Weighted Tanh、ELish、ISRLU、SReLU、Hard Sigmoid、Threshold ReLU......感兴趣的同学可以进一步拓展,搜索更多的激活函数种类与形式,并能够根据激活函数推导出导数。
应用方法
如果要真正了解这些激活函数的使用,是需要搭建具体的神经网络模型的,这样才能够体会不同激活函数的使用的。在这里兔兔仅仅大概介绍一下使用方法。
前面讲到了,Maxout激活函数比较特殊,需要单独讲解。其它的14种中只有softmax激活函数比较特殊: 除了softmax函数,其它函数都是一元函数,即输入是1个,输出是1个,而对于某一层的n个神经元
,激活函数为f(x),那么激活函数的计算过程为:
一般的激活函数都是按照上面的过程来进行计算,而且x1,x2...xn之间没有什么关联。对于softmax函数则不同,它的计算综合了x1到xn各个值,计算过程为:
以上两种情况虽然有些区别,但都是在每一层内操作。在画神经网络图时我们通常会把左半部分向量和右半部分向量拼接合并,即表示为:
一个圆代表一个神经元节点,也就是一个数,一个层由n个神经元组成,也就是一个n维向量。
总结
激活函数作为神经网络的关键组成部分,其重要作用不言而喻。选好激活函数对模型效果的好坏也有很大的影响,而这些都需要在具体应用中慢慢体会。