本文从激活函数的背景知识开始介绍,重点讲解了不同类型的非线性激活函数:Sigmoid、Tanh、ReLU、LReLU、PReLU、Swish,并详细介绍了这些函数的优缺点。
1. 什么是激活函数?生物神经网络启发了人工神经网络的发展。
但是,ANN 并非大脑运作的近似表示。
不过在我们了解为什么在人工神经网络中使用激活函数之前,先了解生物神经网络与激活函数的相关性是很有用处的。
典型神经元的物理结构包括细胞体(cell body)、向其他神经元发送信号的轴突(axon)和接收其他神经元发送的信号或信息的树突(dendrites)。
生物神经网络上图中,红色圆圈代表两个神经元交流的区域。
神经元通过树突接收来自其他神经元的信号。
树突的权重叫作突触权值(synaptic weight),将和接收的信号相乘。
来自树突的信号在细胞体内不断累积,如果信号强度超过特定阈值,则神经元向轴突传递信息。
如未超过,则信号被该神经元「杀死」,无法进一步传播。
激活函数决定是否传递信号。
在这种情况下,只需要带有一个参数(阈值)的简单阶梯函数。
现在,当我们学习了一些新的东西(或未学习到什么)时,一些神经元的阈值和突触权值会发生改变。
这使得神经元之间产生新的连接,大脑学会新的东西。
让我们再次理解这一概念,不过这次要使用人工神经元。
上图中(x_1, ..., x_n)是信号向量,它和权重(w_1, ..., w_n)相乘。
然后再累加(即求和 + 偏置项 b)。
最后,激活函数 f 应用于累加的总和。
注意:权重(w_1, ..., w_n)和偏置项 b 对输入信号进行线性变换。
而激活函数对该信号进行非线性变换,这使得我们可以任意学习输入和输出之间的复杂变换。
过去已经出现了很多种函数,但是寻找使神经网络更好更快学习的激活函数仍然是活跃的研究方向。
2. 神经网络如何学习?我们有必要对神经网络如何学习有一个基本了解。
假设网络的期望输出是 y(标注值),但网络实际输出的是 y'(预测值)。
预测输出和期望输出之间的差距(y - y')可以转化成一种度量,即损失函数(J)。
神经网络犯大量错误时,损失很高;神经网络犯错较少时,损失较低。
训练目标就是找到使训练集上的损失函数最小化的权重矩阵和偏置向量。
在下图中,损失函数的形状像一个碗。
在训练过程的任一点上,损失函数关于梯度的偏导数是那个位置的梯度。
沿偏导数预测的方向移动,就可以到达谷底,使损失函数最小化。
使用函数的偏导数迭代地寻找局部极小值的方法叫作梯度下降。
人工神经网络中的权重使用反向传播的方法进行更新。
损失函数关于梯度的偏导数也用于更新权重。
从某种意义上来说,神经网络中的误差根据求导的链式法则执行反向传播。
这通过迭代的方式来实施,经过多次迭代后,损失函数达到极小值,其导数变为 0。
我们计划在其他文章中介绍反向传播。
这里主要指出的就是训练过程中出现的求导步骤。
3. 激活函数的类型线性激活函数:这是一种简单的线性函数,公式为:f(x) = x。
基本上,输入到输出过程中不经过修改。
线性激活函数非线性激活函数:用于分离非线性可分的数据,是最常用的激活函数。
非线性方程控制输入到输出的映射。
非线性激活函数有 Sigmoid、Tanh、ReLU、LReLU、PReLU、Swish 等。
下文中将详细介绍这些激活函数。
非线性激活函数4. 为什么人工神经网络需要非线性激活函数?神经网络用于实现复杂的函数,非线性激活函数可以使神经网络随意逼近复杂函数。
没有激活函数带来的非线性,多层神经网络和单层无异。
现在我们来看一个简单的例子,帮助我们了解为什么没有非线性,神经网络甚至无法逼近异或门(XOR gate)、同或门(XNOR gate)等简单函数。
下图是一个异或门函数。
叉和圈代表了数据集的两个类别。
当 x_1、x_2 两个特征一样时,类别标签是红叉;不一样,就是蓝圈。
两个红叉对于输入值 (0,0) 和 (1,1) 都有输出值 0,两个蓝圈对于输入值 (0,1) 和 (1,0) 都有输出值 1。
异或门函数的图示从上图中,我们可以看到数据点非线性可分。
也就是说,我们无法画出一条直线使蓝圈和红叉分开来。
因此,我们需要一个非线性决策边界(non-linear decision boundary)来分离它们。
激活函数对于将神经网络的输出压缩进特定边界内也非常关键。
神经元的输出值可以非常大。
该输出在未经修改的情况下馈送至下一层神经元时,可以被转换成更大的值,这样过程就需要极大算力。
激活函数的一个任务就是将神经元的输出映射到有界的区域(如,0 到 1 之间)。
了解这些背景知识之后,我们就可以了解不同类型的激活函数了。
5. 不同类型的非线性激活函数5.1 SigmoidSigmoid又叫作 Logistic 激活函数,它将实数值压缩进 0 到 1 的区间内,还可以在预测概率的输出层中使用。
该函数将大的负数转换成 0,将大的正数转换成 1。
数学公式为:下图展示了 Sigmoid 函数及其导数:Sigmoid 激活函数Sigmoid 导数Sigmoid 函数的三个主要缺陷:1. 梯度消失:注意:Sigmoid 函数趋近 0 和 1 的时候变化率会变得平坦,也就是说,Sigmoid 的梯度趋近于 0。
神经网络使用 Sigmoid 激活函数进行反向传播时,输出接近 0 或 1 的神经元其梯度趋近于 0。
这些神经元叫作饱和神经元。
因此,这些神经元的权重不会更新。
此外,与此类神经元相连的神经元的权重也更新得很慢。
该问题叫作梯度消失。
因此,想象一下,如果一个大型神经网络包含 Sigmoid 神经元,而其中很多个都处于饱和状态,那么该网络无法执行反向传播。
2. 不以零为中心:Sigmoid 输出不以零为中心的。
3. 计算成本高昂:exp() 函数与其他非线性激活函数相比,计算成本高昂。
下一个要讨论的非线性激活函数解决了 Sigmoid 函数中值域期望不为 0 的问题。
5.2 TanhTanh 激活函数Tanh 导数Tanh 激活函数又叫作双曲正切激活函数(hyperbolic tangent activation function)。
与 Sigmoid 函数类似,Tanh 函数也使用真值,但 Tanh 函数将其压缩至-1 到 1 的区间内。
与 Sigmoid 不同,Tanh 函数的输出以零为中心,因为区间在-1 到 1 之间。
你可以将 Tanh 函数想象成两个 Sigmoid 函数放在一起。
在实践中,Tanh 函数的使用优先性高于 Sigmoid 函数。
负数输入被当作负值,零输入值的映射接近零,正数输入被当作正值。
唯一的缺点是:1. Tanh 函数也会有梯度消失的问题,因此在饱和时也会「杀死」梯度。
为了解决梯度消失问题,我们来讨论另一个非线性激活函数——修正线性单元(rectified linear unit,ReLU),该函数明显优于前面两个函数,是现在使用最广泛的函数。
5.3 修正线性单元(ReLU)ReLU 激活函数ReLU 导数从上图可以看到,ReLU 是从底部开始半修正的一种函数。
数学公式为:当输入 x<0 时,输出为 0,当 x> 0 时,输出为 x。
该激活函数使网络更快速地收敛。
它不会饱和,即它可以对抗梯度消失问题,至少在正区域(x> 0 时)可以这样,因此神经元至少在一半区域中不会把所有零进行反向传播。
由于使用了简单的阈值化(thresholding),ReLU 计算效率很高。
但是 ReLU 神经元也存在一些缺点:1. 不以零为中心:和 Sigmoid 激活函数类似,ReLU 函数的输出不以零为中心。
2. 前向传导(forward pass)过程中,如果 x < 0,则神经元保持非激活状态,且在后向传导(backward pass)中「杀死」梯度。
这样权重无法得到更新,网络无法学习。
当 x = 0 时,该点的梯度未定义,但是这个问题在实现中得到了解决,通过采用左侧或右侧的梯度的方式。
为了解决 ReLU 激活函数中的梯度消失问题,当 x < 0 时,我们使用 Leaky ReLU——该函数试图修复 dead ReLU 问题。
下面我们就来详细了解 Leaky ReLU。
5.4 Leaky ReLULeaky ReLU 激活函数该函数试图缓解 dead ReLU 问题。
数学公式为:Leaky ReLU 的概念是:当 x < 0 时,它得到 0.1 的正梯度。
该函数一定程度上缓解了 dead ReLU 问题,但是使用该函数的结果并不连贯。
尽管它具备 ReLU 激活函数的所有特征,如计算高效、快速收敛、在正区域内不会饱和。
Leaky ReLU 可以得到更多扩展。
不让 x 乘常数项,而是让 x 乘超参数,这看起来比 Leaky ReLU 效果要好。
该扩展就是 Parametric ReLU。
5.5 Parametric ReLUPReLU 函数的数学公式为:其中是超参数。
这里引入了一个随机的超参数,它可以被学习,因为你可以对它进行反向传播。
这使神经元能够选择负区域最好的梯度,有了这种能力,它们可以变成 ReLU 或 Leaky ReLU。
总之,最好使用 ReLU,但是你可以使用 Leaky ReLU 或 Parametric ReLU 实验一下,看看它们是否更适合你的问题。
5.6 SwishSwish 激活函数该函数又叫作自门控激活函数,它近期由谷歌的研究者发布,数学公式为:根据论文(https://arxiv.org/abs/1710.05941v1),Swish 激活函数的性能优于 ReLU 函数。
根据上图,我们可以观察到在 x 轴的负区域曲线的形状与 ReLU 激活函数不同,因此,Swish 激活函数的输出可能下降,即使在输入值增大的情况下。
大多数激活函数是单调的,即输入值增大的情况下,输出值不可能下降。
而 Swish 函数为 0 时具备单侧有界(one-sided boundedness)的特性,它是平滑、非单调的。
更改一行代码再来查看它的性能,似乎也挺有意思。
现在,我相信我们大家都很熟悉什么是A-NN了,但接下来请允许我按照自己的理解给A-NN下个定义——它是一个强健有力的,同时也非常复杂的机器学习技术,它可以模仿人类的大脑,继而模仿大脑的运作。
正如我们的人脑一样,在一个层次上和神经元网络中有数百万个神经元,这些神经元通过一种称之为synapses(突触)的结构彼此紧紧相连。
它可以通过 Axons(轴突),将电信号从一个层传递到另一个层。
这就是我们人类学习事物的方式。
每当我们看到、听到、感觉和思考时,一个突触(电脉冲)从层次结构中的一个神经元被发射到另一个神经元,这使我们能够从我们出生的那一天起,就开始学习、记住和回忆我们日常生活中的东西。
好的,接下来我保证大家看到的不再是生物学领域的知识了。
什么是激活函数,它在神经网络模型中是如何使用的?激活函数(Activation functions)对于人工神经网络模型去学习、理解非常复杂和非线性的函数来说具有十分重要的作用。
它们将非线性特性引入到我们的网络中。
其主要目的是将A-NN模型中一个节点的输入信号转换成一个输出信号。
该输出信号现在被用作堆叠中下一个层的输入。
而在A-NN中的具体 *** 作是这样的,我们做输入(X)和它们对应的权重(W)的乘积之和,并将激活函数f(x)应用于其获取该层的输出并将其作为输入馈送到下一个层。
问题是,为什么我们不能在不激活输入信号的情况下完成此 *** 作呢?如果我们不运用激活函数的话,则输出信号将仅仅是一个简单的线性函数。
线性函数一个一级多项式。
现如今,线性方程是很容易解决的,但是它们的复杂性有限,并且从数据中学习复杂函数映射的能力更小。
一个没有激活函数的神经网络将只不过是一个线性回归模型(Linear regression Model)罢了,它功率有限,并且大多数情况下执行得并不好。
我们希望我们的神经网络不仅仅可以学习和计算线性函数,而且还要比这复杂得多。
同样是因为没有激活函数,我们的神经网络将无法学习和模拟其他复杂类型的数据,例如图像、视频、音频、语音等。
这就是为什么我们要使用人工神经网络技术,诸如深度学习(Deep learning),来理解一些复杂的事情,一些相互之间具有很多隐藏层的非线性问题,而这也可以帮助我们了解复杂的数据。
那么为什么我们需要非线性函数?非线性函数是那些一级以上的函数,而且当绘制非线性函数时它们具有曲率。
现在我们需要一个可以学习和表示几乎任何东西的神经网络模型,以及可以将输入映射到输出的任意复杂函数。
神经网络被认为是通用函数近似器(Universal Function Approximators)。
这意味着他们可以计算和学习任何函数。
几乎我们可以想到的任何过程都可以表示为神经网络中的函数计算。
而这一切都归结于这一点,我们需要应用激活函数f(x),以便使网络更加强大,增加它的能力,使它可以学习复杂的事物,复杂的表单数据,以及表示输入输出之间非线性的复杂的任意函数映射。
因此,使用非线性激活函数,我们便能够从输入输出之间生成非线性映射。
激活函数的另一个重要特征是:它应该是可以区分的。
我们需要这样做,以便在网络中向后推进以计算相对于权重的误差(丢失)梯度时执行反向优化策略,然后相应地使用梯度下降或任何其他优化技术优化权重以减少误差。
只要永远记住要做:“输入时间权重,添加偏差和激活函数”最流行的激活函数类型1.Sigmoid函数或者Logistic函数2.Tanh — Hyperbolic tangent(双曲正切函数)3.ReLu -Rectified linear units(线性修正单元)Sigmoid激活函数:它是一个f(x)= 1/1 + exp(-x)形式的激活函数。
它的值区间在0和1之间,是一个S形曲线。
它很容易理解和应用,但使其不受欢迎的主要原因是:·梯度消失问题·其次,它的输出不是以0为中心。
它的梯度更新在不同的方向上且走得太远。
0 <output <1,使优化更加困难。
·Sigmoids函数饱和且kill掉梯度。
·Sigmoids函数收敛缓慢。
现在我们该如何解决上述问题?双曲正切函数——Tanh:其数学公式是f(x)= 1 - exp(-2x)/ 1 + exp(-2x)。
现在它的输出是以0中心的,因为它的值区间在-1到1之间,即-1 <output <1。
因此,在该方法中优化更容易一些,从而其在实践应用中总是优于Sigmoid函数。
但它依然存在着梯度消失问题。
那么我们该如何处理和纠正梯度消失问题呢?ReLu -Rectified linear units(线性修正单元):其实在过去几年中它就已经非常受欢迎了。
最近证明,相较于Tanh函数,它的收敛性提高了6倍。
只要R(x)= max(0,x),即如果x <0,R(x)= 0,如果x> = 0,则R(x)= x。
因此,只看这个函数的数学形式,我们就可以看到它非常简单、有效。
其实很多时候我们都会注意到,在机器学习和计算机科学领域,最简单、相容的技术和方法才是首选,才是表现最好的。
因此,它可以避免和纠正梯度消失问题。
现如今,几乎所有深度学习模型现在都使用ReLu函数。
但它的局限性在于它只能在神经网络模型的隐藏层中使用。
因此,对于输出层,我们应该使用Softmax函数来处理分类问题从而计算类的概率。
而对于回归问题,它只要简单地使用线性函数就可以了。
ReLu函数的另一个问题是,一些梯度在训练过程中可能很脆弱,甚至可能会死亡。
它可以导致权重更新,这将使其永远不会在任何数据点上激活。
简单地说ReLu可能会导致死亡神经元。
为了解决这个问题,我们引进了另一个被称为Leaky ReLu的修改函数,让它来解决死亡神经元的问题。
它引入了一个小斜坡从而保持更新值具有活力。
然后,我们还有另一个变体,它形成于ReLu函数和Leaky ReLu函数的结合,我们称之为Maxout函数。
结论问题是哪一个更好用呢?这个问题的答案就是,现在我们应该使用只应用于隐藏层的ReLu函数。
当然,如果我们的模型在训练过程中遇到死亡神经元,我们就应该使用leaky ReLu函数或Maxout函数。
而考虑到现实的情况,Sigmoid函数和Tanh函数是不适用的,因为梯度消失问题(vanishing Gradient Problem)是一个很严重的问题,会在训练一个神经网络模型中导致更多问题。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)