从Sigmoid到Swish:用Matplotlib和NumPy手把手教你画10种激活函数图(附完整代码)

张开发
2026/5/2 16:48:26 15 分钟阅读

分享文章

从Sigmoid到Swish:用Matplotlib和NumPy手把手教你画10种激活函数图(附完整代码)
从Sigmoid到Swish用Matplotlib和NumPy手把手教你画10种激活函数图附完整代码第一次接触神经网络时我被那些神秘的数学函数深深吸引——它们就像神经元的开关决定信息是否传递。但教科书上的公式总让我昏昏欲睡直到发现用代码绘制这些函数图像后一切突然变得生动起来。本文将带你用Python重现这个发现之旅从经典的Sigmoid到最新的Swish通过可视化理解每个函数背后的设计哲学。1. 环境准备与基础工具工欲善其事必先利其器。我们选择Python生态中最成熟的数据可视化库Matplotlib和数值计算库NumPy作为核心工具。这两个库的组合能完美平衡易用性和性能特别适合教学演示。import numpy as np import matplotlib.pyplot as plt plt.style.use(seaborn) # 使用更美观的绘图风格配置绘图参数让图像更专业def setup_plot(ax, title): ax.spines[left].set_position(center) ax.spines[bottom].set_position(center) ax.spines[right].set_color(none) ax.spines[top].set_color(none) ax.grid(True, linestyle--, alpha0.7) ax.set_title(title, pad20)2. 经典激活函数可视化2.1 Sigmoid神经网络的启蒙老师这个S型函数曾是早期神经网络的标配它的输出范围(0,1)完美对应概率解释。但亲手绘制它的曲线后你会立即发现它的致命缺陷def sigmoid(x): return 1 / (1 np.exp(-x)) x np.linspace(-10, 10, 500) fig, ax plt.subplots(figsize(8,6)) ax.plot(x, sigmoid(x), linewidth3, color#E63946) setup_plot(ax, Sigmoid Function)关键观察点当|x|5时曲线几乎平坦梯度消失输出均值约为0.5非零中心化指数运算计算成本较高2.2 TanhSigmoid的改进版双曲正切函数解决了Sigmoid的非零中心问题成为RNN时代的宠儿def tanh(x): return np.tanh(x) y_tanh tanh(x) plt.figure(figsize(8,6)) plt.plot(x, y_tanh, labelTanh, color#457B9D) plt.plot(x, sigmoid(x), --, labelSigmoid, color#E63946) plt.legend()对比显示输出范围变为(-1,1)曲线依然存在饱和区梯度在零点附近最大0.25 vs Sigmoid的0.53. 现代激活函数革命3.1 ReLU家族深度学习的主力军Rectified Linear Unit及其变体统治了现代深度学习它们的分段线性特性带来了计算效率和训练速度的飞跃。标准ReLUdef relu(x): return np.maximum(0, x) plt.figure(figsize(10,4)) plt.subplot(121) plt.plot(x, relu(x), color#1D3557) plt.title(Standard ReLU) # Leaky ReLU def leaky_relu(x, alpha0.1): return np.where(x0, x, alpha*x) plt.subplot(122) plt.plot(x, leaky_relu(x), color#A8DADC) plt.title(Leaky ReLU (α0.1))性能对比表特性ReLULeaky ReLUELU计算速度★★★★★★★★★☆★★★☆☆死亡神经元存在缓解避免输出均值0≈0≈0平滑性C0连续C0连续C1连续3.2 SwishGoogle的大脑选择这个自门控函数在ImageNet上表现优于ReLU其独特形状值得仔细研究def swish(x, beta1.0): return x * sigmoid(beta*x) x_fine np.linspace(-4, 4, 200) plt.figure(figsize(8,6)) for beta in [0.1, 1.0, 10.0]: plt.plot(x_fine, swish(x_fine, beta), labelfβ{beta}, linewidth2) plt.legend() plt.title(Swish with Different β Values)曲线特征当β→0时趋近于线性函数当β→∞时接近ReLU默认β1时呈现平滑过渡4. 专业级可视化技巧4.1 多函数对比分析在同一坐标系中比较多个函数能直观展现设计差异functions { ReLU: relu, LeakyReLU: leaky_relu, Swish: swish, GELU: lambda x: x * (1 np.tanh(np.sqrt(2/np.pi) * (x 0.044715*x**3))) } plt.figure(figsize(10,6)) for name, func in functions.items(): plt.plot(x, func(x), labelname, linewidth2.5) plt.ylim(-2, 4) plt.legend()4.2 导数可视化激活函数的导数直接影响反向传播用数值微分展示这一特性def plot_derivative(func, ax, h1e-5): y func(x) grad np.gradient(y, x) ax.plot(x, grad, --, linewidth2) fig, (ax1, ax2) plt.subplots(1, 2, figsize(12,5)) ax1.plot(x, swish(x)) plot_derivative(swish, ax1) ax1.set_title(Swish and its Derivative) ax2.plot(x, relu(x)) plot_derivative(relu, ax2) ax2.set_title(ReLU and its Derivative)5. 实战应用建议经过这些可视化实验我总结出几条实用经验计算机视觉优先尝试Swish或ReLU变体自然语言处理Tanh在LSTM中仍有优势稀疏编码LeakyReLU能保持负值信息快速原型标准ReLU仍是可靠默认选择最后分享一个绘制函数集合的实用代码模板def plot_activation_grid(functions_dict, x_range(-4,4)): n len(functions_dict) fig, axes plt.subplots(int(np.ceil(n/2)), 2, figsize(12, 3*np.ceil(n/2))) for ax, (name, func) in zip(axes.flat, functions_dict.items()): x np.linspace(*x_range, 200) y func(x) ax.plot(x, y, labelname, linewidth3) ax.set_title(name) ax.grid(True) plt.tight_layout()

更多文章