前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >深度学习中常用激活函数的详细总结

深度学习中常用激活函数的详细总结

作者头像
触摸壹缕阳光
发布2020-02-17 16:03:00
1.8K0
发布2020-02-17 16:03:00
举报

能坚持别人不能坚持的,才能拥有别人不能拥有的。

前言

本文总结了几个在深度学习中比较常用的激活函数:Sigmoid、ReLU、LeakyReLU以及Tanh,从激活函数的表达式、导数推导以及简单的编程实现来说明。

a

Sigmoid 激 活 函 数

▲Sigmoid激活函数表达式

▲Sigmoid导数表达式

▲Sigmoid编程实现

▲Sigmoid激活函数以及导函数图像

Sigmoid激活函数也叫做Logistic函数,因为它是线性回归转换为Logistic(逻辑回归)的核心函数,这也是Sigmoid函数优良的特性能够把X ∈ R的输出压缩到X ∈ (0, 1)区间。Sigmoid激活函数在其大部分定义域内都会趋于一个饱和的定值。当x取绝对值很大的正值的时候,Sigmoid激活函数会饱和到一个高值(无限趋近于1);当x取绝对值很大的负值的时候,Sigmoid激活函数会饱和到一个低值(无限趋近于0)。Sigmoid函数是连续可导函数,在零点时候导数最大,并在向两边逐渐降低,可以简单理解成输入非常大或者非常小的时候,梯度为0没有梯度,如果使用梯度下降法,参数得不到更新优化。

Sigmoid函数最大的特点就是将数值压缩到(0, 1)区间,在机器学习中常利用(0, 1)区间的数值来表示以下意义:

  1. 概率分布:根据概率公理化定义知道,概率的取值范围在[0, 1]之间,Sigmoid函数的(0, 1)区间的输出和概率分布的取值范围[0, 1]契合。因此可以利用Sigmoid函数将输出转译为概率值的输出。这也是Logistic(逻辑回归)使用Sigmoid函数的原因之一;
  2. 信号强度:一般可以将0~1理解成某种信号的强度。由于RNN循环神经网络只能够解决短期依赖的问题,不能够解决长期依赖的问题,因此提出了LSTM、GRU,这些网络相比于RNN最大的特点就是加入了门控制,通过门来控制是否允许记忆通过,而Sigmoid函数还能够代表门控值(Gate)的强度,当Sigmoid输出1的时候代表当前门控全部开放(允许全部记忆通过),当Sigmoid输出0的时候代表门控关闭(不允许任何记忆通过)。

上面介绍了Sigmoid激活函数将输出映射到(0, 1)区间在机器学习中的两个意义,这也是Sigmoid激活函数的优点。接下来介绍一下Sigmoid激活函数的缺点:

  • 经过Sigmoid激活函数输出的均值为0.5,即输出为非0均值;

▲Sigmoid激活函数输出均值不为0

反向传播时候更新方向要不往正向更新,要不往负向更新,会导致捆绑效果,使得收敛速度减慢。当然,如果使用小批量梯度下降法,由于每个小batch可能会得到不同的信号,所以这个问题还是有可能缓解的。2015年loffe提出的批标准化(Batch Normalization)就是为了适应性的将每层输出分布都进行统一,以便网络学习更加稳定、更快的传播。

  • 计算求解的时候计算量较大,相对来说会比较耗时。这其实很好理解,因为观察Sigmoid激活函数表达式会发现其中有幂函数参与了运算,而且在反向传播求导过程中涉及到除法运算;
  • 对于Sigmoid激活函数最致命的缺点就是容易发生梯度弥散(Gradient vanishing)现象(当然也可能会发生梯度爆炸Exploding gradient,前面层的梯度通过模型训练变的很大,由于反向传播中链式法则的原因,导致后面层的梯度值会以指数级增大。但是在Sigmoid激活函数中梯度保障发生的概率非常小),所谓梯度弥散故名思议就是梯度值越来越小。在深度学习中,梯度更新是从后向前更新的,这也就是所谓的反向传播(Backpropagation algorithm),而反向传播的核心是链式法则。如果使用Sigmoid激活函数,训练的网络比较浅还比较好,但是一旦训练较深的神经网络,会导致每次传过来的梯度都会乘上小于1的值,多经过几层之后,梯度就会变得非常非常小(逐渐接近于0),梯度因此消失了,对应的参数得不到更新。因此使用Sigmoid激活函数,随着神经网络层数的增加,会出现靠近输出的层参数更新幅度比较大,而靠近输入的层参数更新幅度比较小。因而使用Sigmoid激活函数容易出现梯度弥散的现象,无法完成深层网路的训练;

在Tensorflow2.X中Sigmoid激活函数只有函数式接口的实现方式:

  1. 函数式接口:tf.nn.sigmoid(x, name = None);

▲Sigmoid激活函数实现

b

ReLU 激 活 函 数

▲ReLU激活函数表达式

▲ReLU导数表达式

▲ReLU编程实现

▲ReLU激活函数以及导函数图像

2012年ImageNet竞赛的冠军模型是由Hinton和他的学生Alex设计的AlexNet,其中使用了一个新的激活函数ReLU(REctified Linear Unit,修正线性单元)。在这之前Sigmoid函数通常是神经网络激活函数的首选,上面也提到过,Sigmoid函数在输入值较大或较小的时候容易出现梯度值接近于0的现象,也就是梯度弥散。出现梯度弥散现象,网络参数会长时间得不到更新,很容易导致训练不收敛或停滞不动的现象发生,网络层数较深的网络模型更容易发生梯度弥散现象,使得对神经网络的研究一直停留在浅层网络。值得一提的是,AlexNet是一个8层的网络,而后续提出的上百层的卷积神经网络也多是采用ReLU激活函数。

