一、概述
在机器学习中,激活函数是神经网络中的一种函数,用于在神经网络的每个神经元中引入非线性。没有激活函数,神经网络就无法学习复杂的模式,因为线性变换的组合仍然是线性的。
在神经网络的每层中,将该层所有输入乘以其相应的权重加上总体偏差(y=kx+b的b对应的是偏差,k对应的是权重)的总和,作为激活函数的输入,而激活函数的输出则作为该层的输出。
在Keras中,激活函数可以通过设置单独的 Activation 层实现,也可以在构造层对象时通过传递 activation 参数实现。
例如:
from keras.layers import Activation, Dense
... ...
model.add(Dense(64))
model.add(Activation('tanh'))
最后2行代码等价于:model.add(Dense(64, activation='tanh'))
二、常见的激活函数
2.1、线性函数linear
线性激活函数其实不做任何处理,保持原值不变。在keras中函数定义:keras.activations.linear(x),可以直接在模型的层定义中省略激活参数达到同样效果。
2.2、整流线性单元relu
整流线性单元,简称为ReLU(Rectified Linear Unit,也称为修正线性单元)是目前深度学习中使用最广泛的激活函数之一,当输入大于0时,输出就是输入本身;当输入小于或等于0时,输出就是0,即ReLU对应函数为:f(x)=max(0,x)
ReLU特点:
- 计算简单;
- 减少梯度消失问题:由于ReLU在正区间内梯度恒定为1,这有助于缓解梯度消失问题;
- 稀疏激活:由于ReLU在输入小于或等于0时输出为0,这使得网络在任何时候都只有一部分神经元被激活,这种稀疏性可以提高计算效率;
- 神经元死亡:在训练过程中,如果输入持续为负,那么梯度将一直为0,导致这部分神经元不再更新,即所谓的“神经元死亡”;
- 不零中心:ReLU的输出总是非负的,这意味着它不将输出值零中心化,这可能会导致优化问题。
在Keras中ReLU定义有些优化:
定义:keras.activations.relu(x, alpha=0.0, max_value=None, threshold=0.0)
其中:x为输入张量,alpha为负数部分的斜率,max_value为输出的最大值,threshold为浮点数,是采用Thresholded激活时的阈值。
注:在计算机科学和机器学习中,张量通常被定义为一个多维数组,可以是任意阶的。在深度学习框架中,张量是数据的基本表示形式,可以进行各种数学运算。一个标量(0阶张量)是一个单一的数值,没有方向;一个向量(1阶张量)有一个方向;一个矩阵(2阶张量)有两个方向(行和列),…
使用默认值时,它与前面介绍的计算过程一致,返回逐元素的 max(x, 0)。否则计算过程如下:
- 如果 x >= max_value:f(x) = max_value
- 如果 threshold <= x <max_value:f(x) = x
- 否则:f(x) = alpha * (x - threshold)。
2.3、线性指数激活函数elu
elu是"Exponential Linear Unit"的缩写,翻译为中文是“指数线性单元”,ELU函数是一种激活函数,它试图解决ReLU函数的一些问题,特别是Dead ReLU问题。Dead ReLU问题指的是当输入为负数时,ReLU函数的梯度为0,导致一些神经元不再更新,即“死亡”。
Keras中elu函数定义: keras.activations.elu(x, alpha=1.0)
其中:x为输入张量,alpha:一个标量,表示负数部分的斜率。
线性指数激活elu的计算过程:如果 x > 0,返回值为 x;如果 x < 0 返回值为
a
l
p
h
a
∗
(
e
x
−
1
)
alpha * (e^x-1)
alpha∗(ex−1),即
e
l
u
(
x
)
=
{
x
if
x
>
0
α
∗
(
e
x
−
1
)
if
x
≤
0
elu(x) = \{ \begin{array}{ll} x & \text{if } x > 0 \\ \alpha * (e^x-1) & \text{if } x \leq 0 \end{array}
elu(x)={xα∗(ex−1)if x>0if x≤0
2.4、可伸缩指数线性单元SELU
SELU(Scaled Exponential Linear Unit)可伸缩的指数线性单元,是为了解决深度神经网络训练中的梯度消失和梯度爆炸问题而设计的。SELU具有自归一化的特性,即在适当的初始化条件下,网络的输出将自动地保持均值和方差接近于一个固定的值,通常是均值为0,方差为1。
SELU函数的数学表达式定义为:
S
E
L
U
(
x
)
=
s
c
a
l
e
×
{
x
if
x
>
0
a
l
p
h
a
∗
(
e
x
−
1
)
if
x
≤
0
SELU(x) = scale × \{ \begin{array}{ll} x & \text{if } x > 0 \\ alpha * (e^x-1) & \text{if } x \leq 0 \end{array}
SELU(x)=scale×{xalpha∗(ex−1)if x>0if x≤0
其中,alpha 和scale 是预定义的常数,scale为伸缩因子,alpha与线性指数激活函数elu含义相同。
SELU 激活函数的常量 alpha 和 scale 通常分别设为 1.67326324 和 1.05070098。这些值是根据特定的论文研究确定的,用于确保在网络层之间保持激活的均值和方差 。
由计算公式可知,可伸缩的指数线性激活:SELU(x) = scale * elu(x, alpha)。
SELU激活函数的输出在输入接近于0时接近于高斯分布。
SELU的特点包括:
- 自归一化:在训练过程中,它可以使网络的隐藏层输出的均值和方差保持在接近于1的水平
- 非线性:在输入为正数时,SELU近似于线性,而在输入为负数时,它具有指数增长的特性
- 适用性:它适用于输入的取值范围有一定的要求,通常在应用SELU时需要对输入进行归一化。
使用SELU时,通常需要配合特定的权重初始化方法(如Lecun正态分布初始化)以及输入数据的标准化。此外,如果使用dropout,应该使用AlphaDropout。只要正确初始化权重并且输入的数量足够大,选择合适的 alpha 和 scale 的值,就可以在两个连续层之间保留输入的均值和方差。
在实际应用中,SELU被证明可以加速深度网络的训练,并提高模型的性能。然而,它也有一些局限性,比如在某些复杂模型结构中可能不适用或效果不明显,且计算成本相对较高。
Keras中elu函数定义: keras.activations.selu(x)
其中:x为输入张量
注意:
- 与「lecun_normal」初始化方法一起使用
- 与 dropout 的变种「AlphaDropout」一起使用
2.5、softmax函数
softmax函数在中文中通常被称为“软最大函数”。它之所以被称为“软最大”,是因为它与“硬最大”(Hardmax)函数相对应。Hardmax函数会直接输出向量中最大值的位置,而Softmax函数则将输入的数值向量转换为一个概率分布,其中每个元素的值介于0到1之间,并且所有元素的总和为1。
从“软最大”和“硬最大”这个定义上看来,二者好像没有关联关系,但实际上“软”和“硬”在这里指的是函数的平滑性和输出的离散性。Softmax函数的“软”在于它输出的是概率分布,而不是硬最大函数的离散类别标签。
Softmax函数的计算过程如下:
- 指数化:首先对输入张量x中的每个元素计算指数,即 e x i ,其中 x i e^{x_i},其中 x_i exi,其中xi是张量x中的元素;
- 求和:然后对指数化后的张量求和。在Keras中,可以通过axis参数指定对哪个轴求和。axis=-1表示对最后一个轴(通常是类别维度)求和;
- 归一化:最后,将指数化后的张量中的每个元素除以上一步计算的总和,得到的结果就是softmax函数的输出。
Softmax函数数学公式表示为:
s
o
f
t
m
a
x
(
x
i
)
=
e
x
i
∑
j
e
x
j
softmax(x_i) = \frac{e^{x_i}}{\sum_{j} e^{x_j}}
softmax(xi)=∑jexjexi
其中, x i x_i xi是输入向量中的第i个元素,分母是对所有输入元素指数的总和。
Keras中Softmax函数定义: keras.activations.softmax(x, axis=-1)
- 参数:x为输入张量,axis为整数,代表 softmax 所作用的维度
- 返回:softmax 变换后的张量
- 异常:ValueError:如果 dim(x) == 1。
2.6、softplus函数
Softplus 函数在中文中通常被称为“软加函数”,它之所以被称为“软加”,是因为它在数学形式上是 ReLU(Rectified Linear Unit,线性整流单元)函数的平滑版本。
Softplus 函数定义如下: Softplus ( x ) = ln ( 1 + e x ) \text{Softplus}(x) = \ln(1 + e^x) Softplus(x)=ln(1+ex)
Softplus 函数与 ReLU 函数的主要区别在于它在整个实数域上都是平滑且连续可导的,而 ReLU 函数在 x = 0 处不可导,并且在 x < 0时其导数为 0。Softplus 函数在 x < 0时也有非零的输出,这有助于保留更多的梯度信息,从而可以避免 ReLU 函数在负数区域上出现的梯度消失问题。此外,Softplus 函数的输出总是正值,这使得它在某些深度学习应用中比 ReLU 更受青睐。
Softplus 函数被认为是 ReLU(Rectified Linear Unit)激活函数的一个平滑版本,原因如下:
- 形式上的相似性
ReLU 函数定义为:ReLU(x)=max(0,x),Softplus 函数定义为: S o f t p l u s ( x ) = l n ( 1 + e x ) Softplus(x)=ln(1+e ^x) Softplus(x)=ln(1+ex)
当观察 Softplus 函数时,可以发现当 x 为正数且 x 的值越来越大时,Softplus(x) 趋近于 x,这与 ReLU 函数的行为相似。 - 平滑性
ReLU 函数在 x = 0 处不可导,因为其导数从 0 突变到 1;
而Softplus 函数在整个定义域上都是可导的,其导数是连续的,这使得 Softplus 比 ReLU 更平滑。 - 非线性特性
ReLU 提供了非线性特性,但在 x≤0 时其输出为 0,这意味着在负半轴上没有激活(称为死亡 ReLU 问题);
而Softplus 函数在 x≤0 时仍然有激活,虽然很小,但避免了 ReLU 的死亡问题。 - 梯度特性
ReLU 在x>0 时梯度值为 1(x的导数为1),在x≤0 时梯度值为 0(常数的导数为0)。
Softplus 的梯度在 x = 0x=0 附近是正的且非零,随着 xx 的增加,梯度逐渐增加,这有助于缓解梯度消失问题。 - 数学性质
Softplus 可以看作是 ReLU 后接一个归一化指数函数 ln ( 1 + e x ) \ln(1 + e^x) ln(1+ex),这种形式的添加使得 Softplus 在 x 接近 0 时有一个小的非零斜率,这与 ReLU 在 x 为正时的行为相似,但在整个定义域上都是平滑的。 - 近似关系
当 x 非常大时,Softplus(x) 近似于 x,这与 ReLU 的线性部分相同。
由于这些特性,Softplus 可以被看作是 ReLU 的平滑版本,它在保持 ReLU 优点的同时,通过平滑性质改善了梯度消失问题,并在整个定义域上提供了连续的梯度。这使得 Softplus 在某些深度学习应用中比 ReLU 更受青睐。
Keras中softplus函数定义: keras.activations.softplus(x)
- 参数:x为输入张量
- 返回:softplus 变换后的张量
2.7、softsign函数
Softsign 函数在中文中通常被称为“软签名函数”,Softsign 函数的定义是:
Softsign
(
x
)
=
x
1
+
∣
x
∣
\text{Softsign}(x) = \frac{x}{1 + |x|}
Softsign(x)=1+∣x∣x
这个函数尝试模拟一种平滑的决策过程,其中输入值 x被归一化,使其输出值在 -1 到 1 之间。Softsign 函数之所以被称为“软签名”,是因为它在正负值之间是连续且平滑的,这里的“软”指的是函数的平滑性质,这与“硬签名”函数(又称为阶梯)函数在某些点有跳跃的函数形成对比,后者可以被视为“硬”函数。
硬签名函数是指返回变量符号的函数:
Hardsign
(
x
)
=
{
1
if
x
>
0
0
if
x
=
0
−
1
if
x
<
0
\text{Hardsign}(x) = \begin{cases} 1 & \text{if } x > 0 \\ 0 & \text{if } x = 0 \\ -1 & \text{if } x < 0 \end{cases}
Hardsign(x)=⎩
⎨
⎧10−1if x>0if x=0if x<0
Softsign 函数的特点包括:
- 平滑性:在整个实数域上都是连续且可微的
- 归一化:输出值被归一化到 -1 到 1 的范围内
- 对称性:函数关于原点对称。
Softsign 函数在神经网络中使用较少,但它的特性使其在某些情况下可能是一个有用的激活函数。
Keras中softsign函数定义: keras.activations.softsign(x)
- 参数:x为输入张量
- 返回:softsign 变换后的张量
2.8、sigmoid函数
sigmoid 函数在中文中通常被称为“Sigmoid 函数”或者“逻辑函数”,它是一种将任意实数映射到 (0,1) 区间的激活函数,因此经常用于二分类问题中,输出数据解释为概率。
Sigmoid 函数的数学表达式为:
σ
(
x
)
=
1
1
+
e
−
x
σ(x) = \frac{1}{1 + e^{-x}}
σ(x)=1+e−x1
之所以命名为“Sigmoid”,是因为其图形呈“S”形曲线,类似字母“S”。这种曲线也被称为逻辑曲线(Logistic Curve),因为在逻辑回归中经常使用它来将线性回归的输出转换为概率值。这也是它有时被称为“Logistic 函数”的原因。
Keras中sigmoid函数定义: keras.activations.sigmoid(x)
- 参数:x为输入张量
- 返回:sigmoid 变换后的张量
2.9、hard_sigmoid函数
Hard Sigmoid 函数的中文名称通常被称为“硬sigmoid”激活函数,之所以被称为“硬sigmoid”,是因为它模仿了 Sigmoid 函数的形状,但是使用了一种分段线性的方式,这使得它的计算更加快速和简单。
Hard Sigmoid 函数的数学表达式为:
Hard Sigmoid
(
x
)
=
{
0
if
x
<
−
2.5
1
if
x
>
2.5
0.2
x
+
0.5
−
2.5
≤
x
≤
2.5
\text{Hard Sigmoid}(x) = \begin{cases} 0 & \text{if } x < -2.5 \\ 1 & \text{if } x > 2.5 \\ 0.2x + 0.5 & -2.5 \leq x \leq 2.5\end{cases}
Hard Sigmoid(x)=⎩
⎨
⎧010.2x+0.5if x<−2.5if x>2.5−2.5≤x≤2.5
Keras中hard_sigmoid函数定义: keras.activations.hard_sigmoid(x)
- 参数:x为输入张量
- 返回:hard_sigmoid 变换后的张量
2.10、自然数指数激活函数exponential
自然数指数激活函数指的是形如 f ( x ) = e x f(x) = e^x f(x)=ex 的函数,这种激活函数在某些特定的神经网络应用中使用,尤其是在处理具有非常广泛值域的数据时。
作用:
- 非线性变换:指数激活函数提供了一种非线性变换,这对于神经网络来说是必要的,因为只有非线性激活函数才能让神经网络学习复杂的函数映射
- 正输出:指数激活函数的输出总是正的
- 处理极端值:它能够处理非常大或非常小的输入值,因为指数函数可以迅速增长到非常大的值,或者接近于0
- 平滑梯度:指数激活函数在整个定义域内都有非零的导数,这意味着梯度不会消失,有助于神经网络的学习
应用场景:
- 处理极端值:在某些情况下,输入数据的值可能非常大或非常小,指数激活函数可以帮助处理这些极端值
- 生成模型:在生成模型中,如变分自编码器(VAEs)中,指数激活函数可以用于参数化概率分布
- 强化学习:在强化学习中,某些策略梯度方法可能会使用指数激活函数
- 生物神经网络:在模拟生物神经网络的某些模型中,指数激活函数可以模拟神经元的激活特性。
局限性:
- 数值稳定性:指数激活函数可能会导致数值稳定性问题,因为对于大的输入值, 可能会非常大,导致数值溢出
- 梯度消失:尽管指数激活函数在整个定义域内都有非零的导数,但对于非常大的负输入值,输出接近于0,这可能导致梯度消失问题
- 输出范围:指数激活函数的输出范围是 (0,∞),这可能不适合所有类型的任务,特别是那些需要输出值在特定范围内的任务。
在实际应用中,指数激活函数的使用相对较少,因为它的输出值可能会非常大,导致数值计算问题。然而,在需要处理极端值或需要正输出值的情况下,它仍然是一种有用的激活函数。
Keras中exponential函数定义: keras.activations.exponential(x)
- 参数:x为输入张量
- 返回:exponential 变换后的张量
2.11、双曲正切激活函数tanh
双曲正切激活函数(tanh)是神经网络中常用的激活函数之一,它的形状类似于S型曲线,但输出值被压缩到了-1到1的范围内。这种激活函数对于输出值的正负有很好的区分度,并且输出值的中心点在0附近,这有助于减少梯度消失的问题。
双曲正切激活函数之所以被称为“双曲正切”(Hyperbolic Tangent),是因为它基于双曲函数的数学概念。双曲函数是三角函数的一种推广,它们在数学和物理学中有广泛的应用。
双曲函数的基本概念:双曲函数与三角函数类似,但它们的定义基于双曲线而不是圆。常见的双曲函数包括:
- 双曲正弦(sinh): sinh ( x ) = e x − e − x 2 \sinh(x) = \frac{e^x - e^{-x}}{2} sinh(x)=2ex−e−x
- 双曲余弦(cosh): cosh ( x ) = e x + e − x 2 \cosh(x) = \frac{e^x + e^{-x}}{2} cosh(x)=2ex+e−x
- 双曲正切(tanh): tanh ( x ) = sinh ( x ) cosh ( x ) = e x − e − x e x + e − x \tanh(x) = \frac{\sinh(x)}{\cosh(x)} = \frac{e^x - e^{-x}}{e^x + e^{-x}} tanh(x)=cosh(x)sinh(x)=ex+e−xex−e−x
双曲正切函数的导数为: tanh ′ ( x ) = 4 ( e x + e − x ) 2 \tanh'(x) = \frac{4}{(e^x + e^{-x})^2} tanh′(x)=(ex+e−x)24
双曲正切的特点:
- 输出范围:输出值在-1到1之间,这使得它在某些情况下比Sigmoid函数更受欢迎,因为其输出值更接近于0,有助于减少输出值的均值,从而可能减少梯度消失的问
- 零中心化:tanh函数的输出值以0为中心,这意味着其输出的平均值接近于0,这在某些类型的神经网络中是有利的
- 非线性:它是一个非线性函数,可以用于将线性函数映射到非线性函数,这是神经网络能够解决复杂问题的关键
- 梯度:在输入值接近0时,tanh函数的梯度接近1,而在输入值远离0时,梯度接近0,这可能会导致梯度消失问题,尤其是在深层网络中。
Keras中tanh函数定义: keras.activations.tanh(x)
- 参数:x为输入张量
- 返回:tanh 变换后的张量
三、小结
在机器学习中,激活函数是神经网络中的一种函数,用于在神经网络的每个神经元中引入非线性。没有激活函数,神经网络就无法学习复杂的模式,因为线性变换的组合仍然是线性的。在Keras中,激活函数可以通过设置单独的 Activation 层实现,也可以在构造层对象时通过传递 activation 参数实现。本文介绍了11个激活函数,包括线性函数linear、线性指数激活函数elu、整流线性单元relu、可伸缩指数线性单元SELU、softmax函数、softplus函数、softsign函数、sigmoid函数、hard_sigmoid函数、自然数指数激活函数exponential、双曲正切激活函数tanh,详细介绍了这些函数的功能以及在keras中的定义。
keras中激活函数的介绍请参考官方文档的介绍。
更多人工智能知识学习请关注专栏《零基础机器学习入门》后续的文章。
更多人工智能知识学习过程中可能遇到的疑难问题及解决办法请关注专栏《机器学习疑难问题集》后续的文章。
写博不易,敬请支持:
如果阅读本文于您有所获,敬请点赞、评论、收藏,谢谢大家的支持!
关于老猿的付费专栏
- 付费专栏《https://blog.csdn.net/laoyuanpython/category_9607725.html 使用PyQt开发图形界面Python应用》专门介绍基于Python的PyQt图形界面开发基础教程,对应文章目录为《 https://blog.csdn.net/LaoYuanPython/article/details/107580932 使用PyQt开发图形界面Python应用专栏目录》;
- 付费专栏《https://blog.csdn.net/laoyuanpython/category_10232926.html moviepy音视频开发专栏 )详细介绍moviepy音视频剪辑合成处理的类相关方法及使用相关方法进行相关剪辑合成场景的处理,对应文章目录为《https://blog.csdn.net/LaoYuanPython/article/details/107574583 moviepy音视频开发专栏文章目录》;
- 付费专栏《https://blog.csdn.net/laoyuanpython/category_10581071.html OpenCV-Python初学者疑难问题集》为《https://blog.csdn.net/laoyuanpython/category_9979286.html OpenCV-Python图形图像处理 》的伴生专栏,是笔者对OpenCV-Python图形图像处理学习中遇到的一些问题个人感悟的整合,相关资料基本上都是老猿反复研究的成果,有助于OpenCV-Python初学者比较深入地理解OpenCV,对应文章目录为《https://blog.csdn.net/LaoYuanPython/article/details/109713407 OpenCV-Python初学者疑难问题集专栏目录 》
- 付费专栏《https://blog.csdn.net/laoyuanpython/category_10762553.html Python爬虫入门 》站在一个互联网前端开发小白的角度介绍爬虫开发应知应会内容,包括爬虫入门的基础知识,以及爬取CSDN文章信息、博主信息、给文章点赞、评论等实战内容。
前两个专栏都适合有一定Python基础但无相关知识的小白读者学习,第三个专栏请大家结合《https://blog.csdn.net/laoyuanpython/category_9979286.html OpenCV-Python图形图像处理 》的学习使用。
对于缺乏Python基础的同仁,可以通过老猿的免费专栏《https://blog.csdn.net/laoyuanpython/category_9831699.html 专栏:Python基础教程目录)从零开始学习Python。
如果有兴趣也愿意支持老猿的读者,欢迎购买付费专栏。