首页 > 其他分享 >干货 | 深入理解深度学习中的激活函数

干货 | 深入理解深度学习中的激活函数

时间:2023-07-13 11:33:00浏览次数:77  
标签:函数 非线性 relu 干货 ReLU 激活 神经元


理解深度学习中的激活函数

在这个文章中,我们将会了解几种不同的激活函数,同时也会了解到哪个激活函数优于其他的激活函数,以及各个激活函数的优缺点。

1. 什么是激活函数?

生物神经网络是人工神经网络的起源。然而,人工神经网络(ANNs)的工作机制与大脑的工作机制并不是十分的相似。不过在我们了解为什么把激活函数应用在人工神经网络中之前,了解一下激活函数与生物神经网络的关联依然是十分有用的。

一个典型神经元的物理结构由细胞体、向其他神经元发送信息的轴突以及从其他神经元接受信号或信息的树突组成。

干货 | 深入理解深度学习中的激活函数_激活函数

图一 生物神经网络

图一中,红色的圆圈表示两个神经元连接的区域。神经元通过树突从其他神经元中接受信号。树突的信号强度称为突触权值,用于与传入信号相乘。树突传出的信号在细胞体中累积,如果最后的信号强度超过了某个阈值,神经元就会允许轴突中的信息继续传递。否则,信号就会被阻止而得不到进一步的传播。

激活函数决定了信号是否能够被通过。这个例子仅仅是个只有阈值这一个参数的简单的阶跃函数。现在,当我们学习了一些新东西(或者忘掉一些东西)时,阈值以及一些神经元的突触权重会发生改变。这在神经元中创造了新的连接从而使得大脑能学习到新的东西。

让我们在人工神经元的基础上来再次理解相同的概念。

干货 | 深入理解深度学习中的激活函数_深度学习_02

图二 所示的例子是一个输入为干货 | 深入理解深度学习中的激活函数_激活函数_03的神经元,输入对应

的权重分布为干货 | 深入理解深度学习中的激活函数_SLAM_04,偏置为(b),激活函数干货 | 深入理解深度学习中的激活函数_SLAM_05作用于输入

的权重之和上面。

图二中的干货 | 深入理解深度学习中的激活函数_深度学习_06是与权重干货 | 深入理解深度学习中的激活函数_计算机视觉_07相乘的信号向量,接着是累加(例如:总和+偏置b)。最后,激活函数f作用于这个累加的总和。请注意,权重干货 | 深入理解深度学习中的激活函数_计算机视觉_07和偏置b把输入信号转换为线性的。而另一方面,激活函数把信号转换为非线性的,而这种非线性使得我们能够学习到输入与输出之间任意复杂的变换关系。

这些年来,人们使用了各种各样的激活函数,但是寻找一个合适的激活函数使神经网络学习得更好更快依然是一个非常活跃的研究领域。

2. 网络是怎么学习的?

理解神经网络学习的基本概念是关键。假设网络原本应该得到的输出为y。网络产生的输出为干货 | 深入理解深度学习中的激活函数_激活函数_09。应该得到的输出与实际得到的输出之间的差值干货 | 深入理解深度学习中的激活函数_深度学习_10被转换为损失函数干货 | 深入理解深度学习中的激活函数_SLAM_11的度量。当神经网络的错误很多时,该损失很大,而当损失很小时则网络的错误也很少。整个训练过程就是在训练集上寻找使损失函数最小的权值和偏置。

干货 | 深入理解深度学习中的激活函数_深度学习_12

图三 梯度下降

在图三中,损失函数的形状像一个碗。在训练过程中的任何一点,损失函数关于权值的偏导数只是在碗的当前位置上的斜率。可见通过向偏导数预测出的方向移动,我们可以到达碗的底部,从而最小化了损失函数。这个使用函数的偏导数来迭代找到局部最小值的方法称为梯度下降法。

在人工神经网络中,权值通过称为反向传播的方法来更新。损失函数关于权值的偏导数用于更新权值。在某种意义上来说,误差是在网络上用导数来反向传播的。这是用迭代的方式来完成的,在许多轮迭代之后,损失达到最小值,并且损失函数的导数变为0。

3. 激活函数的类型

  • 线性激活函数:形式为干货 | 深入理解深度学习中的激活函数_神经网络_13的简单的线性函数。基本上,输入不经过任何修正就传递给输出。

