激活函数
激活函数通过 引入非线性来增强神经网络的表达能力,对于解决线性模型的局限性至关重要。由于反向传播算法(BP)用于更新网络参数,因此 激活函数必须是可微的,也就是说能够求导的。
1.sigmoid函数
Sigmoid激活函数是一种常见的非线性激活函数,特别是在早期神经网络中应用广泛。它将输入映射到0到1之间的值,因此非常适合处理概率问题。

1.1 公式
Sigmoid函数的数学表达式为:
f
(
x
)
=
σ
(
x
)
=
1
1
+
e
−
x
f(x) = \sigma(x) = \frac{1}{1 + e^{-x}}
f(x)=σ(x)=1+e−x1
其中
e
e
e是自然常数(约等于2.718),
x
x
x 是输入。
1.2 特征
-
将任意实数输入映射到 (0, 1)之间,因此非常适合处理概率场景。
-
sigmoid函数一般只用于二分类的输出层。
-
微分性质: 导数计算比较方便,可以用自身表达式来表示:
σ ′ ( x ) = σ ( x ) ⋅ ( 1 − σ ( x ) ) \sigma'(x)=\sigma(x)\cdot(1-\sigma(x)) σ′(x)=σ(x)⋅(1−σ(x))
1.3 缺点
-
- 梯度消失:
- 在输入非常大或非常小时,Sigmoid函数的梯度会变得非常小,接近于0。这导致在反向传播过程中,梯度逐渐衰减。
- 最终使得早期层的权重更新非常缓慢,进而导致训练速度变慢甚至停滞。
-
- 信息丢失:输入100和输入10000经过sigmoid的激活值几乎都是等于 1 的,但是输入的数据却相差 100 倍。
-
- 计算成本高: 由于涉及指数运算,Sigmoid的计算比ReLU等函数更复杂,尽管差异并不显著。
2 tanh
tanh(双曲正切)是一种常见的非线性激活函数,常用于神经网络的隐藏层。tanh 函数也是一种S形曲线,输出范围为(−1,1)

2.1 公式
tanh数学表达式为:
t
a
n
h
(
x
)
=
e
x
−
e
−
x
e
x
+
e
−
x
{tanh}(x) = \frac{e^x - e^{-x}}{e^x + e^{-x}}
tanh(x)=ex+e−xex−e−x
2.2 特征
-
输出范围: 将输入映射到(-1, 1)之间,因此输出是零中心的。相比于Sigmoid函数,这种零中心化的输出有助于加速收敛。
-
对称性: Tanh函数是关于原点对称的奇函数,因此在输入为0时,输出也为0。这种对称性有助于在训练神经网络时使数据更平衡。
-
平滑性: Tanh函数在整个输入范围内都是连续且可微的,这使其非常适合于使用梯度下降法进行优化。
d d x tanh ( x ) = 1 − tanh 2 ( x ) \frac{d}{dx} \text{tanh}(x) = 1 - \text{tanh}^2(x) dxdtanh(x)=1−tanh2(x)
2.3 缺点
- 梯度消失: 虽然一定程度上改善了梯度消失问题,但在输入值非常大或非常小时导数还是非常小,这在深层网络中仍然是个问题。这是因为每一层的梯度都会乘以一个小于1的值,经过多层乘积后,梯度会变得非常小,导致训练过程变得非常缓慢,甚至无法收敛。
- 计算成本: 由于涉及指数运算,Tanh的计算成本还是略高,尽管差异不大。
3 ReLU
ReLU(Rectified Linear Unit)是深度学习中最常用的激活函数之一,它的全称是修正线性单元。ReLU 激活函数的定义非常简单,但在实践中效果非常好。

