当前位置: 首页 > news >正文

Sigmoid函数简介及其Python实现

文章目录

  • 一、Sigmoid 函数简介
    • 1. 数学公式
    • 2. 关键特性
    • 3. 应用场景
  • 二、Python 实现
    • 1. 使用 `math` 库 (适用于单个数值)
    • 2. 使用 `numpy` 库 (适用于数值、列表、数组、矩阵)
    • 3. 使用 `scipy.special.expit` (数值稳定)
  • 三、小结

一、Sigmoid 函数简介

Sigmoid 函数(也称为 Logistic 函数)是一个在数学、机器学习(尤其是在逻辑回归和早期神经网络中)广泛使用的函数。它的主要特点是将任意实数输入映射到 (0, 1) 这个开区间内。

1. 数学公式

Sigmoid 函数通常用希腊字母 σ (sigma) 表示,其数学表达式为:

σ ( x ) = 1 1 + e − x σ(x) = \frac{1}{1 + e^{-x}} σ(x)=1+ex1

其中:

  • x 是函数的输入(一个实数)。
  • e 是自然对数的底(欧拉数,约等于 2.71828)。

2. 关键特性

(1) 输出范围 (0, 1): 这是 Sigmoid 最重要的特性之一。无论输入 x x x 是什么值(正无穷、负无穷或介于两者之间),输出值 σ ( x ) σ(x) σ(x) 总是严格大于 0 且严格小于 1。这使得它非常适合用来表示概率值,或者在二元分类问题中表示属于某个类别的可能性。
(2) S 形曲线: 函数的图形呈 “S” 形。当 x x x 趋近于负无穷时, e − x e^{-x} ex 趋近于正无穷,分母变得非常大, σ ( x ) σ(x) σ(x) 趋近于 0。当 x x x 趋近于正无穷时, e − x e^{-x} ex 趋近于 0,分母趋近于 1, σ ( x ) σ(x) σ(x) 趋近于 1。
(3) 单调递增: 函数在其整个定义域内是严格单调递增的,这意味着输入 x x x 越大,输出 σ ( x ) σ(x) σ(x) 也越大。
(4) 中心对称: 函数关于点 (0, 0.5) 中心对称。即 σ ( 0 ) = 1 / ( 1 + e 0 ) = 1 / ( 1 + 1 ) = 0.5 σ(0) = 1 / (1 + e^0) = 1 / (1 + 1) = 0.5 σ(0)=1/(1+e0)=1/(1+1)=0.5
(5) 导数易于计算: Sigmoid 函数的导数可以用其自身来表示:
σ ′ ( x ) = σ ( x ) ∗ ( 1 − σ ( x ) ) σ'(x) = σ(x) * (1 - σ(x)) σ(x)=σ(x)(1σ(x))
这个特性在神经网络的反向传播算法中非常有用,因为计算梯度时可以直接利用前向传播计算出的 Sigmoid 值。

3. 应用场景

  • 逻辑回归 (Logistic Regression): Sigmoid 函数是逻辑回归模型的核心,用于将线性模型的输出转换为概率。
  • 神经网络激活函数: 在早期的神经网络中,Sigmoid 曾被广泛用作隐藏层和输出层的激活函数。
    • 输出层: 对于二元分类问题,输出层使用 Sigmoid 可以直接输出概率。
    • 隐藏层: 现在在深度神经网络的隐藏层中,Sigmoid 的使用已大大减少,主要因为梯度消失 (Vanishing Gradient) 问题。当输入 x 的绝对值很大时,Sigmoid 的导数趋近于 0,这会导致在反向传播过程中梯度逐层乘以接近 0 的数,使得深层网络的权重更新非常缓慢甚至停滞。ReLU 及其变种(如 Leaky ReLU, ELU)已成为更常用的隐藏层激活函数。
  • 概率建模: 任何需要将实数值压缩到 (0, 1) 区间以表示概率或置信度的场景。

缺点 (尤其是在深度学习隐藏层中):

  1. 梯度消失: 如上所述,饱和区域(输入绝对值大时)梯度接近 0。
  2. 输出非零中心 (Not Zero-Centered): Sigmoid 的输出恒大于 0。这会导致后续层接收到的输入总是正数,可能在梯度下降过程中引起参数更新的“之”字形抖动(Zigzagging dynamics),降低收敛速度。
  3. 计算复杂度: 相对于 ReLU 函数 (max(0, x)),指数运算 e^x 的计算成本稍高。

