news 2026/5/10 18:28:02

从阶跃到ReLU:用Python和Matplotlib手把手画一遍,彻底搞懂激活函数怎么选

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
从阶跃到ReLU:用Python和Matplotlib手把手画一遍,彻底搞懂激活函数怎么选

从阶跃到ReLU:用Python和Matplotlib手把手画一遍,彻底搞懂激活函数怎么选

神经网络中的激活函数就像交通信号灯,决定信息是否能够继续向前传递。对于初学者来说,面对各种数学公式往往感到抽象难懂。本文将通过Python代码和可视化图表,带你亲手绘制四种经典激活函数,在动手实践中理解它们的特性和应用场景。

1. 环境准备与基础函数实现

在开始绘制之前,我们需要准备好Python环境。推荐使用Jupyter Notebook进行交互式编程,这样可以实时看到每一步的代码执行结果。首先安装必要的库:

pip install numpy matplotlib

接下来导入我们将要用到的库:

import numpy as np import matplotlib.pyplot as plt %matplotlib inline # 在Jupyter中显示图表

1.1 阶跃函数实现

阶跃函数是最简单的激活函数之一,它像开关一样,输入超过阈值就"打开",否则保持"关闭"。用Python实现如下:

def step_function(x): return np.array(x > 0, dtype=np.float32)

这个实现利用了NumPy的广播特性,可以同时处理标量和数组输入。让我们测试一下:

print(step_function(-1)) # 输出0.0 print(step_function(0.5)) # 输出1.0 print(step_function(np.array([-2, -1, 0, 1, 2]))) # 输出[0. 0. 0. 1. 1.]

1.2 Sigmoid函数实现

Sigmoid函数将输入压缩到0到1之间,实现"软开关"效果:

def sigmoid(x): return 1 / (1 + np.exp(-x))

测试Sigmoid函数:

print(sigmoid(0)) # 输出0.5 print(sigmoid(100)) # 接近1.0 print(sigmoid(-100)) # 接近0.0

2. 函数可视化与特性分析

现在我们已经实现了两个基本激活函数,接下来通过可视化来直观比较它们的特性。

2.1 绘制阶跃函数

x = np.arange(-5, 5, 0.1) y_step = step_function(x) plt.figure(figsize=(8, 6)) plt.plot(x, y_step, label='Step Function') plt.title('Step Function Visualization') plt.xlabel('Input') plt.ylabel('Output') plt.grid(True) plt.legend() plt.show()

阶跃函数的图形呈现明显的阶梯状跳跃,在x=0处发生突变。这种特性使得它在感知机中表现良好,但在神经网络训练中可能导致梯度消失问题。

2.2 绘制Sigmoid函数

y_sigmoid = sigmoid(x) plt.figure(figsize=(8, 6)) plt.plot(x, y_sigmoid, label='Sigmoid', color='orange') plt.title('Sigmoid Function Visualization') plt.xlabel('Input') plt.ylabel('Output') plt.grid(True) plt.legend() plt.show()

Sigmoid函数呈现平滑的S形曲线,输出在0到1之间连续变化。这种平滑性使其在反向传播中能够提供有效的梯度信号。

2.3 对比阶跃与Sigmoid

将两个函数放在同一图表中对比:

plt.figure(figsize=(10, 6)) plt.plot(x, y_step, label='Step Function') plt.plot(x, y_sigmoid, label='Sigmoid', linestyle='--') plt.title('Comparison: Step vs Sigmoid') plt.xlabel('Input') plt.ylabel('Output') plt.grid(True) plt.legend() plt.show()

通过对比可以明显看出:

  • 响应曲线:阶跃函数是突变的,Sigmoid是渐变的
  • 输出范围:两者都在[0,1]区间,但Sigmoid能输出中间值
  • 梯度特性:Sigmoid在任何点都有非零梯度,而阶跃函数在x=0处梯度无限大,其他位置梯度为零

3. 现代激活函数实现与比较

随着深度学习的发展,研究者发现了更适合深度网络的激活函数。下面我们实现并分析两个现代激活函数。

3.1 ReLU函数实现

ReLU(Rectified Linear Unit)是当前最流行的激活函数之一:

def relu(x): return np.maximum(0, x)

测试ReLU函数:

print(relu(-1)) # 输出0.0 print(relu(0.5)) # 输出0.5 print(relu(10)) # 输出10.0

3.2 Tanh函数实现

Tanh函数是Sigmoid的变体,输出范围在-1到1之间:

def tanh(x): return np.tanh(x)

测试Tanh函数:

print(tanh(0)) # 输出0.0 print(tanh(1)) # 约0.7615 print(tanh(-1)) # 约-0.7615

3.3 四种函数综合对比

现在我们将四种函数绘制在同一图表中:

y_relu = relu(x) y_tanh = tanh(x) plt.figure(figsize=(12, 7)) plt.plot(x, y_step, label='Step') plt.plot(x, y_sigmoid, label='Sigmoid', linestyle='--') plt.plot(x, y_relu, label='ReLU', color='green') plt.plot(x, y_tanh, label='Tanh', color='red') plt.title('Activation Functions Comparison') plt.xlabel('Input') plt.ylabel('Output') plt.grid(True) plt.legend() plt.ylim(-1.5, 2.5) plt.show()

