思考:在机器学习中,层与层之间的非线性函数sigmoid为f(x)=1/[1+e(-x)]。这个函数在0处的导数为0.25。它不能很好的模拟阶跃函数。因为阶跃函数在0处的导数是无限大。因此有人提出了带参数β的sigmoid函数sigmoid为f(x)=1/[1+e(-βx)],当β越大,sigmoid上升的就越快。也就是更好的模拟了阶跃函数。那为什么我们不把β取得很大,这样sigmoid就更加像阶跃函数了。在实际中却从不采用。请问除了多了一个参数导致的不方便外,还有其他理由说明为什么我们不采用这样的非线性函数吗?
这是一个非常深刻而经典的问题,涉及神经网络中激活函数的可导性、梯度传播、数值稳定性和训练效率等核心问题。
一个很重要的事实:
β 越大,Sigmoid 越接近阶跃函数;但我们实际上并不会让 β 很大。为什么?
除了提到的“多了一个参数 β 不方便调整”这个表面原因,实际上有更关键的、理论与实践上的深层理由。下面我们来逐一分析:
一、β 过大导致梯度消失(Gradient Vanishing)
✅ 先看导数:
最大导数出现在 x = 0 时:
虽然在 x = 0 附近导数变大了,但关键在于远离 0 的区域会发生什么?
当 |x| 增大时,f(x) 趋近于 0 或 1,此时: f(x)(1−f(x))→0⇒f′(x)→0
而且随着 β 越大,收敛得越快,绝大多数输入都会落入极小的梯度区域。这会导致:
- 反向传播时梯度接近于 0;
- 网络权重几乎无法更新;
- 网络陷入“学习瘫痪”状态。
这正是梯度消失问题的典型来源之一。
二、β 越大,数值不稳定(Numerical Instability)
当 β 很大时,sigmoid 中的指数项: e−βx
很容易溢出或下溢,尤其当 β 是几十、几百时,在 float32 精度下:
- 对于较大负数,e−βx -> ∞,造成 溢出;
- 对于较大正数,e−βx -> 0,造成 下溢;
- 最终结果要么是 0、要么是 1,完全失去连续性和可导性;
这会直接导致模型的数值不稳定或训练爆炸。
三、不利于梯度下降的动态调整(优化困难)
当激活函数接近阶跃函数时,网络本质上变成了一个“组合逻辑网络”:
- 只在极少数边界附近可调整;
- 大多数神经元输出几乎恒定(0或1);
- 导致整个网络的参数空间变得非常不连续,极难优化;
- 优化器如 SGD、Adam 无法找到有效的下降方向。
相当于你给网络设置了一个“非常陡峭的山”,但又不给它绳索——梯度!
四、表达能力反而不升反降(可组合性下降)
虽然 β 大的 sigmoid 更接近阶跃函数,但神经网络的强大能力不在于精确模拟阶跃函数,而在于通过多个光滑、非线性层组合出复杂函数。
β 太大 → 函数几乎变成硬门限 → 网络退化成了“硬编码的规则系统”:
- 缺乏微调能力;
- 可微性下降;
- 泛化能力也变差。
五、现代替代品远优于它(如 ReLU)
正因为上面这些问题,现代深度学习中基本不会用 sigmoid(无论是否带 β)作为隐藏层激活函数,取而代之的是:
- ReLU: 简单高效,解决梯度消失;
- Leaky ReLU / ELU:引入负值,增强表达力;
- GELU / Swish:结合 ReLU 的稀疏性与 sigmoid 的平滑性;
- Softmax:用于输出层概率建模,不参与中间层激活。
✅ 总结:为什么不采用 β 很大的 sigmoid?
问题 | 原因 |
---|---|
梯度消失 | 远离 0 区域梯度趋近 0,训练停滞 |
数值不稳定 | 大指数项造成 overflow/underflow |
优化困难 | 非线性太强 → 不可微 → 学不动 |
表达能力差 | 不能微调、可组合性差 |
已有替代方案更优 | ReLU/GELU/Swish 更快更稳定 |
用Python的PyTorch/Numpy 的模拟例子来直观感受这些问题,请到第3页继续阅读👇