二、Python 实现

我们可以使用 Python 的 math 库(处理单个数值)或 numpy 库(处理数值或数组/向量/矩阵)来实现 Sigmoid 函数。在机器学习中,通常使用 numpy 因为它能高效地处理向量化运算。

1. 使用 math 库 (适用于单个数值)

import mathdef sigmoid_math(x):"""计算单个数值的 Sigmoid 值。Args:x: 输入的实数。Returns:x 的 Sigmoid 值,范围在 (0, 1) 之间。"""# 防止 e^(-x) 过大导致 OverflowError (当 x 是非常小的负数时)# Sigmoid(x) = 1 / (1 + exp(-x)) = exp(x) / (exp(x) + 1)# 当 x 非常小时,exp(x) 接近 0,Sigmoid(x) 接近 0# 当 x 非常大时,exp(-x) 接近 0,Sigmoid(x) 接近 1# 这里直接计算标准形式,对于极端值 math.exp 会处理或抛出异常try:result = 1 / (1 + math.exp(-x))except OverflowError:# 如果 exp(-x) 溢出,说明 -x 非常大,即 x 是非常小的负数# 此时 Sigmoid 值接近 0result = 0.0return result# 示例
print(f"Sigmoid(0) = {sigmoid_math(0)}")
print(f"Sigmoid(10) = {sigmoid_math(10)}")
print(f"Sigmoid(-10) = {sigmoid_math(-10)}")
# 一个较大的正数,接近 1
print(f"Sigmoid(100) = {sigmoid_math(100)}")
# 一个较小的负数,接近 0
print(f"Sigmoid(-100) = {sigmoid_math(-100)}")

math实现

2. 使用 numpy 库 (适用于数值、列表、数组、矩阵)

这是在机器学习和数据科学中最常用的方式,因为 numpy 的函数可以对整个数组进行元素级 (element-wise) 操作,效率很高。

import numpy as npdef sigmoid_numpy(x):"""计算输入 x (可以是数值、列表、numpy 数组等) 的 Sigmoid 值。Args:x: 输入,可以是单个数值、列表、元组、numpy 数组等。Returns:与 x 相同形状的 numpy 数组,包含每个元素的 Sigmoid 值。"""# np.exp() 可以直接处理数组# 对于非常大的负数 x, -x 很大, np.exp(-x) 可能溢出或得到 inf# 对于非常大的正数 x, -x 很小, np.exp(-x) 接近 0# Numpy 通常能较好地处理这些边界情况,例如 exp(很大负数) -> 0, exp(很大正数) -> inf# 1 / (1 + inf) -> 0. 这不是我们想要的,当 x 很大时,结果应为 1# Sigmoid(x) = 1 / (1 + exp(-x))# 为了数值稳定性,可以做一些处理,但通常 numpy 的标准实现足够健壮# 或者使用 scipy.special.expit(x) 是一个数值上更稳定的实现# 标准实现:x = np.array(x)  # 确保 x 是 numpy 数组return 1 / (1 + np.exp(-x))# 示例
# 单个值
print(f"Sigmoid(0) = {sigmoid_numpy(0)}")# 列表
input_list = [-10, -1, 0, 1, 10]
print(f"Sigmoid({input_list}) = {sigmoid_numpy(input_list)}")# Numpy 数组
input_array = np.array([[-2, -0.5], [0.5, 2]])
print(f"Sigmoid(\n{input_array}\n) =\n{sigmoid_numpy(input_array)}")# 极端值
print(f"Sigmoid(710) approx = {sigmoid_numpy(710)}") # np.exp(-710) 接近 0, 结果接近 1
# print(f"Sigmoid(800) = {sigmoid_numpy(800)}") # np.exp(-800) 可能下溢为 0,结果为 1
print(f"Sigmoid(-710) approx = {sigmoid_numpy(-710)}") # np.exp(710) 接近 inf, 1/(1+inf) -> 0
# print(f"Sigmoid(-800) = {sigmoid_numpy(-800)}") # np.exp(800) 可能溢出为 inf, 结果为 0

numpy实现

3. 使用 scipy.special.expit (数值稳定)

scipy 库提供了一个专门为 Sigmoid 函数优化的实现,通常在数值上更稳定。