3.1 公式
ReLU 函数定义如下:
ReLU
(
x
)
=
max
(
0
,
x
)
\text{ReLU}(x) = \max(0, x)
ReLU(x)=max(0,x)
即ReLU对输入x进行非线性变换:
∙
当
x
>
0
时,ReLU
(
x
)
=
x
∙
当
x
≤
0
时,ReLU
(
x
)
=
0
\bullet\quad\text{当 }x>0\text{ 时,ReLU}(x)=x\text{}\\\bullet\quad\text{当 }x\leq0\text{ 时,ReLU}(x)=0\text{}
∙当 x>0 时,ReLU(x)=x∙当 x≤0 时,ReLU(x)=0
3.2 特征
-
计算简单:ReLU 的计算非常简单,只需要对输入进行一次比较运算,这在实际应用中大大加速了神经网络的训练。
-
ReLU 函数的导数是分段函数:
ReLU ′ ( x ) = { 1 , if x > 0 0 , if x ≤ 0 \text{ReLU}'(x)=\begin{cases}1,&\text{if } x>0\\0,&\text{if }x\leq0\end{cases} ReLU′(x)={1,0,if x>0if x≤0 -
缓解梯度消失问题:相比于 Sigmoid 和 Tanh 激活函数,ReLU 在正半区的导数恒为 1,这使得深度神经网络在训练过程中可以更好地传播梯度,不存在饱和问题。
-
稀疏激活:ReLU在输入小于等于 0 时输出为 0,这使得 ReLU 可以在神经网络中引入稀疏性(即一些神经元不被激活),这种稀疏性可以减少网络中的冗余信息,提高网络的效率和泛化能力。
3.3 缺点
- 神经元死亡:由于ReLU在x≤0时输出为0,如果某个神经元输入值是负,那么该神经元将永远不再激活,成为“死亡”神经元。随着训练的进行,网络中可能会出现大量死亡神经元,从而会降低模型的表达能力。
4 LeakyReLU
Leaky ReLU是一种对 ReLU 函数的改进,旨在解决 ReLU 的一些缺点,特别是Dying ReLU 问题。Leaky ReLU 通过在输入为负时引入一个小的负斜率来改善这一问题。

4.1 公式
Leaky ReLU 函数的定义如下:
Leaky ReLU
(
x
)
=
{
x
,
if
x
>
0
α
x
,
if
x
≤
0
\text{Leaky ReLU}(x)=\begin{cases}x,&\text{if } x>0\\\alpha x,&\text{if } x\leq0\end{cases}
Leaky ReLU(x)={x,αx,if x>0if x≤0
其中,
α
\alpha
α 是一个非常小的常数(如 0.01),它控制负半轴的斜率。这个常数
α
\alpha
α是一个超参数,可以在训练过程中可自行进行调整。
4.2 特征
- 避免神经元死亡:通过在x≤0 区域引入一个小的负斜率,这样即使输入值小于等于零,Leaky ReLU仍然会有梯度,允许神经元继续更新权重,避免神经元在训练过程中完全“死亡”的问题。
- 计算简单:Leaky ReLU 的计算与 ReLU 相似,只需简单的比较和线性运算,计算开销低。
4.3 缺点
- 参数选择: α \alpha α 是一个需要调整的超参数,选择合适的 α \alpha α 值可能需要实验和调优。
- 出现负激活:如果 α \alpha α 设定得不当,仍然可能导致激活值过低。
5 softmax
Softmax激活函数通常用于分类问题的输出层,它能够将网络的输出转换为概率分布,使得输出的各个类别的概率之和为 1。Softmax 特别适合用于多分类问题。
5.1 公式
假设神经网络的输出层有n个节点,每个节点的输入为z_i,则 Softmax 函数的定义如下:
S
o
f
t
m
a
x
(
z
i
)
=
e
z
i
∑
j
=
1
n
e
z
j
\mathrm{Softmax}(z_i)=\frac{e^{z_i}}{\sum_{j=1}^ne^{z_j}}
Softmax(zi)=∑j=1nezjezi
从上述公式可以看出:
-
每个输出值在 (0,1)之间
-
Softmax()对向量的值做了改变,但其位置不变
-
所有输出值之和为1,即
s u m ( s o f t m a x ( z ) ) = e z 1 s + e z 2 s + . . . + e z n s = s s = 1 sum(softmax(z)) =\frac{e^{z_1}}{s}+\frac{e^{z_2}}{s}+...+\frac{e^{z_n}}{s}=\frac{s}{s}=1 sum(softmax(z))=sez1+sez2+...+sezn=ss=1
5.2 特征
-
将输出转化为概率:通过Softmax,可以将网络的原始输出转化为各个类别的概率,从而可以根据这些概率进行分类决策。

-
概率分布:Softmax的输出是一个概率分布,即每个输出值 Softmax ( z i ) \text{Softmax}(z_i) Softmax(zi)都是一个介于0和1之间的数,并且所有输出值的和为 1:
∑ i = 1 n Softmax ( z i ) = 1 \sum_{i=1}^n\text{Softmax}(z_i)=1 i=1∑nSoftmax(zi)=1 -
突出差异:Softmax会放大差异,使得概率最大的类别的输出值更接近1,而其他类别更接近0。
-
在实际应用中,Softmax常与交叉熵损失函数Cross-Entropy Loss结合使用,用于多分类问题。在反向传播中,Softmax的导数计算是必需的。
5.3 缺点
- 数值不稳定性:在计算过程中,如果z_i的数值过大,e^{z_i}可能会导致数值溢出。因此在实际应用中,经常会对z_i进行调整,如减去最大值以确保数值稳定。
S o f t m a x ( z i ) = e z i − max ( z ) ∑ j = 1 n e z j − max ( z ) \mathrm{Softmax}(z_i)=\frac{e^{z_i-\max(z)}}{\sum_{j=1}^ne^{z_j-\max(z)}} Softmax(zi)=∑j=1nezj−max(z)ezi−max(z)
解释:
z i − max ( z ) z_i-\max(z) zi−max(z)是一个非正数,由于 e z i − m a x ( z ) e^{z_i−max(z)} ezi−max(z) 的形式,当 z i z_i zi 接近 max(z) 时, e z i − m a x ( z ) e^{z_i−max(z)} ezi−max(z) 的值会接近 1,而当 z i z_i zi 远小于 max(z) 时, e z i − m a x ( z ) e^{z_i−max(z)} ezi−max(z) 的值会接近 0。这使得 Softmax 函数的输出中,最大值对应的概率会相对较大,而其他值对应的概率会相对较小,从而提高数值稳定性。
这种调整不会改变 S o f t m a x Softmax Softmax的概率分布结果,因为从数学的角度讲相当于分子、分母都除以了 e max ( z ) e^{\max(z)} emax(z)。
在 PyTorch 中,torch.nn.functional.softmax 函数就自动处理了数值稳定性问题。
- 难以处理大量类别: S o f t m a x Softmax Softmax在处理类别数非常多的情况下(如大模型中的词汇表)计算开销会较大。
5.4 代码实现
代码参考如下:
import torch
import torch.nn as nn
# 表示4分类,每个样本全连接后得到4个得分,下面示例模拟的是两个样本的得分
input_tensor = torch.tensor([[-1.0, 2.0, -3.0, 4.0], [-2, 3, -3, 9]])
softmax = nn.Softmax()
output_tensor = softmax(input_tensor)
# 关闭科学计数法
torch.set_printoptions(sci_mode=False)
print("输入张量:", input_tensor)
print("输出张量:", output_tensor)
输出结果:
输入张量: tensor([[-1., 2., -3., 4.],
[-2., 3., -3., 9.]])
输出张量: tensor([[ 0.0059, 0.1184, 0.0008, 0.8749],
[ 0.0000, 0.0025, 0.0000, 0.9975]])
6. 如何选择
更多激活函数可以查看官方文档:https://pytorch.org/docs/stable/nn.html#non-linear-activations-weighted-sum-nonlinearity
那这么多激活函数应该如何选择呢?实际没那么纠结
6.1 隐藏层
- 优先选ReLU;
- 如果ReLU效果不咋地,那么尝试其他激活,如Leaky ReLU等;
- 使用ReLU时注意神经元死亡问题, 避免出现过多神经元死亡;
- 避免使用sigmoid,尝试使用tanh;
6.2 输出层
- 二分类问题选择sigmoid激活函数;
- 多分类问题选择softmax激活函数;
646

被折叠的 条评论
为什么被折叠?