干货 | 深入理解深度学习中的激活函数_SLAM_14

图四 线性激活函数

  • 非线性激活函数:这些函数用于分离非线性可分的数据,并且是最常使用的激活函数。一个非线性等式决定了从输入到输出的映射。不同类型的非线性激活函数分别有sigmod, tanh, relu, lrelu, prelu, swish等等。本文接下来会详细的讨论这些激活函数。

图五 非线性激活函数

4. 在一个人工神经网络中,我们为什么需要非线性激活函数?

神经网络用于实现复杂的函数,而非线性激活函数能够使神经网络逼近任意复杂的函数。如果没有激活函数引入的非线性,多层神经网络就相当于单层的神经网络。

让我们看一个简单的例子来理解为什么没有非线性,神经网络甚至不可能逼近像XOR和XNOR门这样简单的函数。在图六中,我们用图表表示了XOR门。我们的数据集中有两个类,分别用交叉和圆圈来表示。当两个特征干货 | 深入理解深度学习中的激活函数_计算机视觉_15干货 | 深入理解深度学习中的激活函数_计算机视觉_16相同时,类的标签为红色交叉,否则就是蓝色圆圈。当输入为(0,0)与(1,1)时红色交叉的输出为0,输入为(0,1)和(1,0)时的蓝色圆圈的输出为1。

干货 | 深入理解深度学习中的激活函数_深度学习_17

图六 XOR门的图形表示

通过图六我们可以看到数据点都是非线性可分的。也就是说,我们无法画出一条笔直的直线来分开蓝色圆圈和红色交叉。因此,我们才需要非线性的决策边界来将它们分开。如果没有非线性,神经网络就不能逼近XOR门。

激活函数对控制神经网络的输出范围也起着至关重要的作用。神经元的输出干货 | 深入理解深度学习中的激活函数_计算机视觉_18可以是非常大的值。而这个输出,若我们不经修改就输入到下一层神经元中,有可能演变成一个非常大的数从而使得计算过程非常难以处理。而激活函数的任务之一就是将神经元的输出映射到某个范围内(例如:0到1之间)。
接下来,我们准备去了解一下不同类型的激活函数。

5. 非线性激活函数的类型

5.1 Sigmoid激活函数

Sigmoid也被称为逻辑激活函数(Logistic Activation Function)。它将一个实数值压缩到0至1的范围内。当我们的最终目标是预测概率时,它可以被应用到输出层。它使很大的负数向0转变,很大的正数向1转变。在数学上表示为
干货 | 深入理解深度学习中的激活函数_激活函数_19
下图为sigmoid函数以及它的导数图像。

干货 | 深入理解深度学习中的激活函数_SLAM_20

干货 | 深入理解深度学习中的激活函数_神经网络_21

图七 Sigmoid激活函数 图八 Sigmoid激活函数的导数

Sigmoid激活函数的三个主要缺点是:

  • 梯度消失:sigmoid函数在0和1附近是平坦的。也就是说,sigmoid的梯度在0和1附近为0。在通过sigmoid函数网络反向传播时,当神经元的输出近似于0和1时它的梯度接近于0。这些神经元被称为饱和神经元。因此,这些神经元的权值无法更新。不仅如此,与这些神经元相连接的神经元的权值也更新得非常缓慢。这个问题也被称为梯度消失。所以,想象如果有一个大型网络包含有许多处于饱和动态的sigmoid激活函数的神经元,那么网络将会无法进行反向传播。
  • 不是零均值:sigmoid的输出不是零均值的。
  • 计算量太大:指数函数与其它非线性激活函数相比计算量太大了。
    下一个要讨论的是解决了sigmoid中零均值问题的非线性激活函数。

5.2 Tanh激活函数

干货 | 深入理解深度学习中的激活函数_计算机视觉_22

干货 | 深入理解深度学习中的激活函数_激活函数_23

图九 Tanh激活函数 图十 Tanh激活函数的导数

Tanh也被称为双曲正切激活函数。类似sigmoid,tanh也是把一个实数值压缩到-1到1的范围内。与sigmoid不同的是,tanh在-1到1的输出范围内是零均值的。你可以把tanh函数看做是两个sigmoid加在一起。在实际运用中,tanh比sigmoid更好。负数的输入被认为是更大的负数,零值输入映射到零的附近,而正数的输入被认为是正的。Tanh唯一的缺点是:tanh函数也存在着梯度消失的问题,因此在饱和时会导致梯度消失。