通过ReLU激活函数的函数图像可以看到,ReLU对小于0的值全部抑制为0;对于正数则直接输出,这是一种单边抑制的特性,而这种单边抑制来源于生物学。ReLU函数的导数计算也非常简单,x大于等于0的时候,导数值为1,在反向传播的过程中,它既不会放大梯度,造成梯度爆炸;也不会缩小梯度,造成梯度弥散的现象。

上面从ReLU函数的起源以及Relu函数图像角度来阐述ReLU激活函数,接下来详细的来看看ReLU函数的优缺点。

优点:

  • 不饱和(梯度不会过小)。对于ReLU函数,当输入值为正的时候,梯度恒为1,没有梯度弥散的现象,收敛速度快;
  • 增大了网络的稀疏性。当输入值x < 0的时候,该层的输出为0,训练完成后为0的神经元越来越多,稀疏性会变大,网络的协同性会被破坏,更够迫使网络学习到更一般性的特征,泛化能力会变强。这也正是dropout的原理;
  • 计算量变小。ReLU函数和Sigmoid函数相比少了复杂的幂运算,计算量变小;

缺点:

  • 输出均值非0。ReLU函数与Sigmoid函数相同,输出均值都是非0的,这一点在前面介绍Sigmoid函数的时候提到过,这里不再赘述;
  • Dead ReLU。如果某个层的正向梯度值特别大,会导致w优化参数更新后的值变的特别大,由梯度更新公式可知,该层的输入x < 0,相应的输出值为0,那么此时该层就会"死亡",参数不会更新,而且这是不可逆转的"死亡",这个神经元永远的失效,这会失去数据样本的多样化。如果开始选定的学习率比较大的话很可能40%的神经元在训练开始的时候就会"死亡",因此使用ReLU激活函数的时候,需要选定一个合适的学习率让这种情况发生的概率降低;

在Tensorflow2.X中ReLU激活函数有两种实现方式:

  1. 函数式接口:tf.nn.relu(x, name = None);
  2. 激活函数类:tf.keras.layers.ReLU()。可以像Dense层一样将ReLU函数作为一个网络层添加到网络中,一般来说,激活函数类并不是主要的网络运算层,因此不计入网络的层数;

▲ReLU激活函数函数式接口

▲ReLU激活函数类

c

LeakyReLU 激 活 函 数

▲LeakyReLU激活函数表达式

▲LeakyReLU导数表达式

▲LeakyReLU函数以及导函数实现

▲LeakyReLU激活函数以及导函数图像

LeakyReLU函数是针对ReLU函数的Dead ReLU而提出来的。ReLU激活函数在x < 0的时候导数恒为0,很可能致使很多神经元为0,参数得不到更新。通过LeakyReLU函数表达式也可以看出,与ReLU函数唯一的不同就是在x < 0的部分输出不在为0而是px,p为超参数,通常是一个较小的值。当p = 0的时候,LeakyReLU函数退化成ReLU函数;当p ≠ 0的时候,在x < 0的时候能够得到较小的导数值p。从而避免出现Dead ReLU的现象。

当然了其实ReLU激活函数当x < 0的时候输出为0也有它的优点。也就是增大网络的稀疏性,这往往会提高模型的泛化能力(类似dropout作用)。因此虽然提出了LeakyReLU这种激活函数,但是目前使用比较广泛的还是ReLU激活函数。

在Tensorflow2.X中LeakyReLU激活函数有两种实现方式:

  1. 函数式接口:tf.nn.leaky_relu(x, name = None);
  2. 激活函数类:tf.keras.layers.LeakyReLU()。可以像Dense层一样将LeakyReLU函数作为一个网络层添加到网络中,一般来说,激活函数类并不是主要的网络运算层,因此不计入网络的层数;

▲LeakyReLU激活函数函数式接口

▲LeakyReLU激活函数类

d

Tanh 激 活 函 数

▲Tanh激活函数表达式

▲Tanh导函数表达式

▲Tanh函数实现

▲Tanh函数以及导函数图像

Tanh激活函数(hyperbolic tangent, 双曲正切),通过函数表达式可以看出,tanh可由sigmoid激活函数平移缩放得到。tanh函数将输出值映射到(-1, 1)区间,有点类似于幅度增大的sigmoid激活函数。

接下来依然介绍tanh函数的优点和缺点。

优点:

  • 输出均值为0。这是tanh非常重要的一个优点;
  • tanh在原点附近与y = x函数形式相近,当激活值比较低的时候,训练相对比容易;
  • tanh的变化敏感区间较宽,缓解梯度弥散的现象。tanh导数取值范围在0到1之间,要优于sigmoid激活函数的0到0.25,相比于Sigmoid激活函数能够缓解梯度弥散的现象;
  • tanh的输出和输入能够保持非线性单调上升和下降的关系,符合反向传网络梯度的求解,容错性好,有界;

缺点:

  • 计算量比较大;

在Tensorflow2.X中tanh激活函数只有函数式接口的实现方式:

  1. tf.nn.tanh(x, name = None);

▲Tanh函数实现

参考: 1.《Tensorflow深度学习》

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-01-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 AI机器学习与深度学习算法 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档