前言

最近自己刚刚开始学习神经网络的相关知识,在学习构建一个自定义网络的时候,对于在forward函数中突然出现的Relu函数有点奇怪,然后就去百度查询了一波,原来这就是前面了解概念的时候所说的激活函数也就是激励函数,自己也是在百度和知乎上了解的更加透彻一点点,现在就自己的理解和参考一些别人的说法进行一定的总结,这次总结就主要是如下几点

  • 什么是激活函数
  • 激活函数的作用(为什么就需要激活函数嘞)
  • 有哪些常用的激活函数,都各自有什么性质和特点
  • 在应用中该如何选择合适的激活函数

什么是激活函数

想要了解什么是激活函数,应该先了解神经网络的基本模型,单一的额神经元模型如图1所示。神经网络中的每个神经元节点接受上一层神经元的输出值作为本神经元的输入值,并将输入值传递给下一层,输入层神经元节点会将输入属性值直接传递给下一层(隐层或输出层)。在多层神经网络中,上层节点的输出和下层节点的输入之间具有一个函数关系,这个函数称为激活函数(又称激励函数)。

图 1 单个神经元结构结构

激活函数的作用

查阅了相关资料和学习,大家普遍对神经网络中的激活函数的额作用主要集中在下面这个观点

  • 激活函数是用来加入非线性因素的,解决线性模型所不能解决的问题。

下面举个例子,这个例子是我知乎上看到一位博主写的,个人觉得很不错,就搬过来了,在这里也加入了自己的思考,进一步理解。

首先我们现在有这么一个需求,就是二分类的问题,如果我要将下图的三角形和圆形进行正确的分类,也就是分隔开来,如图2所示:

图 2

利用我们单层的感知机, 下图图3直线是由[公式]得到,那么该感知器实现预测的功能步骤如下,就是我已经训练好了一个感知器模型,后面对于要预测的样本点,带入模型中,如果[公式],那么就说明是直线的右侧,也就是正类(我们定义是三角形),如果[公式],那么就说明是直线的左侧,也就是负类(我们定义是圆形)。

图 3

利用我们上面单层的感知机, 用它可以任意划出一条线, 把平面分割成两部分,如图4所示,很容易能够看出,我给出的样本点根本不是线性可分的,一个感知器无论得到的直线怎么动,都不可能完全正确的将三角形与圆形区分出来,也就是说一条线性结构的直线是无法将三角形和长方形完全分割开来的。

图 4

此刻我们很容易想到用多个感知器来进行组合(也就是可以多条线性的直线),以便获得更大的分类问题,好的,下面我们上图,看是否可行,如图5,

图 5

好的,我们已经得到了多感知器分类器了,那么它的分类能力是否强大到能将非线性数据点正确分类开呢~我们来分析一下:

我们能够得到

哎呀呀,不得了,这个式子看起来非常复杂,估计应该可以处理我上面的情况了吧,哈哈哈哈~不一定额,我们来给它变个形.上面公式合并同类项后等价于下面公式:

啧啧,估计大家都看出了,不管它怎么组合,最多就是线性方程的组合,最后得到的分类器本质还是一个线性方程,该处理不了的非线性问题,它还是处理不了。

就好像下图图6,直线无论在平面上如果旋转,都不可能完全正确的分开三角形和圆形点:

图 6

既然是非线性问题,总有线性方程不能正确分类的地方,那么抛开神经网络中神经元需不需要激活函数这点不说,如果没有激活函数,仅仅是线性函数的组合解决的问题太有限了,碰到非线性问题就束手无策了.那么加入激活函数是否可能能够解决呢?

在上面线性方程的组合过程中(在加入阶跃激活函数的时候),我们其实类似在做三条直线的组合,如下图7:

图 7

在这里就可以大声说出,激活函数就是来解决非线性因素的,没有太大的问题,就拿sigmoid例子说上面的场景,如图8sigmoid函数

图 8

通过这个激活函数映射之后,输出很明显就是一个非线性函数!能不能解决一开始的非线性分类问题不清楚,但是至少说明有可能啊,上面不加入激活函数神经网络压根就不可能解决这个问题

同理,扩展到多个神经元组合的情况时候,表达能力就会更强~对应的组合图9如下:(现在已经升级为三个非线性感知器在组合了)

图 9

跟上面线性组合相对应的非线性组合如下,图10:

图 10

这看起来厉害多了,是不是~最后再通过最优化损失函数的做法,我们能够学习到不断学习靠近能够正确分类三角形和圆形点的曲线,到底会学到什么曲线,不知道到底具体的样子,也许是下面图11这个,那么随着不断训练优化,我们也就能够解决非线性的问题了。

图 11

所以到这里为止,我们就解释了这个观点,加入激活函数是用来加入非线性因素的,解决线性模型所不能解决的问题。

常用激活函数