from scipy.special import expit # expit is the logistic sigmoid function# 示例
print(f"Scipy Sigmoid(0) = {expit(0)}")
print(f"Scipy Sigmoid({input_list}) = {expit(input_list)}")
print(f"Scipy Sigmoid(\n{input_array}\n) =\n{expit(input_array)}")# 处理极端值更稳健
print(f"Scipy Sigmoid(800) = {expit(800)}")
print(f"Scipy Sigmoid(-800) = {expit(-800)}")

sklearn
图像绘制代码如下:

import numpy as np
import matplotlib.pyplot as pltdef sigmoid(x):"""计算 Sigmoid 函数值"""return expit(x) # 使用 scipy 的 expit 函数# 1. 生成 x 值范围
# 我们需要一系列 x 值来绘制平滑的曲线
# np.linspace(start, stop, num) 在指定的间隔内返回均匀间隔的数字。
x = np.linspace(-10, 10, 200) # 生成从 -10 到 10 的 200 个点# 2. 计算对应的 y 值 (Sigmoid 输出)
y = sigmoid(x)# 3. 使用 matplotlib 绘图
plt.figure(figsize=(8, 5)) # 创建一个图形窗口,可以指定大小plt.plot(x, y, label='Sigmoid Function', color='blue', linewidth=2) # 绘制曲线# 4. 添加图形元素,使其更清晰
plt.title('Sigmoid Function: σ(x) = 1 / (1 + e^(-x))') # 图形标题
plt.xlabel('x') # x 轴标签
plt.ylabel('σ(x)') # y 轴标签# 添加网格线
plt.grid(True, linestyle='--', alpha=0.6)# 添加关键水平线和垂直线
plt.axhline(0.5, color='red', linestyle=':', linewidth=1, label='y = 0.5') # y=0.5 水平线
plt.axhline(1.0, color='gray', linestyle=':', linewidth=1, label='y = 1.0') # y=1.0 水平线
plt.axhline(0.0, color='gray', linestyle=':', linewidth=1, label='y = 0.0') # y=0.0 水平线
plt.axvline(0, color='gray', linestyle=':', linewidth=1) # x=0 垂直线# 设置 y 轴范围,更清晰地显示 0 到 1 的区间
plt.ylim(-0.1, 1.1)# 显示图例 (需要 plot 时指定了 label)
plt.legend()# 5. 显示图形
plt.show()

Sigmoid函数图像

三、小结

在实际的机器学习项目中,如果你使用了像 TensorFlowPyTorch 这样的深度学习框架,它们内部都已经内置了高效且数值稳定的 Sigmoid 函数实现,你通常会直接调用框架提供的函数。但理解其原理和基本的 Python 实现仍然很重要。

相关文章:

  • SQL命令二:SQL 高级查询与特殊算法
  • 《JDK 1.7 vs JDK 1.8 ConcurrentHashMap 深度对比与实战解析》
  • EWM 流程全自动化实现方法
  • MySQL explain
  • 《可信数据空间 技术架构》技术文件正式发布
  • Gas 优化不足、升级机制缺陷问题
  • 【区块链】区块链技术介绍
  • 『深夜_MySQL』详解数据库 探索数据库是如何存储的
  • MySQL 中的索引数量是否越多越好?为什么?
  • 华为发布全球首个L3商用智驾ADS4.0
  • vue+django农产品价格预测和推荐可视化系统[带知识图谱]
  • DeepSeek最新大模型发布-DeepSeek-Prover-V2-671B
  • harmonyOS 手机,双折叠,平板,PC端屏幕适配
  • 分布式链路ID实现
  • DeepSeek本地部署及WebUI可视化完全指南
  • 4:QT联合HALCON编程—机器人二次程序抓取开发(九点标定)
  • 鸿蒙ArkUI Inspector配置
  • Mysql数据库高可用解决方案-Mysql Router
  • 什么是美颜SDK?美颜SDK安卓与iOS端开发指南
  • 2025.4.24 JavaScript 基础学习笔记
  • 王受文已任中华全国工商业联合会领导班子成员
  • 北京动物园:大熊猫“萌兰”没有参加日本大阪世博会的计划
  • 法院为“外卖骑手”人身权益撑腰:依法认定实际投保人地位
  • 伊朗外长: 美伊谈判进展良好,讨论了很多技术细节
  • 政治局会议深度|提出“设立新型政策性金融工具”有何深意?
  • 最大规模的陈逸飞大展启幕:回望他,回望一个时代