为了解决梯度消失问题,让我们讨论另一个被称为线性整流函数(ReLU)的非线性激活函数,它比我们之前讨论的两个激活函数都更好,并且也是在今天应用最为广泛的激活函数。

5.3 线性整流函数(ReLU)

干货 | 深入理解深度学习中的激活函数_计算机视觉_24

干货 | 深入理解深度学习中的激活函数_计算机视觉_25

图十一 ReLU激活函数 图十二 ReLU激活函数的导数

如图十一所示,ReLU激活函数从底部进行了半矫正(half-rectified)。在数学上,它可以由这个简单的表达式表达:干货 | 深入理解深度学习中的激活函数_激活函数_26

这意味着,当输入干货 | 深入理解深度学习中的激活函数_神经网络_27时,输出为0。当输入干货 | 深入理解深度学习中的激活函数_激活函数_28时,输出就是输入x的值。这个激活函数能够使网络更快的收敛。没有饱和意味着至少在正数范围内干货 | 深入理解深度学习中的激活函数_深度学习_29能够对梯度消失有抵抗能力,所以神经元至少在一半的输入范围内不会反向传播回全部都是0的结果。ReLU在计算上非常有效率,因为它是使用简单的阈值实现的。

但是Relu神经元有几个缺点:

  • 不是零均值的:与sigmoid相同,它的输出不是零均值的。
  • Relu的另一个问题是,如果在前向传播的过程中干货 | 深入理解深度学习中的激活函数_深度学习_30,神经元保持没有被激活的状态并且在反向传播时抵消了梯度。此时权值得不到更新,网络无法学习。当干货 | 深入理解深度学习中的激活函数_SLAM_31时,斜率在这个点是没有定义的,不过这个问题在实现的过程中通过选择左或者右梯度解决。
    为了解决relu激活函数在x<0时的梯度消失问题, 我们提出了被称为泄漏relu(Leaky Relu)的激活函数,这个激活函数试图解决ReLU激活函数”Dead ReLU”的问题。让我们详细了解一下leaky relu。

5.4泄漏ReLU激活函数(leaky relu)

干货 | 深入理解深度学习中的激活函数_神经网络_32

图十三 Leaky ReLU激活函数

Leaky ReLU激活函数是一个想要缓解relu消亡问题的尝试。它的函数表达式如下:

干货 | 深入理解深度学习中的激活函数_激活函数_33

Leaky relu的思想就是当干货 | 深入理解深度学习中的激活函数_神经网络_27时,会有个很小0.1的正斜率。这个函数多少消除了relu的消亡问题,但是它的结果并不一致。虽然它具有relu激活函数的所有特征,例如:计算效率高、收敛速度快、在正区域不饱和等。

它的思想可以进一步的扩展。如用一个常数项代替乘以x,从而使我们能够将这个常数项乘以一个能够使leaky relu更好工作的超参数。这个leaky relu的拓展被称为parametric relu(参数relu)。

5.5 参数ReLU激活函数(Parametric ReLU)

PRelu的函数为:干货 | 深入理解深度学习中的激活函数_SLAM_35

其中干货 | 深入理解深度学习中的激活函数_激活函数_36为超参数。PRelu的思想是引进任意超参数干货 | 深入理解深度学习中的激活函数_激活函数_36,而这个干货 | 深入理解深度学习中的激活函数_激活函数_36可以通过反向传播学习。这赋予了神经元在负区域内选择最好斜率的能力,因此,他们可以变成单纯的ReLU激活函数或者Leaky ReLU激活函数。

总之,它优于ReLU,但是你可以通过实验使用Leaky ReLU或者Parametric ReLU来观察它们是否能对你的问题给出最好的结果。

5.6 SWISH激活函数


干货 | 深入理解深度学习中的激活函数_激活函数_39

图十四 SWISH激活函数

Swish也被称为self-gated(自门控)激活函数,最近由谷歌研究人员发布。它的数学表达式为:
干货 | 深入理解深度学习中的激活函数_计算机视觉_40
通过阅读论文我们可以了解到,swish激活函数的表现比relu更好。从图十四中我们可以观察到swish激活函数在x轴的负区域内末端的图像形状与relu激活函数是不同的,这是因为swich激活函数即使输入的值在增加,它的输出也可以减少。大部分的激活函数都是单调的,即他们的输出值在输入增加的时候是不会减少的。Swish在0点具有单边有界性,平滑且不单调。

