激活函数系列(一):Sigmoid - 从入门到精通

本文深入介绍深度学习中最经典的激活函数之一:Sigmoid 函数。从数学原理到实际应用,用通俗易懂的方式带你理解这个重要的算法组件。

激活函数系列(一):Sigmoid - 从入门到精通

系列导读: 这是激活函数系列的第一篇文章。后续我们还将介绍 ReLU、Tanh、GELU 等常用激活函数。

🎯 什么是激活函数?

在开始介绍 Sigmoid 之前,我们先理解一个核心概念:激活函数

想象一下,你的大脑中有数十亿个神经元。当一个信号传来时,神经元会决定是否”激活”并传递信号给下一个神经元。这个过程不是简单的”是”或”否”,而是一个非线性的决策过程。

在人工神经网络中,激活函数就扮演着类似的角色:

  • 输入: 神经元接收的加权和(线性组合)
  • 激活函数: 将线性输入转换为非线性输出
  • 输出: 传递给下一层的信息
graph LR
    A[输入 x] --> B[加权求和 z=wx+b]
    B --> C[激活函数 σ]
    C --> D[输出 a=σ z]

    style C fill:#ffeb3b,stroke:#f57c00,stroke-width:3px

为什么需要激活函数?

如果没有激活函数,无论神经网络有多少层,它本质上都只是一个线性模型。激活函数为网络引入了非线性,使其能够学习和表示复杂的模式。


📊 Sigmoid 函数:经典的开创者

1. 函数定义

Sigmoid 函数(也称 Logistic 函数)的数学表达式为:

或者等价地写成:

2. 图形展示

Sigmoid 函数的图像是一条优美的 S 形曲线

graph TD
    A[输入 x] -->|负无穷| B[输出接近 0]
    A -->|0| C[输出为 0.5]
    A -->|正无穷| D[输出接近 1]

    B --> E["范围: 0,1"]
    C --> E
    D --> E

    style B fill:#ffcdd2
    style C fill:#fff9c4
    style D fill:#c8e6c9

关键特征:

  • 输出范围: (0, 1) - 永远在 0 和 1 之间
  • 中心点: 当 x=0 时,y=0.5
  • 对称性: 关于点 (0, 0.5) 中心对称
  • 平滑性: 处处可导,曲线光滑

3. 为什么叫 “Sigmoid”?

“Sigmoid” 来自希腊语 “sigma”(σ),因为它的形状像希腊字母 σ。这条 S 形曲线 是很多自然现象的数学模型,例如:

  • 人口增长
  • 疾病传播
  • 化学反应速率

🧮 数学特性(通俗版)

导数(梯度)

Sigmoid 函数的一个重要特性是它的导数非常优雅:

这意味着什么?

在反向传播算法中,我们需要计算梯度来更新权重。Sigmoid 的导数可以直接用函数值表示,这大大简化了计算:

1
2
3
4
# 计算导数
def sigmoid_derivative(x):
s = sigmoid(x)
return s * (1 - s)

概率解释

由于输出在 (0, 1) 之间,Sigmoid 常被解释为概率

  • σ(x) → 0: 事件发生概率很低
  • σ(x) → 1: 事件发生概率很高
  • σ(0) = 0.5: 不确定状态

这使得 Sigmoid 在二分类问题中特别有用。


✅ Sigmoid 的优点

优点 说明 应用场景
输出有界 输出严格在 (0, 1) 之间,不会爆炸 概率预测、归一化
平滑可导 处处可导,便于梯度下降优化 深度网络训练
概率解释 输出可视为概率,直观易懂 二分类任务
历史意义 最早的激活函数之一,研究充分 教学和理解基础
生物学启发 类似神经元的激活率 神经网络理论

❌ Sigmoid 的缺点

缺点 说明 后果
梯度消失 当输入很大或很小时,梯度趋近于 0 深层网络难以训练
输出非零中心 输出恒为正,导致权重更新偏移 收敛速度慢
计算昂贵 指数运算比简单运算慢 训练时间长
饱和性 容易进入饱和区(输出接近 0 或 1) 梯度几乎为 0

