激活函数大汇总(二)(ELU&SELU附代码和详细公式)
更多激活函数见激活函数大汇总列表
一、引言
欢迎来到我们深入探索神经网络核心组成部分——激活函数的系列博客。在人工智能的世界里,激活函数扮演着不可或缺的角色,它们决定着神经元的输出,并且影响着网络的学习能力与表现力。鉴于激活函数的重要性和多样性,我们将通过几篇文章的形式,本篇详细介绍两种激活函数,旨在帮助读者深入了解各种激活函数的特点、应用场景及其对模型性能的影响。
在接下来的文章中,我们将逐一探讨各种激活函数,从经典到最新的研究成果。
限于笔者水平,对于本博客存在的纰漏和错误,欢迎大家留言指正,我将不断更新。
二、ELU
ELU(Exponential Linear Unit)激活函数是深度学习中用于增强网络学习能力的又一种激活函数,由Djork-Arné Clevert, Thomas Unterthiner, and Sepp Hochreiter在2015年提出。ELU通过在负值输入时提供负值输出,旨在结合ReLU的优点和解决其潜在的一些问题,如ReLU的不活跃神经元问题。
1.数学定义
ELU函数的数学表达式定义为:
ELU
(
x
)
=
{
x
if
x
>
0
α
(
e
x
−
1
)
if
x
≤
0
\operatorname{ELU}(x)= \begin{cases}x & \text { if } x>0 \\ \alpha\left(e^x-1\right) & \text { if } x \leq 0\end{cases}
ELU(x)={xα(ex−1) if x>0 if x≤0
其中,
x
x
x是函数的输入,
α
α
α是一个预定义的超参数,用于控制
x
x
x为负值时输出的饱和度。
2.函数特性
- 非线性:ELU是非线性的,可以帮助神经网络学习复杂的数据表示。
- 连续可导:ELU在整个定义域内连续可导,这有助于提高梯度下降优化算法的稳定性。
- 解决梯度消失问题:对于负值输入,ELU提供了负值输出,这有助于减轻梯度消失问题,尤其是在深层网络中。
- 输出均值接近0:ELU函数能够产生负值输出,这意味着其激活输出的均值更接近0,有助于数据的中心化,减少训练过程中的偏置偏移。
3.导数
ELU函数的导数(或梯度)如下:
E
L
U
′
(
x
)
=
{
1
if
x
>
0
α
e
x
if
x
≤
0
\mathrm{ELU}^{\prime}(x)= \begin{cases}1 & \text { if } x>0 \\ \alpha e^x & \text { if } x \leq 0\end{cases}
ELU′(x)={1αex if x>0 if x≤0
这意味着在正数区域,梯度为1,而在负数区域,梯度取决于
α
α
α和
x
x
x的指数,这有助于保持负输入值的梯度更新。
4.使用场景与局限性
ELU因其改进的性能和减少梯度消失问题的能力而受到青睐,特别是在深层网络中。然而,与ReLU相比,ELU在负值区域的指数运算增加了计算成本。在实践中,选择ELU还是其他激活函数(如ReLU及其变体)通常取决于特定应用的性能和计算资源的权衡。
优势
- 减轻梯度消失问题:对于负值输入,ELU提供了一个非零的负饱和区域,这有助于减轻梯度消失问题,从而改善深层网络的训练效率。
- 输出均值接近于零:ELU函数的输出均值接近于零,这有助于加速学习过程,因为它使得网络层的输入分布更加稳定。
- 连续可导:ELU是在其整个定义域内连续可导的,这有助于优化算法的稳定性和效率。
缺点
- 计算成本:由于ELU在负值时涉及指数运算,其计算成本高于ReLU及其直接变体,尤其是在前向传播时。
5.代码实现
实现ELU(Exponential Linear Unit)激活函数的Python代码相对简单,可以利用NumPy库来处理数学运算。以下是ELU函数及其导数的具体实现:
import numpy as np
def elu(x, alpha=1.0):
"""计算ELU激活函数的值。
参数:
x -- 输入值,可以是一个数值、NumPy数组或者多维数组。
alpha -- 控制负值饱和度的超参数,默认为1.0。
返回:
ELU激活后的结果。
"""
return np.where(x > 0, x, alpha * (np.exp(x) - 1))
def elu_derivative(x, alpha=1.0):
"""计算ELU函数的导数。
参数:
x -- 输入值,可以是一个数值、NumPy数组或者多维数组。
alpha -- 控制负值饱和度的超参数,默认为1.0。
返回:
ELU导数的结果。
"""
return np.where(x > 0, 1, alpha * np.exp(x))
解读
-
elu(x, alpha=1.0)
函数:此函数根据ELU的定义计算激活值。对于输入x
中的每个元素,如果它大于0,函数直接返回该元素的值。如果元素小于或等于0,函数计算alpha * (np.exp(x) - 1)
。这里,np.exp(x)
计算(e^x),alpha
是一个超参数,控制负值输入的输出饱和度。 -
elu_derivative(x, alpha=1.0)
函数:这个函数计算ELU的导数。对于正值输入,导数为1;对于负值输入,导数是alpha * np.exp(x)
。这意味着在负数区域,导数取决于输入x
的指数乘以alpha
。
示例使用
假设你想计算一个输入数组x
的ELU激活值及其导数:
x = np.array([-2, -1, 0, 1, 2])
elu_values = elu(x)
elu_derivatives = elu_derivative(x)
print("ELU Values:", elu_values)
print("ELU Derivatives:", elu_derivatives)
这段代码计算了x
中每个元素的ELU激活值和导数。通过这样的实现,ELU激活函数及其导数可以很容易地集成到深度学习模型中,提供对梯度消失问题的一种解决方案,并帮助模型学习复杂的非线性关系。
三、SELU
SELU(Scaled Exponential Linear Unit)激活函数是一种自归一化的激活函数,由Klambauer等人在2017年提出。SELU设计用于在前向传播和反向传播时保持神经网络层的输出近似保持零均值和单位方差,从而解决深层网络训练过程中的梯度消失和梯度爆炸问题。SELU通过特定的缩放系数自动调整神经网络的权重,使得网络能够自我归一化。
1.数学定义
SELU函数的数学表达式定义为:
SELU
(
x
)
=
λ
{
x
if
x
>
0
α
(
e
x
−
1
)
if
x
≤
0
\operatorname{SELU}(x)=\lambda \begin{cases}x & \text { if } x>0 \\ \alpha\left(e^x-1\right) & \text { if } x \leq 0\end{cases}
SELU(x)=λ{xα(ex−1) if x>0 if x≤0
其中,
x
x
x是函数的输入。与ELU相似,
a
a
a和
λ
\lambda
λ是预定义的缩放参数,用于确保自归一化属性。在原始论文中,
α
≈
1.6732632423543772848170429916717
\alpha \approx 1.6732632423543772848170429916717
α≈1.6732632423543772848170429916717,
λ
≈
1.0507009873554804934193349852946
\lambda \approx 1.0507009873554804934193349852946
λ≈1.0507009873554804934193349852946,这些值被特别设计来保持输入数据的均值和方差在一定范围内。
2.函数特性
- 自归一化性质:SELU激活函数的最大特点是其自归一化性能,这有助于控制深层神经网络中的信息流,使得网络层的激活输出自动保持在零均值和单位方差。
- 连续可导:SELU在整个定义域内连续可导,有利于优化算法的稳定性和效率。
- 解决梯度问题:SELU旨在通过其自归一化性质解决梯度消失和梯度爆炸的问题,这对于深层神经网络的训练非常重要。
3.导数
SELU函数的导数(或梯度)如下:
SELU
′
(
x
)
=
λ
{
1
if
x
>
0
α
e
x
if
x
≤
0
\operatorname{SELU}^{\prime}(x)=\lambda \begin{cases}1 & \text { if } x>0 \\ \alpha e^x & \text { if } x \leq 0\end{cases}
SELU′(x)=λ{1αex if x>0 if x≤0
这表示在正数区域,梯度由
λ
\lambda
λ缩放;而在负数区域,梯度由
λ
\lambda
λ和
α
e
x
\alpha e^x
αex共同决定。
4.使用场景与局限性
SELU因其在自归一化网络中的优异性能而受到关注,特别适合解决深层前馈神经网络的训练问题。然而,SELU的成功依赖于一系列条件,包括权重初始化方法(推荐使用Lecun正态分布初始化)、输入数据的标准化,以及网络结构必须是密集连接的。在实践中,当这些条件得到满足时,SELU可以显著提高网络的训练速度和性能。
优势
- 自归一化属性:SELU的最大优点是它能够使得网络自动地归一化,维持激活输出的均值和方差在一定范围内。这有助于防止梯度消失或爆炸问题,使得深层网络训练更加稳定。
- 改善深度网络训练:由于其自归一化特性,SELU在一些深度网络结构中,特别是那些难以使用批量归一化的结构中,展示了优越的性能。
- 无需额外的归一化技术:使用SELU可以减少或消除对批量归一化等额外归一化技术的需求,简化模型结构和训练过程。
缺点
- 条件限制:SELU的自归一化属性依赖于特定的初始化方法和网络结构(如顺序模型),在某些复杂模型结构中可能不适用或效果不明显。
- 计算成本:类似于ELU,SELU在处理负值输入时也涉及指数运算,因此计算成本较高。
5.代码实现
import numpy as np
def selu(x, lambda_=1.0507, alpha_=1.6733):
"""计算SELU激活函数的值。
参数:
x -- 输入值,可以是一个数值、NumPy数组或者多维数组。
lambda_ -- 缩放参数,默认为1.0507。
alpha_ -- 负斜率系数,默认为1.6733。
返回:
SELU激活后的结果。
"""
return np.where(x > 0, lambda_ * x, lambda_ * (alpha_ * np.exp(x) - alpha_))
解读
selu(x, lambda_=1.0507, alpha_=1.6733)
函数:这个函数根据SELU的定义来计算激活值。对于输入x
中的每个元素,如果它大于0,函数返回lambda_ * x
。如果元素小于或等于0,函数计算lambda_ * (alpha_ * np.exp(x) - alpha_)
。参数lambda_
和alpha_
是根据原论文推荐的值设置的,旨在促进自归一化的属性。
示例使用
x = np.array([-3, -1, 0, 1, 3])
selu_values = selu(x)
print("SELU Values:", selu_values)
这段代码将计算并打印出数组x
中每个元素的SELU激活值。通过使用SELU激活函数,神经网络特别是深层神经网络可以维持较稳定的激活分布,有助于改善训练过程中的梯度流动,并提高训练稳定性和效率。
四、参考文献
ELU (Exponential Linear Unit)
- Clevert, D.-A., Unterthiner, T., & Hochreiter, S. (2015). “Fast and Accurate Deep Network Learning by Exponential Linear Units (ELUs).” arXiv preprint arXiv:1511.07289. 这篇论文首次介绍了ELU激活函数,并且展示了它在加速深度网络学习和提高准确性方面的优势。
SELU (Scaled Exponential Linear Unit)
- Klambauer, G., Unterthiner, T., Mayr, A., & Hochreiter, S. (2017). “Self-Normalizing Neural Networks.” In Advances in Neural Information Processing Systems (NIPS). 这篇论文提出了SELU激活函数,它是专门为自归一化神经网络设计的,能够在某些条件下自动达到近似的单位方差和零均值,从而帮助改善深度学习模型的训练过程。