参考:
https://www.learnopencv.com/understanding-activation-functions-in-deep-learning/

标签:函数,非线性,relu,干货,ReLU,激活,神经元
From: https://blog.51cto.com/u_14318213/6708953

相关文章

  • 函数
    函数创建和删除函数创建函数,需要createprocedure或createanyprocedure的系统权限,创建存储函数的语法和创建存储过程的类似create[orreplace]FUNCTION函数名[(参数[in]数据类型....)]return数据类型 ----注意此不能有分号{as|is}{说明部分}begin可执行部分return......
  • C语言动态分配内存的函数
    今天在学习中碰见了动态分配内存有关的函数:mallocrealloccallocfree。以下是详细的记录"动态内存":在程序运行期间,动态分配内存空间,一般是在"堆,heap"空间上分配。malloc:memoryallocate内存分配realloc:repeatallocate再分配——重新分配:一次内存分配完成之后,后面用......
  • 直接“printf”到char数组字符串——C语言snprintf函数
    注:我写这个只是为了备注并介绍一下这个神器。有关它的更详细用法,互联网的各个角落都不缺少资料。如果您和曾经的我一样是C语言的初学者,您有可能时常遇到那些“奇异”的字符串处理问题,例如,int里的数转成char数组字符串类型,在char数组中间插入或者删除什么东西,等等。要是采用传统方......
  • vue2-生命周期-了解生命周期和生命周期函数的概念
    1.生命周期&生命周期函数生命周期(LifeCycle)是指一个组件从创建->运行->销毁的整个阶段,强调的是一个时间段。生命周期函数:是由vue框架提供的内置函数,会伴随者组件的生命周期,自动按次序执行。注意:生命周期强调的是时间段,生命周期函数强调的是时间点。......
  • 魔法函数 __repr__() 和 __str__()的区别
    1'''2__repr__()和__str__()都是Python中的特殊方法,用于定义对象的字符串表示形式。它们之间的区别如下:31.__repr__(self):返回一个字符串,用于表示对象的“官方”字符串表示形式。这个字符串应该是可以用来重新创建对象的,并且应该尽可能准确和详细。4......
  • ORACLE instr函数
    语法     系列函数:INSTR系列函数总共有5个,常用为instr函数,其他4个都是变体。这些函数之间区别仅在于入参string数据类型的限制。Instr函数入参string类型要求为:char, varchar2, nchar(采用unicode标准字符集存储), nvarchar2, clob(characterlargeobject......
  • 111.在进行函数参数以及返回值传递时,可以使用引用或者值传递,其中使用引用的好处有哪
    111.在进行函数参数以及返回值传递时,可以使用引用或者值传递,其中使用引用的好处有哪些?对比值传递,引用传参的好处:1)在函数内部可以对此参数进行修改2)提高函数调用和运行的效率(因为没有了传值和生成副本的时间和空间消耗)如果函数的参数实质就是形参,不过这个形参的作用域只是在函......
  • 112.说一说strcpy、sprintf与memcpy这三个函数的不同之处
    112.说一说strcpy、sprintf与memcpy这三个函数的不同之处1.复制的内容不同。strcpy只能复制字符串,而memcpy可以复制任意内容,例如字符数组、整型、结构体、类等。2.复制的方法不同。strcpy不需要指定长度,它遇到被复制字符的串结束符"\0"才结束,所以容易溢出。memcpy则是根据其第3......
  • C语言库函数
    C语言库函数1.stdio库1.1printf函数printf格式化输出符:inta=3;floatb=3.14;doublec=5.2;chars1[6]={'h','e','l','l','o','\0'};char*s2="world";printf("%d%f%f\n",......
  • 高等数学——一隐函数及参数方程求导
    隐函数求导显函数:\(y\)能表达成\(x\)的一种表达式。隐函数:\(y\)在表达式里提取不出来。\[e^{y}+xy-e=0\]两边同时对\(x\)进行求导即可。\[e^{y}\cdoty'+y+xy'=0\]\[y'=-\frac{y}{e^{y}+x}\]出来的带着\(y\)带着就带着,甭管。对于形似:\[y=u^{v}=e^{\lnu^{v}}=e^{......