已经成为深度学习人工智能领域的必备工具。起源于人工神经网络的研究,具有多个隐藏层的多层感知器是一种深度学习结构。寻找隐藏层的权重参数和偏差的过程通常被称为“学习”过程,其遵循的基本原则是最小化网络的最终输出误差。在神经网络中,激活函数是为了使神经网络获得最佳结果和性能而必须选择的众多参数之一。常用的激活函数有哪些?如何选择?关于激活函数激活函数(ActivationFunction)是运行在人工神经网络的神经元上的函数,负责将神经元的输入映射到输出,激活函数将神经元中的输入信号之和进行转换网络转换成输出信号。大部分的激活函数都是非线性函数,这样就可以将多层感知器的输出转化为非线性,从而使神经网络可以任意逼近任何非线性函数,进而可以应用到很多非线性模型中。换句话说,非线性激活函数可以创建输入和输出键的复杂映射,神经网络也可以“学习”更新参数。而且,由于非线性函数的导数与输入有关,可以通过反向传播算法计算梯度,也可以构建多层神经网络来处理复杂问题。常见的激活函数有浅层网络的sigmoid系列、深层网络的ReLU系列、循环网络的tanh系列和Softmax系列。sigmoid级数sigmoid函数也称为Logistic函数,用于隐含层神经元的输出。它可以将(?∞,+∞)的值映射到(0,1)的区间。当以概率形式表示预测值时,一般使用函数。sigmod激活函数的Python代码如下:importnumpyasnpdefsigmoid(x):s=1/(1+np.exp(-x))返回s函数的图像如下:Sigmoid函数在于它可以被引导,取值范围在0到1之间,使得神经元的输出标准化,是神经网络中最早使用的激活函数。它的缺点也很明显。当它增加或减少到一定程度时,函数值变化很小。这就是所谓的“梯度消失”,会减慢网络的收敛速度,消耗计算资源。此外,输出值不是以0为中心,而是以0.5为中心。一般的sigmoid函数适用于浅层网络。HardSigmoid在Sigmoid的基础上又有了HardSigmoid,因为当输入值趋于无穷时,输出值趋于1;当输入值趋于无穷小时,输出值趋于0。所以,顾名思义,HardSigmoid是在Sigmoid的基础上,当输入值超过一定范围时,强制置1和0。python代码HardSigmoid如下:defHard_sigmoid(x):y=[]foriinx:ifi<-2.5:y_i=0elifi>=-2.5andi<=2.5:y_i=0.2*i+0.5else:y_i=1y.append(y_i)returnyHardSigmoid激活函数的函数图像如下:Swishswish的表达式为:f(x)=x?sigmoid(bx),python代码如下:defSwish(x):returnx/(1+np.exp(-b*x))其中b为可学习参数,Swish具有无上下界、平滑、非单调性的特点。Swish在深度模型上优于ReLU。例如,简单地用Swish单元替换ReLU可以将MobileNASNetA在ImageNet上的分类精度提高0.9%。maxoutMaxout可以看作是在深度学习网络中增加了一层激活函数层,其中包含一个参数k。与ReLU、sigmoid等相比,这一层的特殊之处在于增加了k个神经元,然后输出激活值最大的值。maxout是一个函数逼近器。对于一个标准的MLP网络,如果隐藏层的神经元足够多,理论上可以逼近任何函数。Maxout的拟合能力很强,可以拟合任何凸函数,具有ReLU的所有优点,线性,不饱和,没有ReLU的一些缺点,比如神经元死亡。Relu级数Relu(RectifiedLinearUnit)称为“线性整流函数”或“修正后的线性单元”。通常直接调用ReLU函数,是一种解决梯度消失问题的方法。在神经网络中引入ReLU函数的同时,也引入了大量的稀疏性。然而,由于稀疏性,时间和空间复杂度较低,并且不涉及成本更高的指数运算,从而使网络能够快速收敛。虽然Relu看起来像一个线性函数,但它具有导数函数并且允许反向传播。python代码如下:importnumpyasnpdefrelu(x):s=np.where(x<0,0,x)returnsReLU引入了神经元死亡的问题,当输入接近于零或负数时,函数的梯度变为零,网络将无法进行反向传播,也无法学习,即网络的大部分组件将永远不会更新。此外,它也无法避免爆炸梯度问题。ReLU是DNN模型中比较常用的激活函数。ELUExponentialLinearUnit激活函数ELU解决了ReLU的一些问题,同时保留了一些好的方面。这个激活函数有一个alpha值;常用值在0.1到0.3之间。但是α=0.3时的函数图像如下:ELU可以避免神经元死亡的问题,并且可以得到负输出,可以帮助网络将权重和偏差的变化推向正确的方向,计算的时候可以激活梯度而不是让它们等于0。ELU的python代码如下:importnumpyasnpdefelu(x):s=np.where(x>=0,x,α(np.exp(x)-1)returns但是由于包含了指数运算,计算时间较长,无法避免梯度爆炸问题,另外神经网络并没有学习到α值,LeakyReLUleakyrectifiedlinear单位激活函数也有一个α值,通常在0.1到0.3之间。LeakyReLU激活函数很常用,它和ELU相比也有一些缺陷,但是比ReLU有一些优势。LeakyReLU有一个小的负斜率,不是a平坡,训练前需要确定斜率系数,即不是在训练中学到的。这种类型的激活函数在可能遇到稀疏梯度的任务中很流行,比如训练生成对抗网络。importnumpyasnpdeflrelu(x):s=np.where(x>=0,x,αx)returns与ELU类似,LeakyReLU也可以避免deadReLU问题,因为它在计算导数时允许更小的梯度,并且因为不包含指数运算,所以计算速度比ELU快。扩展指数线性单元激活函数(SELU)SELU激活可以使神经网络自归一化。首先从均值中减去归一化,然后除以标准差。因此,归一化后,网络的组成部分(权重、偏差和激活)的均值为0,标准差为1,这就是SELU激活函数的输出。通过归一化,网络参数被初始化为正态分布。通过归一化,网络参数被初始化为正态分布。defSeLU(x,alpha=1.6732632423543772848170429916717,scale=1.0507009873554804934193349852946):y=[]foriinx:ifi>=0:y_i=scale*ielse:y_i.pha(nscale)-1)_y.append(y)returnySELU的内部归一化速度比外部归一化更快,这意味着网络可以更快收敛,避免梯度消失或爆炸的问题。在CNN或RNN网络架构中,都有应用。高斯误差线性单元激活函数GELUGELU是某些函数(如双曲正切函数tanh)和近似值的组合。当x大于0时,输出为x;除了从x=0到x=1的区间,当曲线更偏向y轴时。将numpy导入为npdeftanh(x):s1=np.exp(x)-np.exp(-x)s2=np.exp(x)+np.exp(-x)s=s1/s2返回sgelu=lambdax:0.5*x*(1+tanh(np.sqrt(2/np.pi)*(x+0.044715*np.power(x,3))))GELU在NLP领域有不错的表现,尤其是在Transformer在模型中的最佳性能可以避免梯度消失的问题。tanh级数tanhTanh函数,即双曲正切函数,比sigmoid函数更受欢迎,可以为多层神经网络提供更好的性能。它的输出更加以零为中心,这有助于加快收敛速度??,尤其是在训练的早期阶段。双曲正切函数的python代码如下:importnumpyasnpdeftanh(x):s1=np.exp(x)-np.exp(-x)s2=np.exp(x)+np.exp(-x)s=s1/s2returnsTanh函数最大的优点是输出值以0为中心,即关于坐标原点对称,属于正数和负数两类数字。函数及其导数是单调的,收敛速度比sigmoid快,这样可以减少迭代次数。这使得它既有Sigmoid函数的优点又克服了一些缺点。但是,“梯度消失”的问题依然存在,导致收敛速度变慢。Tanh通常用于递归神经网络。HardTanhHardtanh激活函数是Tanh的线性分段逼近。它相对更容易计算,这使得学习计算速度更快,尽管第一个导出的值为零可能会导致神经元沉默/学习速度太慢。TanhShrink是在Tanh的基础上计算输入输出的差值,即TanhShrink,函数图像如下。当输入接近0时,梯度接近0,但当输入极大或极小时,梯度反而是正常的。softmax系列Softmax函数更适合作为多分类模型的激活函数,一般匹配交叉熵损失函数。通常,Softmax函数只作用于输出层,将一堆实数值映射到0-1区间,并使它们的和为1,可以理解为对应每个类别对应的预测概率.python代码如下:defsoftmax(x):x_exp=np.exp(x)x_sum=np.sum(x_exp,axis=1,keepdims=True)s=x_exp/x_sumreturns如果某个zj大于thanotherz,那么这个map的分量接近1,其他的接近0。Softmax函数用来将输入归一化为(0,1),其和为1,一般应用于分类模型的预测概率值(互斥)。其实凡是涉及到概率的地方,基本都是用softmax。通常,例如在注意力层中,softmax用于计算注意力值。LogSoftMaxLogSoftmax基于Softmax函数,计算其对应的对数值。范围为(-∞,0)计算交叉熵损失函数(根据groundtruthlabel,取对应的值即可)。LogSoftMax加速计算并提高数据稳定性。SoftminSoftmin是在Softmax的基础上,做了相反的变换。Softmin是在Softmax的基础上,做相反的变换。和softmax类似,输入n维t数据,重新缩放,使得n维输出的每个元素都在[0,1]区间,和为1。不同的是softmax是单调递增的,softmin是单调递减,也就是说softmax操作在激活操作后会让最大值保持最大,softmin会让最小的数在softmin后变成最大。激活函数的选择从头开始,激活函数的选择也服务于最终的任务目标。不存在普遍适用于各种神经网络的通用激活函数。选择激活函数时,必须考虑不同的条件。比如,如果函数可以微分,求导有多难?功能有多流畅?输出是否保持标准化?网络收敛速度有多快?等等。一般来说,sigmoid函数及其组合通常在分类器中使用时效果更好。为了避免梯度消失的问题,需要避免使用Sigmoid和TanH。在回归模型的情况下,可以在输出层上使用线性激活函数。如果是浅层神经网络,比如不超过4层,可以选择使用多种激活函数,影响不大。如果网络中有大量不活跃的神经元,可以考虑leakyReLU函数。ReLU函数是一种广泛使用的激活函数,可以作为默认选项。深度学习往往需要大量的时间来处理大量的数据,模型的收敛速度尤为重要,因此尽量选择具有零中心特性的激活函数来加快模型的收敛速度。经验建议是:SELU>ELU>LeakyReLU>ReLU>tanh>sigmoid,但是,如果网络的架构阻止自归一化,那么ELU可能是比SELU更好的选择。如果速度很重要,LeakyReLU将是比慢得多的ELU更好的选择。更重要的是,激活函数还在发展中,需要跟踪行业最新进展,勇于探索和创新。一句话总结激活函数是神经网络中的一个重要参数。一般二分类任务的输出层使用Sigmoid系列,多分类任务的输出层使用softmax系列,模型隐藏层使用tanh系列,Relu系列用于回归任务。和卷积神经网络隐藏层。但没有绝对,新的研究激活函数还在不断涌现。附上reddit上有一张激活函数的图片,很有意思!
