激活函数深度解析:从Sigmoid到Swish

🎙️ 语音朗读 当前: 晓晓 (温柔女声)

激活函数深度解析:从Sigmoid到Swish

激活函数是神经网络中引入非线性的关键组件,选择合适的激活函数对模型性能有着重要影响。

为什么需要激活函数

如果没有激活函数,无论神经网络有多少层,其输出仅仅是输入的线性组合,无法学习复杂的非线性映射:

1
2
3
4
5
6
7
8
9
10
11
import numpy as np
import matplotlib.pyplot as plt

# 无激活函数的多层网络等价于单层线性变换
W1 = np.random.randn(3, 4)
W2 = np.random.randn(4, 2)
W3 = np.random.randn(2, 1)

# 三层线性变换等价于一个线性变换
W_equiv = W3 @ W2 @ W1 # 仍然是线性变换
print(f"等效权重矩阵形状: {W_equiv.shape}")

Sigmoid函数

Sigmoid是最早广泛使用的激活函数:

$$\sigma(x) = \frac{1}{1 + e^{-x}}$$

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def sigmoid(x):
return 1 / (1 + np.exp(-x))

def sigmoid_derivative(x):
s = sigmoid(x)
return s * (1 - s)

x = np.linspace(-10, 10, 100)
plt.figure(figsize=(12, 4))
plt.subplot(1, 2, 1)
plt.plot(x, sigmoid(x))
plt.title('Sigmoid Function')
plt.subplot(1, 2, 2)
plt.plot(x, sigmoid_derivative(x))
plt.title('Sigmoid Derivative')
plt.show()

优点

  • 输出在(0,1)之间,可以表示概率
  • 平滑可导

缺点

  • 梯度消失:当输入绝对值较大时,梯度趋近于0
  • 输出非零中心化:导致后续层梯度更新缓慢

Tanh函数

$$\tanh(x) = \frac{e^x - e^{-x}}{e^x + e^{-x}}$$

1
2
3
4
5
def tanh(x):
return np.tanh(x)

def tanh_derivative(x):
return 1 - np.tanh(x) ** 2

Tanh是Sigmoid的改进版本,输出在(-1,1)之间,零中心化,但仍存在梯度消失问题。

ReLU函数

ReLU(Rectified Linear Unit)是目前最常用的激活函数:

$$\text{ReLU}(x) = \max(0, x)$$

1
2
3
4
5
def relu(x):
return np.maximum(0, x)

def relu_derivative(x):
return np.where(x > 0, 1, 0)

优点

  • 计算高效
  • 正区间梯度恒为1,缓解梯度消失
  • 稀疏激活

缺点

  • 神经元死亡:负区间梯度为0,可能导致神经元永久失活

Leaky ReLU

Leaky ReLU在负区间引入一个小的斜率,解决神经元死亡问题:

1
2
3
4
5
def leaky_relu(x, alpha=0.01):
return np.where(x > 0, x, alpha * x)

def leaky_relu_derivative(x, alpha=0.01):
return np.where(x > 0, 1, alpha)

PReLU

PReLU将负区间的斜率设为可学习参数:

1
2
3
4
import torch
import torch.nn as nn

prelu = nn.PReLU(num_parameters=1) # 斜率作为参数自动学习

ELU

ELU在负区间使用指数函数,使输出均值接近0:

1
2
def elu(x, alpha=1.0):
return np.where(x > 0, x, alpha * (np.exp(x) - 1))

Swish函数

Swish是Google提出的自门控激活函数:

$$\text{Swish}(x) = x \cdot \sigma(\beta x)$$

1
2
def swish(x, beta=1.0):
return x * sigmoid(beta * x)

研究表明,Swish在深层网络中表现优于ReLU。

GELU

GELU(Gaussian Error Linear Unit)在Transformer中被广泛使用:

1
2
def gelu(x):
return 0.5 * x * (1 + np.tanh(np.sqrt(2 / np.pi) * (x + 0.044715 * x**3)))

激活函数选择指南

场景 推荐激活函数
隐藏层(通用) ReLU
隐藏层(深层网络) Swish/GELU
隐藏层(存在死亡神经元) Leaky ReLU/PReLU
输出层(二分类) Sigmoid
输出层(多分类) Softmax
输出层(回归) 无激活/Linear

总结

激活函数从Sigmoid发展到ReLU及其变体,再到Swish和GELU,每一次改进都解决了前一代的问题。ReLU及其变体因为计算高效和缓解梯度消失而成为隐藏层的默认选择,而Swish和GELU在Transformer等深层架构中表现更优。选择激活函数时,需要综合考虑梯度特性、计算效率和具体任务需求。

© 2019-2026 ovo$^{mc^2}$ All Rights Reserved. | 站点总访问 28969 次 | 访客 19045
Theme by hiero