调光旋钮为什么输给了单向门:Sigmoid 是怎样被 ReLU 取代的

Posted on 四 16 7月 2026 in Tech

Abstract 调光旋钮为什么输给了单向门:Sigmoid 是怎样被 ReLU 取代的
Authors Walter Fan
Category Tech
Status v1.0
Updated 2026-07-16
License CC-BY-NC-ND 4.0

一个当过主角、后来被换下场的函数

学神经网络,几乎绕不开 Sigmoid(准确说是 Logistic Sigmoid,逻辑斯蒂函数)。它是最早被大量使用的激活函数之一,公式简单、曲线漂亮,还能直接当概率读。很多教材第一章就是它。

可要是你现在去翻一个真实的深度学习模型,会发现一件有点反常的事:隐藏层里几乎见不到 Sigmoid 了,取而代之的是长相寒酸得多的 ReLU——负数一律归零,正数原样放过,连个弯都不带拐的。

这就有意思了。一个数学上更“高级”、还能输出概率的函数,怎么就被一个“小学生都能画出来”的折线打败了?

这篇文章想把这件事讲透,而且尽量照顾数学基础一般的读者。我们会按这样一条阶梯往上走:为什么要激活函数 → Sigmoid 长什么样 → 它的导数为什么这么妙 → 妙的地方怎么反过来要了它的命 → ReLU 凭什么接班。看完你应该能用一句大白话回答:Sigmoid 输在哪。

正文里会出现几个公式和一段推导。它们不是考试题,每个公式前后都有大白话兜底;不感兴趣的段落可以跳,主线不会断。

这篇怎么读

你想带走什么 建议路线
只想知道结论 直接看第 1 节和第 6 节的对比表
想真正理解“梯度消失” 第 1、2、4、5 节
想连推导一起吃透 从头读,重点看第 3 节“数学加餐”

1. 先问一句:为什么要有激活函数?

先把一个神经元想象成上一篇感知机文章里的那个门卫:它收到几个输入,各乘一个权重,再加起来,加上一个默认分(偏置):

$$ z = w_1x_1 + w_2x_2 + w_3x_3 + b $$

如果神经元算完 \(z\) 就直接输出 \(z\),会发生什么?假设我们把很多层这样的神经元摞起来,每一层都只是“乘一乘、加一加”。问题在于,线性变换套线性变换,结果还是线性变换:

$$ W_2\,(W_1x + b_1) + b_2 = (W_2W_1)\,x + (W_2b_1 + b_2) $$

右边整理完,仍然是“一个矩阵乘 \(x\) 再加一个常数”。换句话说,你堆一百层,本质还是一条直线。这就像把一百个只会画直线的尺子接起来,画出来的还是直线,弯的东西一个都描不出来。

所以中间必须插一个非线性函数,把 \(z\) 掰个弯:

$$ a = \phi(z) $$

这个 \(\phi\) 就是激活函数(Activation Function)。有了它,后面一层才能在前一层的基础上组合、扭曲,最终画出复杂的边界。Sigmoid,就是历史上最早挑起这个担子的函数之一。

激活函数不是装饰,是让“深”这个字有意义的前提。 没有它,再深的网络也只是一条被反复改写的直线。


2. Sigmoid 长什么样

Sigmoid 的公式很短:

$$ \sigma(x) = \frac{1}{1 + e^{-x}} $$

这里 \(e \approx 2.718\) 是自然常数,\(x\) 可以是任意实数。别被 \(e^{-x}\) 吓到,我们代几个数就有感觉了。

关键在于指数函数长得快得离谱:

\(x\) \(e^{-x}\) \(\sigma(x) = \dfrac{1}{1+e^{-x}}\)
\(-10\) \(\approx 22026\) \(\dfrac{1}{22027} \approx 0\)
\(0\) \(1\) \(\dfrac{1}{2} = 0.5\)
\(10\) \(\approx 0.0000454\) \(\approx 1\)
  • \(x\) 很大时,\(e^{-x}\) 趋近 0,分母趋近 1,输出趋近 1
  • \(x\) 很小(很负)时,\(e^{-x}\) 变得巨大,分母巨大,输出趋近 0
  • \(x = 0\) 时正好卡在 0.5

