激活函数大汇总(五)(Hard Sigmoid & Hard Tanh附代码和详细公式)
更多激活函数见激活函数大汇总列表
一、引言
欢迎来到我们深入探索神经网络核心组成部分——激活函数的系列博客。在人工智能的世界里,激活函数扮演着不可或缺的角色,它们决定着神经元的输出,并且影响着网络的学习能力与表现力。鉴于激活函数的重要性和多样性,我们将通过几篇文章的形式,本篇详细介绍两种激活函数,旨在帮助读者深入了解各种激活函数的特点、应用场景及其对模型性能的影响。
在接下来的文章中,我们将逐一探讨各种激活函数,从经典到最新的研究成果。
限于笔者水平,对于本博客存在的纰漏和错误,欢迎大家留言指正,我将不断更新。
二、Hard Sigmoid
Hard Sigmoid激活函数是Sigmoid激活函数的一个简化版本,旨在提供一个计算上更高效的非线性函数。通过近似Sigmoid函数的形状,Hard Sigmoid在保持一定非线性的同时,简化了计算过程,特别适用于计算资源受限的环境。
1. 数学定义
Hard Sigmoid函数通常定义为:
HardSigmoid
(
x
)
=
max
(
0
,
min
(
1
,
x
a
+
1
2
)
)
\operatorname{HardSigmoid}(x)=\max \left(0, \min \left(1, \frac{x}{a}+\frac{1}{2}\right)\right)
HardSigmoid(x)=max(0,min(1,ax+21))
其中,
x
x
x是函数的输入,
a
a
a是一个控制函数斜率的正常数(在很多实现中,
a
a
a常取值为5)。这个定义确保了Hard Sigmoid的输出值被限制在0和1之间。
2. 函数特性
- 计算简单:与传统的Sigmoid函数相比,Hard Sigmoid通过线性函数和限制操作简化了计算,减少了计算资源的消耗。
- 输出限制:Hard Sigmoid的输出被限制在[0, 1]范围内,与Sigmoid函数相似,但是通过一个分段线性函数实现。
- 近似非线性:尽管Hard Sigmoid是通过分段线性函数实现的,它仍然提供了一种非线性的近似,适用于需要非线性激活但又对计算效率有要求的场景。
3. 导数
Hard Sigmoid函数的导数在其线性部分为常数,具体表达式为:
HardSigmoid
′
(
x
)
=
{
0
if
x
≤
−
a
2
or
x
≥
a
2
1
a
if
−
a
2
<
x
<
a
2
\operatorname{HardSigmoid}^{\prime}(x)= \begin{cases}0 & \text { if } x \leq-\frac{a}{2} \text { or } x \geq \frac{a}{2} \\ \frac{1}{a} & \text { if }-\frac{a}{2}<x<\frac{a}{2}\end{cases}
HardSigmoid′(x)={0a1 if x≤−2a or x≥2a if −2a<x<2a
这表明Hard Sigmoid在输入值绝对值较大时梯度为0,在输入值处于中间区域时梯度为一个固定常数
(
1
a
)
\left(\frac{1}{a}\right)
(a1)。
4. 使用场景与局限性
使用场景:
- 嵌入式系统和移动设备:在计算资源受限的环境中,如嵌入式系统和移动设备,Hard Sigmoid因其计算效率而被广泛使用。
- 大规模深度学习训练:在需要快速原型或大规模训练时,Hard Sigmoid可以作为一种计算成本较低的激活函数选项。
局限性:
- 非线性近似:作为Sigmoid函数的近似,Hard Sigmoid不能完全捕捉到Sigmoid的平滑非线性特性,这可能在某些任务中影响模型的性能。
- 梯度消失:尽管Hard Sigmoid在其线性部分有固定的非零梯度,但在输入值较大或较小时梯度仍然为0,这可能导致梯度消失问题。
Hard Sigmoid激活函数提供了一种在计算资源受限情况下实现快速、有效计算的方法,尽管它牺牲了一些非线性的精确表达。在实际应用中,选择使用Hard Sigmoid还是其他激活函数需根据具体任务的需求和计算资源的可用性来决定。
5.代码实现
import numpy as np
def hard_sigmoid(x):
"""计算Hard Sigmoid激活函数的值。
参数:
x -- 输入值,可以是一个数值、NumPy数组或者多维数组。
返回:
Hard Sigmoid激活后的结果。
"""
return np.clip((x / 5.0) + 0.5, 0, 1)
解读
- 函数实现:这个
hard_sigmoid
函数首先将输入x
除以5(即(a=5)),然后加上0.5,最后使用np.clip
函数将结果限制在0和1之间。这种实现直接对应于Hard Sigmoid函数的数学定义。 np.clip
的使用:np.clip
函数用于将数组中的元素限制在给定的一个范围内。在这里,它被用来确保Hard Sigmoid函数的输出值在0和1之间,这符合函数的期望输出范围。- 向量化操作:通过使用NumPy,这个实现自然地支持向量化操作,这意味着
hard_sigmoid
函数可以直接作用于整个NumPy数组,而不需要显式的循环。这在处理大量数据时非常有用,可以显著提高计算效率。
示例使用
下面展示了如何使用hard_sigmoid
函数来计算一组输入值的Hard Sigmoid激活:
x = np.array([-5, -2.5, 0, 2.5, 5])
hard_sigmoid_values = hard_sigmoid(x)
print("Hard Sigmoid Values:", hard_sigmoid_values)
这段代码首先定义了一个包含正负值的NumPy数组x
,然后使用hard_sigmoid
函数计算每个元素的Hard Sigmoid激活值。
三、Hard Tanh
Hard Tanh(Hard Hyperbolic Tangent)激活函数是双曲正切(Tanh)激活函数的一个简化版本,设计为在计算效率和实现简便性方面对原始Tanh函数进行优化。通过对Tanh函数的输出进行近似,Hard Tanh提供了一种在深度学习模型中实现快速非线性激活的方式。
1. 数学定义
Hard Tanh函数通常定义为:
HardTanh
(
x
)
=
max
(
−
1
,
min
(
1
,
x
)
)
\operatorname{HardTanh}(x)=\max (-1, \min (1, x))
HardTanh(x)=max(−1,min(1,x))
这个定义意味着输入值
x
x
x被限制在([-1, 1])的范围内。如果
x
x
x小于-1,函数输出-1;如果(x)大于1,函数输出1;如果
x
x
x在([-1, 1])内,函数输出
x
x
x本身。
2. 函数特性
- 简单高效:与Tanh相比,Hard Tanh因其计算上的简洁性而在特定应用中更高效,尤其是在硬件资源有限的情况下。
- 分段线性:Hard Tanh是一个分段线性函数,这使得它在实现上非常直接且易于优化。
- 饱和性:Hard Tanh在其输入的绝对值超过1时饱和,与Tanh函数类似,这种饱和性能够限制激活函数的输出范围。
3. 导数
Hard Tanh函数的导数为:
HardTanh
′
(
x
)
=
{
0
if
x
<
−
1
or
x
>
1
1
if
−
1
≤
x
≤
1
\operatorname{HardTanh}^{\prime}(x)= \begin{cases}0 & \text { if } x<-1 \text { or } x>1 \\ 1 & \text { if }-1 \leq x \leq 1\end{cases}
HardTanh′(x)={01 if x<−1 or x>1 if −1≤x≤1
这意味着当输入
x
x
x的绝对值小于或等于1时,Hard Tanh函数的梯度为1;否则,梯度为0。
4. 使用场景与局限性
使用场景:
- 资源受限的设备:在嵌入式系统或移动设备等计算资源受限的环境中,Hard Tanh可以作为一种有效的非线性激活函数。
- 快速原型和大规模训练:在需要快速模型原型或处理大量数据的场景中,Hard Tanh由于其简单和高效性,常被选用以加速训练过程。
局限性:
- 非连续梯度:Hard Tanh在输入绝对值为1时的导数不连续,这可能在某些情况下影响模型的学习效率。
- 激活饱和:和Tanh函数一样,Hard Tanh在输入的绝对值大于1时会出现激活饱和,可能导致梯度消失问题,特别是在深层网络中。
Hard Tanh激活函数因其计算简单和执行高效而在特定场景下非常有用,但选择使用Hard Tanh还是其他激活函数需要根据具体任务的需求和模型的特点来决定。
5.代码实现
import numpy as np
def hard_tanh(x):
"""计算Hard Tanh激活函数的值。
参数:
x -- 输入值,可以是一个数值、NumPy数组或者多维数组。
返回:
Hard Tanh激活后的结果。
"""
return np.clip(x, -1, 1)
解读
-
使用
np.clip
:这个实现中,np.clip
函数用于将输入值x
限制在-1
和1
之间。这是Hard Tanh函数的核心,直接对应其数学定义。np.clip
函数的第一个参数是输入数组,第二个和第三个参数分别是需要被限制的最小值和最大值。 -
向量化操作:通过使用NumPy,这个
hard_tanh
实现自然支持向量化操作。这意味着它可以高效地对单个数值、一维数组或多维数组进行操作,而无需显式循环遍历数组中的每个元素。这对于处理大规模数据集时提高计算效率非常有用。
示例使用
下面是如何使用hard_tanh
函数来计算一组输入值的Hard Tanh激活:
x = np.array([-2, -1, 0, 1, 2])
hard_tanh_values = hard_tanh(x)
print("Hard Tanh Values:", hard_tanh_values)
这段代码定义了一个包含正负值的NumPy数组x
,然后使用hard_tanh
函数计算每个元素的Hard Tanh激活值。
四、参考文献
Hard Tanh
- Courbariaux, M., Bengio, Y., & David, J.-P. (2015). “BinaryConnect: Training Deep Neural Networks with binary weights during propagations.” In Advances in Neural Information Processing Systems. 这篇论文虽然主要关注二值权重的网络,但在讨论网络激活函数时,Hard Tanh作为一种激活函数选项被提及,特别是在资源受限的环境下。