深度学习核心之激活函数
概述
激活函数(Activation Function)
是一种添加到人工神经网络中的函数,旨在帮助网络学习数据中的复杂模式
引入激活函数的目的
不使用激活函数的话,神经网络的每层都只是做线性变换,多层输入叠加后也还是线性变换。因为线性模型的表达能力通常不够
所以这时候就体现了激活函数的作用了,激活函数可以引入非线性因素,设有三个线性变换
将这三个线性变换加到一起,可以得到
所以,如果神经网络只有线性,那么不论有多少隐层,有多少神经元,最终还是线性的
此时就需要通过添加激活函数来对每一层的输出做处理,引入非线性因素,使得神经网络可以逼近任意的非线性函数
激活函数在神经网络中的应用,除了引入非线性表达能力
,其在提高模型鲁棒性
、缓解梯度消失
问题、将特征输入映射到新的特征空间以及加速模型收敛等方面都有不同程度的改善作用
小结:
引入非线性表达能力
提高模型鲁棒性:非线性的激活函数能够引入非线性变换,从而使神经网络具有更强的表达能力,能够更好地拟合复杂的数据分布和模式
缓解梯度消失问题:在深层神经网络中,由于链式求导的关系,梯度在反向传播过程中会逐渐减小,导致梯度消失的问题
使用非线性激活函数可以帮助缓解梯度消失,因为这些函数在输入的不同范围内具有不同的斜率,从而允许梯度能够在反向传播中更好地传递
常见激活函数
Activation Functions with Derivative and Python code: Sigmoid vs Tanh Vs Relu
激活函数发展历程
早期 | 1970 | 1980 | 2010 | 2013 |
---|---|---|---|---|
阶跃函数(Step Function) | Sigmoid | 双曲正切(Tanh) | ReLU(Rectified Linear Unit) | Leaky ReLU Maxout |
2015 | 2016 | 2017 | 2020 |
---|---|---|---|
PReLU(Parametric ReLU) | ELU(Exponential Linear Unit) GELUS(Gaussian Error Linear Units) |
Swish | Mish |
相对应的论文链接如下
Fast and Accurate Deep Network Learning by Exponential Linear Units (ELUs) 2016
Gaussian Error Linear Units (GELUS) 2016年提出
Searching for Activation Functions (Swish) 2017
Swish: a Self-Gated Activation Function 2017
Mish: A Self Regularized Non-Monotonic Neural Activation Function 2019
Sigmoid
Sigmoid函数
(Logistic函数
)函数的图像看起来像一个S形曲线,函数表达式如下
对应的导数为
函数图像和对应的导数图像如下图所示
作用
将输入映射到0到1之间的连续值,常用于二分类问题或输出层的概率预测
Sigmoid激活函数的优缺点
优点
- 平滑
- 易于求导
- 可以作为概率,辅助模型解
缺点
梯度消失: Sigmoid函数的导数形式为,其中是Sigmoid函数
当输入值非常大时,Sigmoid函数接近于1,导数接近于0,而当输入值非常小时,Sigmoid函数接近于0,导数同样接近于0
这意味着在反向传播时,梯度逐渐变小并趋近于零,传递到较早层时,梯度几乎消失了
梯度更新慢: 如果神经元的输出大部分位于饱和区域(接近0或1),那么梯度将非常小,
因为sigmoid函数在饱和区域的导数接近于0
(如图所示)这样,权重的更新将变得非常缓慢,可能导致训练过程变得困难,并且网络的收敛速度减慢
计算效率低: Sigmoid函数执行指数运算,计算机运行得较慢
Tanh
Tanh函数
(双曲正切函数
)函数的图像看起来也像一个S形曲线,函数表达式如下
对应的导数为
Tanh图像和sigmoid函数比较如下图所示
与Sigmoid函数对比
Tanh是一个双曲正切函数,Tanh函数和sigmoid函数的曲线相对相似,但是它比sigmoid函数更有一些优势,这两种激活函数均为饱和激活函数
优点:
- 范围更广:tanh函数的输出范围是(-1, 1),而sigmoid函数的输出范围是(0, 1),tanh函数在均值为0附近更集中,对于某些任务可能更适用
- 收敛速度快:tanh函数在输入的绝对值较大时,输出的梯度也较大,这可以帮助网络更快地收敛
- 具有零中心性:tanh函数的均值为0,相对于sigmoid函数来说更容易处理正负值的输入,训练相对容易
缺点:
- 梯度消失问题: 与Sigmoid函数类似,梯度消失问题仍然存在
- 计算代价较高:相对于sigmoid函数来说,tanh函数的计算代价较高,因为它需要进行指数运算
Relu
ReLU函数
的主要优点是计算简单、非线性表达能力强、使网络更快速地收敛,并且在深度神经网络中表现出良好的性能,函数表达式如下
对应的导数为
函数图像和对应的导数图像如下图所示
主要优缺点
优点:
- 计算速度快:ReLU函数的计算非常简单,只有线性关系,不需要指数计算,不管在前向传播还是反向传播,计算速度都比sigmoid和tanh快
- 缓解梯度消失问题:相比于sigmoid和tanh等函数,在正区间上ReLU函数的导数为常数1,这有助于缓解梯度消失问题,使得深层网络的梯度能够更好地传播,更容易进行反向传播算法的优化,至少x在正区间内,神经元不会饱和
- 激活稀疏性:ReLU函数对于负输入值直接输出为0,这导致神经元的激活变得稀疏,即只有部分神经元会被激活。这种稀疏性有助于减少参数之间的冗余,并且在一定程度上具有正则化的效果
缺点:
- 神经元死亡问题:ReLU函数在负区间上输出恒为0,当神经元在训练过程中出现负输入时,会导致该神经元永远不会被激活,称为神经元死亡问题。这会导致一部分神经元失去了学习能力
- 输出不是零中心:ReLU函数的输出范围是,并不以0为中心,这可能会对某些优化算法的收敛速度产生影响
训练神经网络的时候,一旦学习率没有设置好,第一次更新权重的时候,输入的是负值,那么这个含有ReLU的神经节点就会死亡,再也不会被激活
在实际训练中,如果学习率设置的太高,可能会发现网络中40%的神经元都会死掉,且在整个训练集中这些神经元都不会被激活
所以,设置一个合适的较小的学习率会降低这种情况的发生
为了解决神经元节点死亡的情况,有人提出了Leaky ReLU、P-ReLU、R-ReLU、ELU等激活函数
Leaky ReLU
Leaky ReLU函数
在负数范围内引入了一个小的斜率,解决了ReLU函数中负数部分的死亡问题,函数表达式如下
对应的导数为
函数图像和对应的导数图像如下图所示
优缺点
优点:
Leaky ReLU中引入了超参数,一般设置为0.01。在反向传播过程中,对于Leaky ReLU的输入小于零的情况,也可以计算得到一个梯度(而不是像ReLU一样值为0),这样就避免了神经元死亡的问题
缺点:
- 稀疏性差: 相较于ReLU,神经网络的稀疏性要差一些
- 额外的超参数: 引入了额外的超参数
- 神经网络不学习值
为什么Leaky ReLU比ReLU更好
- 调整负值的零梯度: Leaky ReLU通过把x的非常小的线性分量给予负输入(0.01x)来调整负值的零梯度(zero gradients)问题
- 扩大函数的范围: Leaky ReLU有助于扩大ReLU函数的范围,通常的值为0.01左右
- 取值范围: Leaky ReLU的函数范围是(负无穷到正无穷)
从理论上讲,Leaky ReLU具有ReLU的所有优点,而且Dead ReLU不会有任何问题,但在实际操作中,尚未完全证明Leaky ReLU总是比ReLU更好
PReLU
P-Relu激活函数的解析式
P-Relu函数及其导数的图像如下图所示
其中是超参数。这里引入了一个随机的超参数,它可以被学习,因为你可以对它进行反向传播
这使神经元能够选择负区域最好的梯度,有了这种能力,它们可以变成ReLU或Leaky ReLU
与ReLU和Leaky ReLU的关系
看一下PReLU的公式:参数α通常为0到1之间的数字,并且通常相对较小
- 如果,则变为ReLU
- 如果,则变为Leaky ReLU
- 如果是可学习的参数,则变为PReLU
ELU
ELU激活函数
解决了ReLU的一些问题,同时也保留了一些好的方面。这种激活函数要选取一个值;常见的取值是在0.1到0.3之间
对应的导数为
函数及其导数的图像如下图所示
如果我们输入的值大于0,则结果与ReLU一样,即值等于值;但如果输入的值小于0,则我们会得到一个稍微小于0的值,所得到的值取决于输入的值,但还要兼顾参数你可以根据需要来调整这个参数。更进一步,我们引入了指数运算,因此ELU的计算成本比ReLU高
优缺点
优点
- 与ReLU不同,它没有神经元死亡的问题。 这是因为 ELU 的梯度对于所有负值都是非零的
- 与其他线性非饱和激活函数(如 ReLU 及其变体)相比,它有着更快的训练时间
- 作为非饱和激活函数,它不会遇到梯度爆炸或消失的问题
- 所有点上都是连续的和可微
缺点
- 包含指数运算,计算时间长
- 无法避免梯度爆炸问题
- 神经网络无法学习值
与Leaky-ReLU和PReLU类似,与ReLU不同的是,ELU没有神经元死亡的问题(ReLU Dying 问题是指当出现异常输入时,在反向传播中会产生大的梯度,这种大的梯度会导致神经元死亡和梯度消失)。
它已被证明优于ReLU及其变体,如Leaky-ReLU(LReLU)和Parameterized-ReLU(PReLU)。与ReLU及其变体相比,使用ELU可在神经网络中缩短训练时间并提高准确度
GELU
GELU可以看做是RELU的一个平滑版本;GELU激活函数的最大特点是:将非线性与依赖输入数据分布的随机正则化器相结合在一个激活函数的表达中
在预训练语言模型中,GELU可以说是主流的激活函数;Bert,RoBERTa,ALBERT,GPT-2等顶尖的NLP预训练模型都是使用的GELU
bert中使用的激活函数,作者经过实验证明比relu等要好。原点可导,不会有Dead ReLU问题
与Relu和ELU比较如下
Softplus
Softplus函数类似于ReLU函数,但是相对较平滑,像ReLU一样是单侧抑制,它的接受范围很广
其对应的导数如下
优点:
- 作为relu的一个不错的替代选择,softplus能够返回任何大于0的值
- 与relu不同,softplus的导数是连续的、非零的,无处不在,从而防止出现死神经元
缺点:
- 导数常常小于1,也可能出现梯度消失的问题
- softplus另一个不同于 relu的地方在于其不对称性,不以零为中心,可能会妨碍学习
Maxout
等待…
Swish
将Sigmoid函数与线性函数的乘积作为激活函数,平衡了非线性和线性表达能力
Mish
Mish: A Self Regularized Non-Monotonic Neural Activation Function 2020
SoftSign
优点:
- softsign是 tanh激活函数的另一个替代选择
- softsign是反对称、去中心、可微分,并返回−1和1之间的值
- softsign更平坦的曲线与更慢的下降导数表明它可以更高效地学习
缺点:
- 导数的计算比tanh更麻烦
激活函数的选择
选择一个适合的激活函数并不容易,需要考虑很多因素,通常的做法是,如果不确定哪一个激活函数效果更好,可以把它们都试试,然后看看在验证集或者测试集上的效果
然后看哪一种表现的更好,就去使用它
以下是常见的选择情况:
- 如果输出是0、1值(二分类问题),则输出层选择Sigmoid函数,然后其它的所有单元都选择ReLU函数
- 如果在隐藏层上不确定使用哪个激活函数,那么通常会使用ReLU激活函数。有时,也会使用Tanh激活函数
- Sigmoid激活函数:除了输出层是一个二分类问题基本不会用它
- Tanh激活函数:Tanh是非常优秀的,几乎适合所有场合
- ReLU激活函数:最常用的默认函数,如果不确定用哪个激活函数,就使用ReLU或者Leaky ReLU,再去尝试其他的激活函数
- 如果遇到了一些死的神经元,我们可以使 Leaky ReLU函数