把这些点连起来,就是那条著名的 S 形曲线:

Sigmoid 把任意实数压进 0 到 1 之间的 S 形曲线

它干的事一句话就能说清:\((-\infty, +\infty)\) 这么宽的范围,平滑地压进 \((0, 1)\) 这个小区间。 输出永远在 0 和 1 之间,这让它天生适合表示“概率”。

上一篇里我打过一个比方:如果说感知机用的阶跃函数像电灯开关,只有关和开;那 Sigmoid 就像调光旋钮——你拧一点,灯就亮一点,中间有无数个平滑的档位。判断“这是不是一只猫”,它不会硬邦邦地回答“是/否”,而是给你 0.97,读作“97% 的把握是猫”。

这个“平滑”的特性,正是当年大家喜欢它的原因。它也是后面所有故事的伏笔。


3. 它的导数,藏着一个漂亮的巧合

要理解 Sigmoid 后来为什么不行,得先看它的导数。导数听起来吓人,其实就是一句话:输入稍微动一点,输出会跟着变多少。 训练神经网络时,全靠这个“变多少”来决定每个参数该往哪个方向调、调多少。

Sigmoid 有个让无数初学者拍大腿的性质:它的导数可以用它自己表示。

$$ \boxed{\;\sigma'(x) = \sigma(x)\,\bigl(1 - \sigma(x)\bigr)\;} $$

也就是说,前向传播时如果你已经算出了 \(y = \sigma(x)\),那么导数直接 y * (1 - y) 就得到,不用再重新算一遍指数、除法。在需要反复求导的反向传播里,这省下的可是实打实的计算量。

数学加餐:这条公式怎么推出来的

不想看推导,跳到本节最后一句即可,不影响主线。

原函数是 \(y = \dfrac{1}{1 + e^{-x}}\)。为了好写,设 \(u = 1 + e^{-x}\),于是 \(y = u^{-1}\)

第一步,对 \(u^{-1}\) 求导(幂函数法则,再乘上里层的导数):

$$ y' = -u^{-2}\,u' = -\frac{u'}{u^2} $$

第二步,求 \(u' = (1 + e^{-x})'\)。常数 1 求导是 0,剩下 \(e^{-x}\)。用链式法则,记住 \((e^t)' = e^t\),这里 \(t = -x\),所以:

$$ (e^{-x})' = e^{-x}\cdot(-1) = -e^{-x} \quad\Longrightarrow\quad u' = -e^{-x} $$

第三步,代回去,负负得正:

$$ y' = -\frac{-e^{-x}}{(1+e^{-x})^2} = \frac{e^{-x}}{(1+e^{-x})^2} $$

这是第一种写法。接下来是最妙的一步——把它凑成“\(\sigma(x)\) 乘以 \(1\)\(\sigma(x)\)”。先看 \(1 - \sigma(x)\) 是多少:

$$ 1 - \sigma(x) = 1 - \frac{1}{1+e^{-x}} = \frac{e^{-x}}{1+e^{-x}} $$

于是:

$$ \sigma(x)\,\bigl(1-\sigma(x)\bigr) = \frac{1}{1+e^{-x}}\cdot\frac{e^{-x}}{1+e^{-x}} = \frac{e^{-x}}{(1+e^{-x})^2} $$

和上面那一坨一模一样。所以 \(\sigma'(x) = \sigma(x)(1-\sigma(x))\) 成立。

一句话记忆:Sigmoid 的导数不用另算,拿它自己的输出 \(y\) 代进 \(y(1-y)\) 就行。


4. 但这条导数曲线,长得有点“憋屈”

好,公式漂亮,可我们真正关心的是它的形状。把 \(\sigma'(x) = \sigma(x)(1-\sigma(x))\) 画出来,是一座矮矮的钟:

Sigmoid 的导数呈钟形,最大值只有 0.25,两端迅速衰减到接近 0

请盯住纵轴的最高点——它只到 0.25。这不是画得小气,是算出来的:导数在 \(x = 0\) 处最大,此时 \(\sigma(0) = 0.5\),所以

$$ \sigma'(0) = 0.5 \times (1 - 0.5) = 0.25 $$

也就是说,Sigmoid 的导数天花板就是 0.25,再往两边走还要更小。

更要命的是两侧那两块浅色“饱和区”。当输入稍微大一点,比如 \(x = 8\),Sigmoid 输出已经是 0.9997,几乎贴着 1 了;这时导数是:

$$ 0.9997 \times (1 - 0.9997) \approx 0.0003 $$

几乎是 0。直觉上也好理解:曲线在两端已经躺平,输入再怎么变,输出都几乎不动,那“变多少”自然趋近于 0。这个现象叫饱和(saturation)——旋钮拧到头了,再拧也没反应。

单看一层,0.25 甚至 0.0003 好像也还行。问题出在“深”这个字上。


5. 致命伤:梯度消失

神经网络训练靠反向传播,说白了就是把“误差该怪谁”这个信号,从输出层一层层往回传。传的过程里,每经过一层带 Sigmoid 的神经元,这个信号就要乘上一次它的导数

而我们刚说了,这个导数最大才 0.25。于是:

梯度反向传播时每穿过一层最多乘以 0.25,几层之后就衰减到接近 0

假设信号一开始是 1,往回传:

$$ 1 \times 0.25 = 0.25,\quad 0.25 \times 0.25 = 0.0625,\quad \dots $$

才五六层,信号就从 1 掉到了 0.001 以下。而这还是最理想的情况(每层都取最大导数 0.25);一旦某些神经元落进饱和区,导数只有 0.0003,那衰减得更快,几乎瞬间归零。

结果就是:靠近输入的那些层,收到的更新信号几乎为 0,参数怎么练都不动。 前面几层像坐在会议室最后一排、听不清台上在说什么的员工——不是不想改,是根本没接收到“该怎么改”的指令。

这就是深度学习早期最有名的拦路虎之一:梯度消失(Gradient Vanishing)。层数越深,越明显。它一度让“把网络堆深”这条路走得异常艰难。

这里得补一句边界,免得把话说满:梯度消失不是 Sigmoid 一个人的锅,也和权重初始化、网络结构有关;换成两端斜率更大的 tanh 会缓解一些,但没根治。真正把这道坎显著降低的,是换一个“不那么容易饱和”的激活函数。


6. ReLU 凭什么接班

ReLU(Rectified Linear Unit,修正线性单元)的公式简单到有点让人怀疑:

$$ \text{ReLU}(x) = \max(0,\; x) $$

负数一律输出 0,正数原样输出。上一篇里我把它比作单向门:负数挡在门外,正数直接放行。

把它和 Sigmoid 摆一起看:

Sigmoid 两端饱和、导数最大 0.25;ReLU 在正区间斜率恒为 1、不饱和

关键差别在导数。ReLU 在正区间的导数是恒定的 1

$$ \text{ReLU}'(x) = \begin{cases} 1, & x > 0 \\ 0, & x < 0 \end{cases} $$

导数是 1 意味着什么?意味着信号往回传的时候,只要神经元是激活的(正区间),梯度就原样通过,不打折\(1 \times 1 \times 1 \times \dots\) 传一百层还是 1,梯度消失的问题一下子就轻多了。这就是深层网络敢往几十层、上百层堆的重要底气之一。

顺带一提,ReLU 还有两个便宜:计算只是一次比大小,比算指数快得多;而且负区间直接归零,天然带来“稀疏性”,一部分神经元干脆不输出,反而让网络更好训练。

当然,ReLU 也不是完人。负区间导数为 0,如果一个神经元长期落在负区间,就会“死掉”再也学不动,这叫 Dying ReLU。后来的 Leaky ReLU、GELU、Swish 等都是在给这个毛病打补丁。所以别把这理解成“新的一定全面碾压旧的”——工程上从来都是权衡。

把主流激活函数摆成一张表,一眼就能看出谁适合放在哪:

激活函数 输出范围 最大导数 是否容易梯度消失 常见位置
Sigmoid \((0, 1)\) 0.25 很容易 二分类输出层
tanh \((-1, 1)\) 1 较轻 早期网络、部分 RNN
ReLU \([0, +\infty)\) 1(正区间) 基本不会(正区间) 大量网络的隐藏层
GELU / Swish \((-\infty, +\infty)\) 接近 1 很少 现代 Transformer

注意表格最后一列:Sigmoid 并没有被扫进历史垃圾堆。它退出的是隐藏层这个主战场,却牢牢守住了二分类输出层——因为那里恰好需要一个能输出 0 到 1 概率的函数,而这正是它的天赋。多分类里它的兄弟 Softmax 也是同样的道理。

一句话总结这场交接班:Sigmoid 平滑好看、能读作概率,可它的导数最大只有 0.25,深层网络里一乘就没;ReLU 长得糙,但正区间导数恒为 1,梯度传得动,于是接管了隐藏层。


最后一句

回到开头那个问题:一个更“高级”的函数,为什么输给了一条折线?

因为深度学习真正稀缺的资源,不是表达能力,而是“让信号顺畅地传回去”的能力。Sigmoid 赢在形状漂亮,却输在导数太小;ReLU 赢在导数够大、够简单。评判一个零件好不好,从来不看它单独多精巧,而看它放进整个系统后,信号还能不能流动。

这个道理,其实不止在神经网络里成立。一个组织也一样:再漂亮的战略,如果反馈信号在层层传递中衰减到接近 0,最前线的人收不到“该怎么改”,那再深的层级也只是空转。有时候,一个“糙但通畅”的机制,比一个“精致但堵塞”的机制强得多。

动手清单

  • [ ] 用纸笔代 3 个值(\(x = -10, 0, 10\)),亲手确认 Sigmoid 输出趋近 0、0.5、1;
  • [ ] 验证 \(\sigma'(0) = 0.25\),再算一下 \(x = 8\) 时导数约为 0.0003;
  • [ ] 用 0.25 连乘 6 次,直观感受梯度消失有多快;
  • [ ] 写一行 relu = lambda x: max(0, x),画出它和 Sigmoid 的对比;
  • [ ] 用一句话向同事解释:为什么隐藏层爱用 ReLU,输出层还留着 Sigmoid。

术语小抄

术语 一句话解释
激活函数 给神经元的加权总分掰个弯,制造非线性
Sigmoid 把任意实数压进 \((0,1)\) 的 S 形函数,可当概率读
导数 输入动一点,输出跟着变多少;训练时用来定方向
饱和 曲线两端躺平,导数趋近 0,旋钮拧到头
梯度消失 信号反向传播时层层衰减,前几层几乎更新不了
ReLU 负数归零、正数照过的单向门,正区间导数恒为 1

全文思维导图

@startmindmap
<style>
mindmapDiagram {
  node {
    BackgroundColor #F8F9FA
    RoundCorner 10
    Padding 10
    FontSize 13
  }
  :depth(0) {
    BackgroundColor #1E3A5F
    FontColor white
    FontSize 18
    FontStyle bold
  }
  :depth(1) {
    FontSize 15
    FontStyle bold
  }
  :depth(2) {
    FontSize 13
  }
}
</style>

* Sigmoid 为何被 ReLU 取代
** 为什么要激活函数
*** 线性套线性还是线性
*** 掰个弯才能画复杂边界
** Sigmoid 是什么
*** 公式 1/(1+e^-x)
*** 压进 (0,1),可当概率
*** 调光旋钮
** 导数的巧合
*** σ'=σ(1-σ)
*** 前向算过就能复用
** 致命伤
*** 导数最大只有 0.25
*** 两端饱和≈0
*** 梯度消失
** ReLU 接班
*** max(0,x),单向门
*** 正区间导数恒为 1
*** 计算快、带稀疏性
*** 边界:Dying ReLU
** 结论
*** 隐藏层用 ReLU
*** 输出层留 Sigmoid
@endmindmap

Sigmoid 为何被 ReLU 取代 - 思维导图


本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。 欢迎在我的个人网站 https://www.fanyamin.com 访问原文并评论。