从对比图中我们可以总结出:

特性阶跃SigmoidReLUTanh
输出范围[0,1](0,1)[0,∞)(-1,1)
非线性
梯度特性中等
计算复杂度极低
死亡神经元风险

提示:在实际项目中,ReLU通常是默认选择,但在输出层需要特定范围时,可能需要使用Sigmoid或Tanh。

4. 激活函数选择实践指南

理解了各种激活函数的特性后,我们来看如何在实际项目中做出选择。

4.1 不同场景下的选择建议

  1. 二分类问题输出层:Sigmoid(输出在0-1之间,可解释为概率)
  2. 多分类问题输出层:Softmax(Sigmoid的多分类扩展)
  3. 隐藏层
    • 大多数情况:ReLU及其变体(LeakyReLU, PReLU等)
    • RNN/LSTM:Tanh或Sigmoid
  4. 回归问题输出层:线性激活(无激活函数)或特定范围激活

4.2 梯度特性实验

让我们通过代码观察不同激活函数的梯度表现:

def plot_gradients(): x = np.arange(-3, 3, 0.1) # 计算函数值 y_sig = sigmoid(x) y_relu = relu(x) y_tanh = tanh(x) # 计算梯度(近似导数) grad_sig = np.gradient(y_sig, 0.1) grad_relu = np.gradient(y_relu, 0.1) grad_tanh = np.gradient(y_tanh, 0.1) # 绘制梯度 plt.figure(figsize=(12, 8)) plt.subplot(2, 1, 1) plt.plot(x, y_sig, label='Sigmoid') plt.plot(x, y_relu, label='ReLU') plt.plot(x, y_tanh, label='Tanh') plt.title('Activation Functions') plt.legend() plt.subplot(2, 1, 2) plt.plot(x, grad_sig, label='Sigmoid Gradient') plt.plot(x, grad_relu, label='ReLU Gradient') plt.plot(x, grad_tanh, label='Tanh Gradient') plt.title('Gradients of Activation Functions') plt.legend() plt.tight_layout() plt.show() plot_gradients()

从梯度图中可以看到:

  • Sigmoid:梯度在输入绝对值较大时接近0,导致梯度消失
  • ReLU:正区间梯度恒为1,负区间为0
  • Tanh:类似Sigmoid但梯度范围更大

4.3 实际应用中的变体

为了解决标准激活函数的问题,研究者提出了多种改进版本:

# LeakyReLU实现 def leaky_relu(x, alpha=0.01): return np.where(x > 0, x, alpha * x) # ELU实现 def elu(x, alpha=1.0): return np.where(x > 0, x, alpha * (np.exp(x) - 1)) # 绘制比较 x = np.arange(-3, 3, 0.1) plt.figure(figsize=(10, 6)) plt.plot(x, relu(x), label='ReLU') plt.plot(x, leaky_relu(x), label='LeakyReLU', linestyle='--') plt.plot(x, elu(x), label='ELU', linestyle=':') plt.title('ReLU Variants Comparison') plt.legend() plt.grid(True) plt.show()

这些变体解决了标准ReLU的"死亡神经元"问题,在特定场景下表现更好。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/10 18:21:39

WorkshopDL实用指南:如何高效下载Steam创意工坊模组?

WorkshopDL实用指南:如何高效下载Steam创意工坊模组? 【免费下载链接】WorkshopDL WorkshopDL - The Best Steam Workshop Downloader 项目地址: https://gitcode.com/gh_mirrors/wo/WorkshopDL WorkshopDL是一款专为跨平台游戏玩家设计的Steam创…

作者头像 李华
网站建设 2026/5/10 18:19:17

从HDLbits做题到项目实战:一个简单状态机的四种写法,哪种综合出来的时序报告最好?

状态机编码风格实战评测:四种写法对综合结果的影响深度解析 在数字电路设计中,状态机(FSM)作为控制逻辑的核心组件,其编码风格直接影响着最终实现的时序性能、资源占用和功耗表现。许多工程师在仿真阶段验证功能正确后,往往发现实…

作者头像 李华
网站建设 2026/5/10 18:17:05

渐进式形态学滤波实战:PCL库参数调优与城市/山区场景应用解析

1. 渐进式形态学滤波入门:从原理到PCL实战 第一次接触渐进式形态学滤波(PMF)时,我被它处理城市点云数据的效率震惊了。记得当时手头有个包含大量建筑物和树木的机载LiDAR数据集,传统滤波方法要么把屋顶误判为地面&…

作者头像 李华
网站建设 2026/5/10 18:16:00

DouZero深度强化学习在欢乐斗地主中的技术实现与实战应用

DouZero深度强化学习在欢乐斗地主中的技术实现与实战应用 【免费下载链接】DouZero_For_HappyDouDiZhu 基于DouZero定制AI实战欢乐斗地主 项目地址: https://gitcode.com/gh_mirrors/do/DouZero_For_HappyDouDiZhu 基于深度强化学习技术的AI斗地主助手DouZero_For_Happy…

作者头像 李华