梯度消失问题详解

这是 Sigmoid 最大的问题。让我们看看为什么:

graph TD
    A["输入 x 远大于 0"] --> B["sigmoid x 约等于 1"]
    B --> C["梯度约等于 0"]

    D["输入 x 远小于 0"] --> E["sigmoid x 约等于 0"]
    E --> F["梯度约等于 0"]

    G["输入 x 约等于 0"] --> H["sigmoid x 约等于 0.5"]
    H --> I["梯度约等于 0.25 最大值"]

    style C fill:#ffcdd2
    style F fill:#ffcdd2
    style I fill:#c8e6c9

当输入很大或很小时,梯度接近于 0。在深层网络中,梯度经过多次连乘后会变得极小,导致深层参数几乎不更新


🎮 实际应用场景

1. 二分类问题

Sigmoid 最经典的用途是二分类的输出层:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import torch
import torch.nn as nn

# 定义一个简单的二分类网络
class BinaryClassifier(nn.Module):
def __init__(self):
super().__init__()
self.fc1 = nn.Linear(10, 5)
self.fc2 = nn.Linear(5, 1)
self.sigmoid = nn.Sigmoid()

def forward(self, x):
x = torch.relu(self.fc1(x))
x = self.sigmoid(self.fc2(x))
return x

# 使用示例
model = BinaryClassifier()
output = model(input_data) # 输出在 0-1 之间
prediction = (output > 0.5).float() # 转换为 0 或 1

解释: 输出 0.8 表示有 80% 的概率属于正类。

2. 门控机制

在 LSTM 和 GRU 等循环网络中,Sigmoid 用于控制信息流:

1
2
3
# LSTM 中的遗忘门
forget_gate = sigmoid(W_f * [h_prev, x] + b_f)
# 输出 0-1,决定保留多少信息

3. 注意力机制

某些注意力机制使用 Sigmoid 来生成注意力权重:

1
attention_weights = sigmoid(attention_scores)

💻 代码示例

Python 实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import numpy as np
import matplotlib.pyplot as plt

# Sigmoid 函数
def sigmoid(x):
"""
Sigmoid 激活函数

参数:
x: 输入值或数组

返回:
Sigmoid 输出,范围 (0, 1)
"""
return 1 / (1 + np.exp(-x))

# Sigmoid 导数
def sigmoid_derivative(x):
"""
Sigmoid 函数的导数

参数:
x: 输入值或数组

返回:
Sigmoid 导数值
"""
s = sigmoid(x)
return s * (1 - s)

# 可视化
x = np.linspace(-10, 10, 100)
y = sigmoid(x)
y_deriv = sigmoid_derivative(x)

plt.figure(figsize=(12, 5))

plt.subplot(1, 2, 1)
plt.plot(x, y, label='Sigmoid', linewidth=2)
plt.axhline(y=0.5, color='r', linestyle='--', alpha=0.5)
plt.axvline(x=0, color='r', linestyle='--', alpha=0.5)
plt.title('Sigmoid Function')
plt.xlabel('x')
plt.ylabel('σ(x)')
plt.grid(True, alpha=0.3)
plt.legend()

plt.subplot(1, 2, 2)
plt.plot(x, y_deriv, label='Derivative', color='orange', linewidth=2)
plt.axhline(y=0.25, color='r', linestyle='--', alpha=0.5)
plt.title('Sigmoid Derivative')
plt.xlabel('x')
plt.ylabel("σ'(x)")
plt.grid(True, alpha=0.3)
plt.legend()

plt.tight_layout()
plt.savefig('sigmoid_visualization.png', dpi=300)
plt.show()

# 打印一些关键值
print("Sigmoid 关键值:")
print(f"sigmoid(0) = {sigmoid(0):.4f}") # 0.5
print(f"sigmoid(5) = {sigmoid(5):.4f}") # 0.9933
print(f"sigmoid(-5) = {sigmoid(-5):.4f}") # 0.0067
print(f"\n最大导数值:")
print(f"sigmoid'(0) = {sigmoid_derivative(0):.4f}") # 0.25

