深度学习 - 激活函数
激活函数(Activation Function)是神经网络中的关键组件,用于引入非线性,使得网络能够学习和表示复杂的模式和关系。以下是几种常见的激活函数及其详细解释:
1. Sigmoid(S型激活函数)
作用过程:
Sigmoid 函数将输入映射到 (0, 1) 之间。公式为:
σ
(
x
)
=
1
1
+
e
−
x
\sigma(x) = \frac{1}{1 + e^{-x}}
σ(x)=1+e−x1
Sigmoid 将大负数映射到接近 0,大正数映射到接近 1,中间值映射到 0.5 附近。
优点:
- 输出在 (0, 1) 之间,有明确的边界,适合处理概率问题。
- 平滑且连续,易于计算导数。
缺点:
- 梯度消失问题:当输入非常大或非常小时,梯度接近零,导致参数更新缓慢。
- 输出非零均值:输出范围是正数,导致后续层的输入非零均值,这可能导致训练不稳定。
适用场景:
- 输出需要概率的场景,如二分类问题的输出层。
实际案例:
在二分类问题中,例如垃圾邮件分类,Sigmoid 函数常用于输出层,将神经网络的输出映射为概率值。
代码实现:
import torch
import torch.nn as nn
import matplotlib.pyplot as plt
x = torch.linspace(-10, 10, 100)
sigmoid = nn.Sigmoid()
y = sigmoid(x)
plt.plot(x.numpy(), y.detach().numpy())
plt.title("Sigmoid Activation Function")
plt.xlabel("Input")
plt.ylabel("Output")
plt.grid(True)
plt.show()
2. ReLU(Rectified Linear Unit)
作用过程:
ReLU 函数将输入中小于零的部分置为零,其余部分保持不变。公式为:
ReLU
(
x
)
=
max
(
0
,
x
)
\text{ReLU}(x) = \max(0, x)
ReLU(x)=max(0,x)
优点:
- 计算简单且高效,只需比较和赋值。
- 缓解梯度消失问题:只要输入为正,梯度恒为 1,确保反向传播时梯度不会消失。
缺点:
- Dying ReLU 问题:如果输入始终为负,神经元将永远不激活,导致部分神经元永远不起作用。
适用场景:
- 隐藏层的首选激活函数,广泛应用于各类神经网络。
实际案例:
在图像分类任务中,ReLU 常用于卷积神经网络(CNN)的隐藏层,因其高效的计算特性。
代码实现:
relu = nn.ReLU()
y = relu(x)
plt.plot(x.numpy(), y.detach().numpy())
plt.title("ReLU Activation Function")
plt.xlabel("Input")
plt.ylabel("Output")
plt.grid(True)
plt.show()
3. Leaky ReLU
作用过程:
Leaky ReLU 在 ReLU 的基础上引入了一个小的斜率,使得负输入也有一个小的输出,公式为:
Leaky ReLU
(
x
)
=
max
(
0.01
x
,
x
)
\text{Leaky ReLU}(x) = \max(0.01x, x)
Leaky ReLU(x)=max(0.01x,x)
优点:
- 解决 Dying ReLU 问题:负输入仍有非零输出,确保神经元不完全死亡。
缺点:
- 引入了额外的参数,计算复杂度稍高于 ReLU。
适用场景:
- 需要避免 Dying ReLU 的场景,尤其是在深度神经网络中。
实际案例:
在深度卷积神经网络(如 ResNet)中,Leaky ReLU 可以用于各层之间,以防止神经元失活。
代码实现:
leaky_relu = nn.LeakyReLU(0.01)
y = leaky_relu(x)
plt.plot(x.numpy(), y.detach().numpy())
plt.title("Leaky ReLU Activation Function")
plt.xlabel("Input")
plt.ylabel("Output")
plt.grid(True)
plt.show()
4. Tanh(双曲正切函数)
作用过程:
Tanh 函数将输入映射到 (-1, 1) 之间,公式为:
tanh
(
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
优点:
- 输出零均值:输出在 (-1, 1) 之间,有助于收敛速度的提升。
缺点:
- 梯度消失问题:与 Sigmoid 类似,当输入非常大或非常小时,梯度接近零。
适用场景:
- 希望输出有负值的情况,例如 RNN 的隐藏层。
实际案例:
在自然语言处理任务中,Tanh 常用于 RNN 的隐藏层,因为其输出具有零均值特性,有助于序列数据的建模。
代码实现:
tanh = nn.Tanh()
y = tanh(x)
plt.plot(x.numpy(), y.detach().numpy())
plt.title("Tanh Activation Function")
plt.xlabel("Input")
plt.ylabel("Output")
plt.grid(True)
plt.show()
5. Softmax
作用过程:
Softmax 函数将输入转换为概率分布,总和为 1,适用于多分类问题,公式为:
Softmax
(
x
i
)
=
e
x
i
∑
j
e
x
j
\text{Softmax}(x_i) = \frac{e^{x_i}}{\sum_{j} e^{x_j}}
Softmax(xi)=∑jexjexi
优点:
- 输出为概率分布,适合多分类任务。
- 保证输出和为 1,便于概率解释。
缺点:
- 数值不稳定:对于大数值输入,可能导致溢出。
适用场景:
- 多分类问题的输出层,例如图像分类任务中的类别概率预测。
实际案例:
在 ImageNet 图像分类任务中,Softmax 常用于最后一层,将网络输出转换为各类别的概率。
代码实现:
softmax = nn.Softmax(dim=0)
y = softmax(x)
plt.plot(x.numpy(), y.detach().numpy())
plt.title("Softmax Activation Function")
plt.xlabel("Input")
plt.ylabel("Output")
plt.grid(True)
plt.show()
常见问题及解决方案
-
梯度消失:
- 问题:当激活函数的梯度趋近于零时,神经网络的训练速度变得极慢。
- 解决方案:使用 ReLU 或其变体(如 Leaky ReLU)来缓解梯度消失问题。
-
Dying ReLU:
- 问题:ReLU 中的一些神经元可能会永久性地输出零。
- 解决方案:使用 Leaky ReLU 或 Parametric ReLU 来避免神经元死亡。
-
数值不稳定:
- 问题:在计算 Softmax 或其他激活函数时,可能会出现数值溢出或下溢。
- 解决方案:在计算 Softmax 时使用数值稳定技巧,例如减去输入中的最大值。
-
训练不稳定:
- 问题:某些激活函数可能导致训练过程中的不稳定性。
- 解决方案:对输入数据进行标准化,或在网络中使用 Batch Normalization。
-
慢收敛:
- 问题:激活函数的选择可能导致训练过程收敛缓慢。
- 解决方案:尝试不同的激活函数,并调整学习率和优化器参数。
激活函数汇总
激活函数汇总表格
激活函数 | 公式 | 优点 | 缺点 | 适用场景 |
---|---|---|---|---|
Sigmoid | σ ( x ) = 1 1 + e − x \sigma(x) = \frac{1}{1 + e^{-x}} σ(x)=1+e−x1 | 输出在 (0, 1) 之间,适合处理概率问题,平滑且连续,易于计算导数 | 梯度消失问题,输出非零均值,导致训练不稳定 | 输出需要概率的场景,如二分类问题的输出层 |
ReLU | ReLU ( x ) = max ( 0 , x ) \text{ReLU}(x) = \max(0, x) ReLU(x)=max(0,x) | 计算简单且高效,缓解梯度消失问题 | Dying ReLU 问题,如果输入始终为负,神经元将永远不激活 | 隐藏层的首选激活函数,广泛应用于各类神经网络 |
Leaky ReLU | Leaky ReLU ( x ) = max ( 0.01 x , x ) \text{Leaky ReLU}(x) = \max(0.01x, x) Leaky ReLU(x)=max(0.01x,x) | 解决 Dying ReLU 问题,负输入仍有非零输出 | 引入了额外的参数,计算复杂度稍高于 ReLU | 需要避免 Dying ReLU 的场景,尤其是在深度神经网络中 |
Tanh | tanh ( 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 | 输出零均值,有助于收敛速度的提升 | 梯度消失问题,与 Sigmoid 类似,当输入非常大或非常小时,梯度接近零 | 希望输出有负值的情况,例如 RNN 的隐藏层 |
Softmax | Softmax ( x i ) = e x i ∑ j e x j \text{Softmax}(x_i) = \frac{e^{x_i}}{\sum_{j} e^{x_j}} Softmax(xi)=∑jexjexi | 输出为概率分布,适合多分类任务,保证输出和为 1,便于概率解释 | 数值不稳定,对于大数值输入,可能导致溢出 | 多分类问题的输出层,例如图像分类任务中的类别概率预测 |
具体效果及常见问题总结
激活函数 | 具体效果 | 常见问题及解决方案 |
---|---|---|
Sigmoid | 训练速度较慢,梯度消失问题显著,适用于输出层概率预测。 | 梯度消失:使用 ReLU 或其他激活函数。训练不稳定:标准化输入数据。慢收敛:调整学习率。 |
ReLU | 通常能提供较好的训练效果和模型性能,但可能会遇到 Dying ReLU 问题。 | Dying ReLU:使用 Leaky ReLU 或 Parametric ReLU。输出不平衡:使用 Batch Normalization。过拟合:应用正则化技术。 |
Leaky ReLU | 有效解决 Dying ReLU 问题,训练更稳定,适用于深层网络。 | 斜率选择:通过实验选择合适的负斜率。过拟合:应用正则化。不稳定梯度:使用 Batch Normalization。 |
Tanh | 比 Sigmoid 更常用,输出零均值有助于收敛,但深层网络中仍可能遇到梯度消失问题。 | 梯度消失:使用 ReLU 或其他激活函数。训练不稳定:标准化输入数据。慢收敛:调整学习率。 |
Softmax | 多分类任务中非常有效,将输出转换为概率分布,但需要注意数值稳定性问题。 | 数值不稳定:使用数值稳定技巧如减去最大值。梯度消失:减少层数或使用其他激活函数。过拟合:应用正则化技术。 |
激活函数全称
激活函数 | 英文全称 | 中文翻译 |
---|---|---|
Sigmoid | Sigmoid Activation Function | S型激活函数 |
ReLU | Rectified Linear Unit | 修正线性单元 |
Leaky ReLU | Leaky Rectified Linear Unit | 带泄露的修正线性单元 |
Tanh | Hyperbolic Tangent Function | 双曲正切函数 |
Softmax | Softmax Activation Function | Softmax激活函数 |