当前位置: 首页 > 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 实现仍然很重要。

http://www.xdnf.cn/news/229033.html

相关文章:

  • uv安装及使用
  • 在pycharm中创建Django项目并启动
  • TIME_WAIT状态+UDP概念及模拟实现服务器和客户端收发数据
  • 决策树在电信客户流失分析中的实战应用
  • 126. 单词接龙 II
  • 数学建模论文手的学习日常01
  • 牛客:AB5 点击消除
  • 【已解决】TensorRT安装好后加载不了或者转换不了engine模型,或者加载时报错
  • LeetCode392_判断子序列
  • 基于PHP的在线编程课程学习系统
  • [特殊字符] 开发工作高内存占用场景下,Windows 内存压缩机制是否应该启用?实测分析与优化建议
  • 涨薪技术|0到1学会性能测试第44课-apachetop模块监控
  • MCU片上存储器的类型与特性
  • 【学习 python day5】
  • 3.2goweb框架GORM
  • kotlin 过滤 filter 函数的作用和使用场景
  • MATLAB小试牛刀系列(3)
  • linux系统加固
  • 基于 Rancher 部署 Kubernetes 集群的工程实践指南
  • StarRocks Lakehouse 如何重构大数据架构?
  • 基于标注数据的情感分析模型研究
  • 使用 Spring Data Redis 实现 Redis 数据存储详解
  • 【数据结构】——顺序表刷题
  • 论文阅读:2024 EMNLP User Inference Attacks on Large Language Models
  • MySQL表的内外连接
  • 黑群晖Moments视频无缩略图,安装第三方ffmpeg解决
  • kivy android打包buildozer.spec GUI配置
  • (Go Gin)Gin学习笔记(二):路由配置、基本路由、表单参数、上传单个文件、上传多个文件、浅扒路由原理
  • 2025年- H13-Lc121-189.轮转数组(普通数组)---java版
  • Neo4j多关系或多路径