You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

编写深度学习代码时Sigmoid函数如何避免除零错误

Sigmoid实现的除零/数值错误规避方案

你当前使用的sigmoid实现未做任何数值稳定性防护,并不会在正向传播阶段直接触发除零,但会在输入取极端值时出现指数溢出,导致激活值被截断为0或1,最终在反向传播计算梯度时触发除零错误。

问题产生的具体逻辑

原生公式A = 1 / (1 + np.exp(-Z))的数值风险来自两个极端场景:

  • 当Z为绝对值极大的负数时,-Z为极大正数,np.exp(-Z)会上溢为inf,此时计算得到的A会被截断为0,后续反向传播如果对A做除法、取对数运算,就会直接触发除零、对数域错误。
  • 当Z为绝对值极大的正数时,-Z为极小负数,np.exp(-Z)会下溢为0,此时计算得到的A会被截断为1,同样会在反向传播阶段引发数值错误。

规避逻辑

核心是利用sigmoid的数学等价性,对输入的正负区间做分支计算,从根源上避免大值指数运算:

  • 对所有满足Z >= 0的元素,保留原公式1/(1 + np.exp(-Z)):此时-Z <= 0,np.exp(-Z)取值范围在(0, 1]之间,不会出现指数上溢,计算结果稳定。
  • 对所有满足Z < 0的元素,使用等价变形公式np.exp(Z) / (1 + np.exp(Z)):此时Z < 0,np.exp(Z)取值范围在(0, 1)之间,同样不会出现指数溢出,计算结果不会被异常截断。
  • 额外防护:如果需要进一步兜底,可以在所有除法运算的分母上添加一个极小的平滑项(如1e-8),彻底避免分母为0的极端情况。

数值稳定版实现代码

import numpy as np

def sigmoid(Z):
    """
    逐元素计算Z的sigmoid激活值(数值稳定版本)

    参数
    ---------
    Z : array
        仿射变换层的输出值

    返回值
    -------
    A : array
        经过sigmoid激活后的输出值
    Z : array
        仿射变换层的原始输出值(供反向传播阶段缓存复用)
    """
    A = np.zeros_like(Z, dtype=np.float64)
    # 生成正负区间掩码做分支计算
    pos_mask = Z >= 0
    neg_mask = ~pos_mask
    # 正区间计算逻辑
    A[pos_mask] = 1 / (1 + np.exp(-Z[pos_mask]))
    # 负区间计算逻辑
    exp_z_neg = np.exp(Z[neg_mask])
    A[neg_mask] = exp_z_neg / (1 + exp_z_neg)

    return A, Z

内容的提问来源于stack exchange,提问作者user2458922

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 01:51:20