输出结果:

1
2
3
4
5
6
7
Sigmoid 关键值:
sigmoid(0) = 0.5000
sigmoid(5) = 0.9933
sigmoid(-5) = 0.0067

最大导数值:
sigmoid'(0) = 0.2500


🔄 与其他激活函数对比

激活函数 公式 输出范围 主要优点 主要缺点
Sigmoid 1/(1+e^(-x)) (0, 1) 输出有界,概率解释 梯度消失,非零中心
Tanh (e^x-e^(-x))/(e^x+e^(-x)) (-1, 1) 零中心,更强梯度 梯度消失
ReLU max(0, x) [0, +∞) 计算快,无梯度消失 死亡ReLU问题
Leaky ReLU max(αx, x) (-∞, +∞) 无死亡ReLU 需调参
GELU x·Φ(x) (-∞, +∞) 平滑,性能好 计算复杂
graph LR
    A[Sigmoid 1980s] --> B[Tanh 1990s]
    B --> C[ReLU 2011]
    C --> D[Leaky ReLU 2013]
    D --> E[GELU 2016]
    E --> F[Swish 2017]

    style A fill:#ffcdd2
    style C fill:#c8e6c9
    style E fill:#bbdefb

演进趋势: 从 Sigmoid → ReLU → GELU,追求更好的梯度流动和训练效率。


📚 历史背景

Sigmoid 函数在神经网络中的应用可以追溯到 1940年代

  1. 1943年: McCulloch 和 Pitts 提出第一个神经元模型
  2. 1950-1960年代: Sigmoid 成为神经网络的标准激活函数
  3. 1980年代: BP 算法普及,Sigmoid 被广泛使用
  4. 2011年: ReLU 出现,逐渐取代 Sigmoid
  5. 现在: Sigmoid 主要用于二分类输出层和门控机制

🎯 何时使用 Sigmoid?

✅ 推荐使用场景

  1. 二分类输出层: 需要输出概率
  2. 门控机制: LSTM、GRU 中的门控
  3. 注意力权重: 需要在 (0, 1) 之间的权重
  4. 教学演示: 理解激活函数的基础

❌ 不推荐使用场景

  1. 深层网络隐藏层: 容易梯度消失
  2. 多分类任务: 应使用 Softmax
  3. 需要零中心输出: 应使用 Tanh
  4. 计算资源受限: ReLU 更高效

🧪 练习题

问题 1

为什么 Sigmoid 函数的输出范围是 (0, 1)?

答案: 因为 e^(-x) 永远是正数,所以 1 + e^(-x) > 1,因此 1/(1 + e^(-x)) < 1。同时分母大于 1,所以结果 > 0。

问题 2

Sigmoid 函数在 x=0 处的导数是多少?

答案: 0.25。因为 σ’(x) = σ(x)·(1-σ(x)),当 x=0 时,σ(0)=0.5,所以 σ’(0) = 0.5 × 0.5 = 0.25。

问题 3

为什么深层网络中 Sigmoid 会导致梯度消失?

答案: Sigmoid 的最大导数是 0.25(在 x=0 处)。在深层网络中,梯度需要经过多层连乘,0.25^n 会快速趋近于 0,导致梯度无法传递到浅层。


📖 总结

核心要点

  1. 定义: Sigmoid 将任意输入映射到 (0, 1) 区间
  2. 优势: 输出有界,适合概率预测,数学性质优美
  3. 劣势: 梯度消失问题严重,不适合深层网络隐藏层
  4. 应用: 二分类输出层、门控机制、注意力权重
  5. 演进: 已逐渐被 ReLU 等更高效的激活函数取代

记忆口诀

“S 形曲线 0 到 1,梯度消失要留意。二分类里显身手,深层网络需警惕。”

延伸阅读


🔗 参考资料


下一篇预告: 我们将介绍 ReLU 激活函数,这个简单而强大的函数如何解决了 Sigmoid 的梯度消失问题,并成为现代深度学习的标准选择。


发布日期:2026年2月21日
标签:激活函数、Sigmoid、深度学习、神经网络、算法