zoukankan      html  css  js  c++  java
  • 干货 | 深入理解深度学习中的激活函数

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

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

    1. 什么是激活函数?

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

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

    ki2mBd.png

    ​ 图一 生物神经网络

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

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

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

    ki2tBj.png

    ​ 图二 所示的例子是一个输入为((x_1-x_n))的神经元,输入对应

    ​ 的权重分布为((w_1-w_n)),偏置为(b),激活函数((f))作用于输入

    ​ 的权重之和上面。

    ​ 图二中的((x_1,...,x_n))是与权重((w_1,...,w_n))相乘的信号向量,接着是累加(例如:总和+偏置b)。最后,激活函数f作用于这个累加的总和。请注意,权重((w_1,...,w_n))和偏置b把输入信号转换为线性的。而另一方面,激活函数把信号转换为非线性的,而这种非线性使得我们能够学习到输入与输出之间任意复杂的变换关系。

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

    2. 网络是怎么学习的?

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

    ki2enH.png

    ​ 图三 梯度下降

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

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

    3. 激活函数的类型

    • 线性激活函数:形式为(f(x)=x)的简单的线性函数。基本上,输入不经过任何修正就传递给输出。

    ki2Vje.png

    ​ 图四 线性激活函数

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

      ki2Q4P.png

      ​ 图五 非线性激活函数

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

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

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

    ki2nHA.png

    ​ 图六 XOR门的图形表示

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

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

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

    5.1 Sigmoid激活函数

    ​ Sigmoid也被称为逻辑激活函数(Logistic Activation Function)。它将一个实数值压缩到0至1的范围内。当我们的最终目标是预测概率时,它可以被应用到输出层。它使很大的负数向0转变,很大的正数向1转变。在数学上表示为

    [alpha(x)=frac{1}{1+e^{-x}} ]

    下图为sigmoid函数以及它的导数图像。

    ki2KAI.png ki2MNt.png

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

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

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

    • 不是零均值:sigmoid的输出不是零均值的。

    • 计算量太大:指数函数与其它非线性激活函数相比计算量太大了。

      下一个要讨论的是解决了sigmoid中零均值问题的非线性激活函数。

    5.2 Tanh激活函数

    ki2338.pngki2Gjg.png

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

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

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

    5.3 线性整流函数(ReLU)

    ki219f.pngki28gS.png

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

    ​ 如图十一所示,ReLU激活函数从底部进行了半矫正(half-rectified)。在数学上,它可以由这个简单的表达式表达:$$f(x)=max(x,0)$$

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

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

    • 不是零均值的:与sigmoid相同,它的输出不是零均值的。

    • Relu的另一个问题是,如果在前向传播的过程中(x<0),神经元保持没有被激活的状态并且在反向传播时抵消了梯度。此时权值得不到更新,网络无法学习。当(x=0)时,斜率在这个点是没有定义的,不过这个问题在实现的过程中通过选择左或者右梯度解决。

      为了解决relu激活函数在x<0时的梯度消失问题, 我们提出了被称为泄漏relu(Leaky Relu)的激活函数,这个激活函数试图解决ReLU激活函数”Dead ReLU”的问题。让我们详细了解一下leaky relu。

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

    ki2NHs.png

    ​ 图十三 Leaky ReLU激活函数

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

    ​ $$f(x)=max(0.1x,x)$$

    ​ Leaky relu的思想就是当(x<0)时,会有个很小0.1的正斜率。这个函数多少消除了relu的消亡问题,但是它的结果并不一致。虽然它具有relu激活函数的所有特征,例如:计算效率高、收敛速度快、在正区域不饱和等。

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

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

    ​ PRelu的函数为:(f(x)=max(alpha{x},x))

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

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

    5.6 SWISH激活函数

    ki2YuQ.png

    ​ 图十四 SWISH激活函数

    ​ Swish也被称为self-gated(自门控)激活函数,最近由谷歌研究人员发布。它的数学表达式为:

    [alpha{(x)}=frac{x}{1+e^{-x}} ]

    ​ 通过阅读论文我们可以了解到,swish激活函数的表现比relu更好。从图十四中我们可以观察到swish激活函数在x轴的负区域内末端的图像形状与relu激活函数是不同的,这是因为swich激活函数即使输入的值在增加,它的输出也可以减少。大部分的激活函数都是单调的,即他们的输出值在输入增加的时候是不会减少的。Swish在0点具有单边有界性,平滑且不单调。

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

    推荐阅读

    原来CNN是这样提取图像特征的。。。
    算力限制场景下的目标检测实战浅谈
    开源 | 用深度学习让你的照片变得美丽
    面试时让你手推公式不在害怕 | 线性回归
    深度学习在计算机视觉各项任务中的应用

  • 相关阅读:
    pipelinewise 学习二 创建一个简单的pipeline
    pipelinewise 学习一 docker方式安装
    Supercharging your ETL with Airflow and Singer
    ubuntu中使用 alien安装rpm包
    PipelineWise illustrates the power of Singer
    pipelinewise 基于singer 指南的的数据pipeline 工具
    关于singer elt 的几篇很不错的文章
    npkill 一个方便的npm 包清理工具
    kuma docker-compose 环境试用
    kuma 学习四 策略
  • 原文地址:https://www.cnblogs.com/CV-life/p/10449293.html
Copyright © 2011-2022 走看看