Sigmoid函数,是比较常用的非线性激活函数

  • 数学表达式

  • 值域:(0,1);导数值域(0,0.25)

  • 函数图像,如下图:

  • 优点

    • 值域为(0,1),可以放到模型最后一层,作为模型的概率输出
    • 特别的,如果是非常大的负数,那么输出就是0;如果是非常大的正数,输出就是1
  • 缺点

    • 在深度神经网络中梯度反向传递时导致梯度爆炸和梯度消失,其中梯度爆炸发生的概率非常小,而梯度消失发生的概率比较大。如果我们初始化神经网络的权值为 [ 0 , 1 ] 之间的随机值,由反向传播算法的数学推导可知,梯度从后向前传播时,每传递一层梯度值都会减小为原来的0.25倍,如果神经网络隐层特别多,那么梯度在穿过多层后将变得非常小接近于0,即出现梯度消失现象;当网络权值初始化为 ( 1 , + ∞ ) (1,+∞)(1,+∞) 区间内的值,则会出现梯度爆炸情况。

    • 函数输出不是以0为中心的(不是zero-centered输出问题),这样会使权重更新效率降低。这是不可取的,因为这会导致后一层的神经元将得到上一层输出的非0均值的信号作为输入。 产生的一个结果就是:如

      那么对w求局部梯度则都为正,这样在反向传播的过程中w要么都往正方向更新,要么都往负方向更新,导致有一种捆绑的效果,使得收敛缓慢。

    • 其解析式中含有幂运算,计算机求解时相对来讲比较耗时。对于规模比较大的深度网络,这会较大地增加训练时间

tanh函数

  • 数学表达式

  • 值域:(-1,1)当|x|>3时,函数容易饱和;导数值域(0,1)当|x|>3时,梯度几乎为0

  • 函数图像,如下图:(蓝色是Tanh原函数,紫色是导函数图像)

  • 优点

    • 函数均值为0,一般作为图像生成的最后一层激活函数。
    • 整个函数是以0为中心的,这个特点比sigmod的好,解决了Sigmoid函数的不是zero-centered输出问题
  • 缺点

    • 仍然存在梯度消失问题;涉及指数运算,复杂度高一些

Relu函数

  • 数学表达式

  • 值域:当x<0时,函数值为0,当x>0时,函数值跟x线性增长; 当x<0时,导数值域:导函数值为0,当x>0时,导函数值为1

  • 函数图像:

  • 优点

    • 解决了gradient vanishing问题 (在正区间)
    • 计算速度非常快,只需要判断输入是否大于0
    • 收敛速度远快于sigmoid和tanh
  • 缺点

    • 当输入是负数的时候,ReLU是完全不被激活的,这就表明一旦输入到了负数,ReLU就会死掉。这样在前向传播过程中,还不算什么问题,有的区域是敏感的,有的是不敏感的。但是到了反向传播过程中,输入负数,梯度就会完全到0,这个和sigmod函数、tanh函数有一样的问题。
    • ReLU函数的输出要么是0,要么是正数,这也就是说,ReLU函数也不是以0为中心的函数。

尽管存在这两个问题,ReLU目前仍是最常用的activation function,在搭建人工神经网络的时候推荐优先尝试!

ELU函数

  • 数学表达式

  • 函数图像:

  • ELU函数是针对ReLU函数的一个改进型,相比于ReLU函数,在输入为负数的情况下,是有一定的输出的,而且这部分输出还具有一定的抗干扰能力。这样可以消除ReLU死掉的问题,不过还是有梯度饱和和指数运算的问题。不会有Dead ReLU问题和 输出的均值接近0,zero-centered。理论上虽然好于ReLU,但在实际使用中目前并没有好的证据证明ELU总是优于ReLU。

PReLU函数

  • 函数表达式

  • 函数图像:

  • PReLU也是针对ReLU的一个改进型,在负数区域内,PReLU有一个很小的斜率,这样也可以避免ReLU死掉的问题。相比于ELU,PReLU在负数区域内是线性运算,斜率虽然小,但是不会趋于0,这算是一定的优势吧。

    我们看PReLU的公式,里面的参数α一般是取0~1之间的数,而且一般还是比较小的,如零点零几。当α=0.01时,我们叫PReLU为Leaky ReLU,是PReLU的一种特殊情况吧

Maxout函数

  • 函数表达式:
  • 我们可以看到,Sigmoid函数实际上就是把数据映射到一个(−1,1)的空间上,也就是说,Sigmoid函数如果用来分类的话,只能进行二分类,而这里的softmax函数可以看做是Sigmoid函数的一般化,可以进行多分类。Softmax回归模型是logistic回归模型在多分类问题上的推广,在多分类问题中,待分类的类别数量大于2,且类别之间互斥。比如我们的网络要完成的功能是识别0-9这10个手写数字,若最后一层的输出为[0,1,0, 0, 0, 0, 0, 0, 0, 0],则表明我们网络的识别结果为数字1。

应用中如何选择激活函数

  • 深度学习往往需要大量时间来处理大量数据,模型的收敛速度是尤为重要的。所以,总体上来讲,训练深度学习网络尽量使用zero-centered数据 (可以经过数据预处理实现) 和zero-centered输出。所以要尽量选择输出具有zero-centered特点的激活函数以加快模型的收敛速度。
  • 如果使用 ReLU,那么一定要小心设置 learning rate,而且要注意不要让网络出现很多 “dead” 神经元,如果这个问题不好解决,那么可以试试 Leaky ReLU、PReLU 或者 Maxout.
  • 最好不要用 sigmoid,你可以试试 tanh,不过可以预期它的效果会比不上 ReLU 和 Maxout.
  • 在较深层的神经网络中,选用relu激活函数能使梯度更好地传播回去,但当使用softmax作为最后一层的激活函数时,其前一层最好不要使用relu进行激活,而是使用tanh作为替代,否则最终的loss很可能变成Nan;
  • 当选用高级激活函数时,建议的尝试顺序为ReLU->ELU->PReLU->MPELU,因为前两者没有超参数,而后两者需要自己调节参数使其更适应构建的网络结构。