神经网络激活函数的作用和原理?有没有形象解释?前面一些分享文章提到了激活函数,这篇文章将介绍各种激活函数,以及我和同事在业务中对激活函数的一些思考与应用。
在介绍各种激活函数之前,先了解人工神经网络的提出背景和工作原理,从而更好地理解激活函数的作用,以及各个激活函数的特点分析。(想直接看激活函数的朋友可以跳过这部分直接到第3部分对常用激活函数的介绍。)
受生物神经系统处理信息的启发,人工神经网络(Artificial neural network,简写ANN)的概念被提出。
生物神经处理系统由数量庞大的神经元组成,这些神经元之间有复杂的连接关系,形成强大的生物神经网络(Biological Neural Networks,简写BNN)。
生物神经网络中的每个神经元,只处理简单的任务。单个神经元由细胞体(Cell body)、轴突(axion)和树突(dendrite)构成,如图1所示。轴突负责向其它神经元发送信号,树突负责从其它神经元接收信号。图1中红色圈表示两个神经元的连接区域。当神经元通过树突接收到从另一个神经元的轴突传来的信号时,信号在细胞体内累计,当接收的信号超过一定强度时,神经元则通过轴突继续传递信号,若信号太弱,则无法通过该神经元继续传递。
ANN的结构如图2所示,可以包含一层或多层隐层。ANN的网络结构类似BNN,神经元之间相互连接,每个神经元进行简单的计算逻辑。和BNN神经元对信号的处理原理对应,ANN中每个神经元对输入进行加权、求和、激活计算后得到输出。激活计算对应于BNN中神经元对信号的继续传递或者阻断继续传递的处理。激活函数的产生由此而来,用于ANN中神经元的激活逻辑。
人工神经网络的学习分为两个过程:前向传播(forward propagation,简写为FP)和反向传播(back propagation,简写为BP)。两个过程交替进行,每次FP后进行BP,然后进行下一次FP和BP。
FP的过程很简单,即输入经过若干隐层处理后得到输出,隐层中每个神经元的计算包括加权求和和激活。式子(1.1)和式子(1.2)分别表示了隐层神经元的加权求和和激活的计算过程。加权求和的输入为与当前神经元相连的上一层神经元的输出,即式子(1.1)中的\mathbf y^{(i)},加权求和的结果也就是\mathbf z^{(i+1)}再经过激活函数,得到当前层神经元的输出\mathbf y^{(i+1)}。
FP过程中的计算,依赖很多参数,这些参数更新和计算,依赖于BP过程。BP采用梯度下降法对参数进行更新,也就是对FP过程计算出的损失(预测值和真实值的差异),对所有参数求导得到梯度,每个参数用自身的梯度进行更新。参数的梯度计算采用链式法则进行,如式子(2.1)所示,可见损失对w的求导依赖于损失对y的求导,损失对y的求导如式子(2.2)所示。每次BP后参数更新一次,那么下一次FP将采用更新后的参数进行计算。
在梯度计算过程中,若网络参数初始化不当或者网络超参设置不合理等,容易出现梯度消失和梯度爆炸问题。梯度消失是指训练过程中梯度趋近于0,造成参数无法更新,损失函数不再继续收敛,从而导致网络得不到充分训练。梯度爆炸是指训练过程中,梯度过大甚至是NAN(not a number),造成损失大幅震荡或者无法收敛开云网址,导致网络无法收敛。
对于没有系统学过神经网络基础知识而是在业务中直接运用神经网络的人来说,激活函数好像很天然地跟神经网络绑定在一起,有神经网络的地方就自然会有激活函数。另一方面,激活函数的生物学背景,也使得它似乎天然就应该设计在神经网络的计算逻辑中。激活函数确实是神经网络的一部分,那为什么神经网络需要激活函数,是否可以不需要它,没有激活函数的神经网络还能不能称为神经网络,理解了这些问题,就理解了激活函数的作用和神经网络的大致工作原理。
常用的激活函数包括sigmoid、tanh、ReLU、Leaky ReLU、ELU、SELU、PReLU、Dice、maxout、softmax等,其中Leaky ReLU、ELU、SELU、PReLU、Dice的原理都是ReLU为基础进行一些改进,softmax是sigmoid的拓展,主要用于多分类网络的最后一层。激活函数的原理决定了其特点和适用场景,通过了解原理,可以在具体业务场景中更好地运用这些激活函数。
sigmoid激活函数被广泛使用,和生物神经元的激活逻辑最接近,其定义如式子(4)所示,函数图像如图3所示。
sigmoid函数的特点明显:(1) 连续光滑、严格单调;(2) 输出范围为(0,1),以(0, 0.5)为对称中心;(3) 当输入趋于负无穷时,输出趋近于0,当输入趋于正无穷时,输出趋近于1;(4) 输入在0附近时,输出变化趋势明显,输入离0越远,变化趋势越平缓且逐渐趋于不变。
根据sigmoid激活函数的特点,可以得到对应的优缺点。其优点包括:(1) 输出范围为(0,1),适合作为概率的使用;(2) 求导方便,如式子(5)所示,不需要额外的计算量。
其缺点包括:(1) 当输入离0较远时,输出变化非常平缓,容易陷入梯度饱和状态,导致梯度消失问题;(2) 以(0, 0.5)为对称中心,原点不对称,容易改变输出的数据分布;(3) 导数取值范围为(0, 0.25](推导过程见式子(5)),连乘后梯度呈指数级减小,所以当网络加深时,浅层网络梯度容易出现梯度消失,详细原因见推导1;(4) 输出总是正数,使反向传播时参数w的梯度全正或全负,梯度下降出现zigzag形状,导致网络收速度慢,详细原因见分析1;(5) 计算包括指数项,耗时多。
当所有梯度同为正或者负时,参数在梯度更新时容易出现zigzag现象。zigzag现象如图4所示,不妨假设一共两个参数,w_0和w_1,紫色点为参数的最优解,蓝色箭头表示梯度最优方向开云网址,红色箭头表示实际梯度更新方向。由于参数的梯度方向一致,要么同正,要么同负,因此更新方向只能为第三象限角度或第一象限角度,而梯度的最优方向为第四象限角度,也就是参数w_0要向着变小的方向,w_1要向着变大的方向,在这种情况下,每更新一次梯度,不管是同时变小(第三象限角度)还是同时变大(第四象限角度),总是一个参数更接近最优状态,另一个参数远离最优状态,因此为了使参数尽快收敛到最优状态,出现交替向最优状态更新的现象,也就是zigzag现象。
sigmoid函数在什么情况下会出现zigzag现象呢(有兴趣的朋友可以先思考一下再看后面的内容)。从上面的分析可以看出,当梯度更新的最优方向不满足所有参数梯度正负向一致时,也就是有的参数梯度正向,有的参数梯度负向,容易出现zigzag现象。
两个参数时,出现zigzag现象的梯度更新最优方向为图4中的绿色背景部分,即第二象限和第四象限。在深度学习中,网络参数非常巨大,形成高维的空间,梯度更新的最优方向非常容易出现不同参数的梯度正负向不一致的情况,也就更容易造成zigzag现象。
抛开激活函数,当参数量纲差异大时,也容易造成zigzag现象,其中的原因和sigmoid函数造成的zigzag现象,是相通的。
tanh函数特点:(1) 连续光滑、严格单调;(2) 输出范围为(-1,1),以(0, 0)为对称中心,均值为0;(3) 输入在0附近时,输出变化明显;输入离0越远,输出变化越小最后输出趋近于1不变。
优点:输出关于原点对称,0均值,因此输出有正有负,可以规避zigzag现象,另外原点对称本身是一个很好的优点,有益于网络的学习。
缺点:存在梯度消失问题,tanh的导数计算为f^{} = \frac{4e^{2x}}{(e^{2x}+1)^2},取值范围为(0,1],虽然取值范围比sigmoid导数更广一些,可以缓解梯度消失,但仍然无法避免随着网络层数增多梯度连乘导致的梯度消失问题。
ReLU系列的激活函数包括ReLU、Leaky ReLU、PReLU、ELU,在PReLU的基础上,又发展出Dice激活函数。这个系列的激活函数采用分段的思路,其中一段为线性,从而解决部分梯度消失的问题。
ReLU函数的分段性使其具有如下优点:(1) 输入0时保持梯度为恒定值不衰减,从而缓解梯度消失问题;(2) 输入0时导数为0,当神经元激活值为负值时,梯度不再更新,增加了网络的稀疏性,从而使模型更具鲁棒性,这点类似dropout但不完全等同dropout;(3) 计算速度快,ReLU函数的导数是if-else的实现逻辑,计算非常方便快速。
ReLU函数的缺点也很明显:(1) 输入0时梯度为1,可能导致爆炸问题;(2) 输入0时导数为0,一旦神经元激活值为负开云网址,则神经元进入永久性dead状态,梯度不再更新,导致梯度消失问题,学习率过大容易导致所有神经元都进入dead状态,所以需设置较小的学习率;(3) ReLU的输出均值大于0,容易改变输出的分布,可以通过batch normalization缓解这个问题。
相比sigmoid和tanh,ReLU可明显改善梯度消失的问题,且计算高效,因此在业界被广泛使用。
ReLU的非线性来源于不同隐层对不同神经元的激活,如图7所示,当神经元的输出为正时,神经元才被激活,即图7中蓝色神经元所示。虽然每个被激活的神经元的输入输出是线性关系,但通过每层选择部分神经元激活实现了输入输出的非线 ReLU激活函数对神经元的选择
ReLU对神经元的选择,类似dropout,但两者原理不同。深度学习场景数据量复杂高维,ReLU根据神经元的输出进行选择,多层神经元的选择相当于在原始输入数据层增加稀疏度,这也是ReLU增加模型鲁棒性的原因,增加数据稀疏度可以起到去除噪音的效果。Dropout是动态去除一些神经元到下一层的连接,相当于是动态L2正则化,通过打压隐层连接参数W实现稀疏性。
ReLU激活函数使得输出为负值的神经元永久性dead,这个问题可以通过对ReLU函数负半轴的输出进行调整,使其不为0,从而得到解决。Leaky Relu、elu、selu等函数则是采用这种思路解决神经元永久性dead问题。
需要手工调整的缺点。理论上Leaky ReLU激活函数效果好,但其优势在实际场景中并未得到证明,因此在具体业务中使用不多。3.3.2.2 ELU和SELU
类似Leaky ReLU思路解决神经元dead问题的还有ELU和SELU,式子(9)为ELU函数,图9为其函数图像,式子(10)为SELU函数。从定义可以看出,SELU在ELU的基础上引入了一个缩放系数,其形状和ELU相似。
ELU结合了ReLU和sigmoid,具备两者的优点:(1) 在输入正半轴为线性,无饱和性,使其可以缓解梯度消失问题;(2) 在输入负半轴具有软饱和性,其下边界为-\alpha,软饱和性一方面可以解决ReLU中神经元永久性dead问题,另一方面可以使ELU对输入噪声具有更强的鲁棒性;(3) 输出的均值接近0,可以缓解均值不为0带来的输出分布变化问题,加快模型收敛。
ELU在输入负半轴采用指数的形式,这导致ELU相比ReLU存在计算复杂度较高的缺点。SELU和ELU具有同样的特点。理论上ELU优于ReLU,但在推荐实际应用场景没有得到充分证明,可能和推荐领域网络深度不深有关系,在视觉领域网络层数深,相比ReLU、Leaky ReLU,ELU可以在网络收敛性上有优势。
当成神经元的一个参数的思路,通过网络学习得到,从而使其不依赖于人工。PReLU的定义和函数图像跟Leaky ReLU相同,如式子(8)和图8所示,其特点也和Leaky ReLU相同。不同的是,PReLU通过网络自身学习参数\alpha,使其和当前场景的数据更适配。
处,论文根据对不同数据分布的输入其激活函数的阶跃点应进行对应调整的思路,提出Dice。Dice的定义如式子(11)所示,其中p(s)为阶跃点的指示函数,如图10所示,E[s]和Var[s]为每个输入batch的均值和方差。图10对比了PReLU和Dice的阶跃点指示函数,可以看出,Dice激活函数的阶跃点随着输入数据的分布动态变化。
softplus激活函数的定义如式子(13)所示,图像如图12所示,从函数定义和图像可以看出,softplus是ReLU的平滑版本。
softmax激活函数是sigmoid激活函数的扩展,如式子(14)所示,通常用于多分类网络最后的输出层。softmax通过指数归一化方式,可以强化各项之间的区分度。