阶段 1 · 最小学习机器

激活函数:给网络
折出第一道褶

上一章《MLP 多层感知机》说过:没有激活函数,堆 100 层也等于 1 层。 这一章把这句话真的验证一遍——用矩阵乘法,不用比喻。 然后解释为什么 ReLU 会成为十年的默认选择、它必须配一套专门的初始化才训得动,以及它自己会在哪儿出问题。

1

先证明:不折弯,深度就是幻觉

一层线性层能做的事,说到底是「拉伸 + 旋转 + 平移」:把输入 x 乘上一张乘数表(矩阵)W, 再加上一串数(偏置)b,写成 f₁(x) = W₁x + b₁。 连续做两次,得到的还是一个「拉伸 + 旋转 + 平移」:

摊开就是这个意思:f₂(f₁(x)) = W₂(W₁x + b₁) + b₂ = (W₂W₁)x + (W₂b₁ + b₂) = W′x + b′。

也就是说:两层可以合并成一层,一层也可以拆成两层。 那 20 层呢?下面就真的算一遍。

互动 · 线性网络与 ReLU 网络,各自折出了什么形状

线性:永远是一条直线,永远只有 1 段

ReLU:每加一层就多折几道

左边的误差读数停在浮点误差量级:默认 6 层约 1e-15,把它拖到 20 层也只涨到约 1e-13,那是双精度累积的舍入误差。 意思是:无论多少层线性网络,它和 1 层在数学上是同一个函数,深度带来的表达能力是零。 右边那个残差是现算的:它回答「用任意一条直线(=任意单层线性网络)去拟合这条曲线,最好能拟合到多好」; 把「层数」拖到 20,它一直没缩回 0(在 0.03 和 0.9 之间上下跳);拖回 1 层,右图也塌成一条直线,因为那时的 ReLU 根本没生效。

🎯 类比 一张平纸,你再怎么拉长、旋转、平移,它还是平的——叠一百张,得到的仍然是一张平整的纸。 只有折出褶子,纸才真正有了形状。
激活函数就是那道褶:线性层只会把纸拉长和转动,是它把纸折了起来。 没有褶,堆多少层都只是一次更大的拉伸。

💡 只要网络真的折了,这个数就不可能等于 0

经过 ReLU 之后函数已经不是线性的了,而单层线性网络只能表达线性函数。 在一摞线性层里,激活函数是唯一的非线性来源:它让网络能表达「如果……那么……」这种条件判断。

2

函数画廊:点一下它们长什么样

虚线是导数 f′(z)。这里的 z 是神经元先算出的加权和,激活函数把它折一下才得到输出。 导数直接决定梯度能不能往回传:训练时,网络要把「错了多少」从输出一层层传回去 (《梯度下降与反向传播》细讲);每经过一层,就乘上这一层激活函数的导数。 导数是 0.0066,传回去就只剩 1/150。

老板说了一句话,要一个接一个传下去。每个人只肯按自己的音量复述一遍。
嗓子小的人(Sigmoid),传几个人就听不见了; 嗓子一般、但岗位上自带一个放大器的人(ReLU 配上 He 初始化),传出去还是原样。
整条链子最后剩多少音量,是所有人的音量相乘,这就是反向传播里那个连乘。 上排每过一个人乘 0.23,下排乘 1.0(理想复述)——拖动人数,看末端音量怎么掉。

示意 · 一队人传话:每过一个人,音量乘一个数

互动 · 常见激活函数 + 导数探针

⚠️ Sigmoid 在 z = −5 处的导数只有 0.0066

Sigmoid 在 z = −5 处的导数只有 0.0066。这意味着: 梯度每穿过这样一个神经元,就被乘上 0.0066,也就是缩到原来的 1/150。
穿过 3 个这样的神经元:0.0066³ ≈ 2.9e-7。前面那些层基本上收不到任何学习信号了。
这不是比喻,这是乘法的必然结果。

函数公式导数最大值用在哪儿
阶跃z > 0 ? 1 : 0几乎处处为 0感知机(已经没人用)
Sigmoid1/(1+e⁻ᶻ)0.25二分类的输出层(只用一次,不存在连乘)
tanh(eᶻ−e⁻ᶻ)/(eᶻ+e⁻ᶻ)1.0(但两端为 0)RNN、小网络
ReLUmax(0, z)1CNN 的默认选择(大模型改用 GELU / SwiGLU)
LeakyReLUmax(0.01z, z)1ReLU 死掉时的替补
GELUz·Φ(z)≈1.1Transformer 全家
Swish / SiLUz·sigmoid(z)≈1.1SwiGLU 的骨架(LLaMA / Qwen 等)

表里那个符号不用记:Φ(z) 是正态分布的累积分布函数, 它在这里只干一件事:把 z 平滑地压进 0~1,好让 GELU 按概率衰减负半轴。 (F.gelu 有一个 tanh 近似版本,结果几乎一样,但快得多。)

3

梯度消失在哪儿:一次连乘

反向传播把梯度一层一层乘回去。如果每层都乘一个 0.23,20 层之后就是 0.23²⁰ ≈ 2×10⁻¹³, 前面的层几乎收不到任何信号,等于没在学。
那这个「每层乘的数」到底是多少?它不是导数最大值,甚至不只是斜率。 它是初始化给这把刀配的尺度 × 工作点上的斜率(工作点 = 输入 z 实际落在的位置,由上一层的输出和初始化决定)。下面这个互动把它量了一遍。

互动 · 梯度传到第 n 层还剩多少

第 1 层
1.000
第 5 层
—
第 20 层
—

上表里 tanh 的导数最大值是 1.0,看起来很健康,但那只是 z = 0 那一个点。 实际工作点上它只有 0.9 左右(曲线两端导数被压到接近 0,那一段叫饱和区,第 2 节把探针拖到 −5 就能看到), 而它配的是 Xavier 初始化(c = 1——「散布预算」:初始化给每层权重定的散布大小,本节末会拆开讲),于是每层乘 0.91。Sigmoid 更糟:最大值 0.25 本身就不够,工作点上只剩 0.23。

ReLU 的平均斜率其实也只有 0.51——一半输入落在负半边,那里的斜率是 0,平均下来自然砍掉一半。 可它配的 He 初始化(一套按激活函数斜率定制的权重方差)会乘进一个 √2, 于是每层乘 √0.51 × √2 ≈ 1.01,正好把漏掉的那一半补回来。

💡 看「导数最大值」会误导人

真正决定梯度能传多远的,是工作点上的斜率 × 初始化给它配的尺度。 这两个数的来路在 §9「更严格的形式」第 1 条。

⚠️ 梯度消失和梯度爆炸是同一枚硬币

每层乘的数如果 > 1,就变成梯度爆炸,损失直接变 NaN。 两者都来自同一个连乘,只是方向相反。
梯度爆炸好治(梯度裁剪:给梯度设一个上限,超了就按比例缩回去),梯度消失难治(你没法把已经乘成 0 的东西乘回来)。

那 Sigmoid 为什么不也乘一个大数,把 0.23 补回 1?

因为 √2 不是「补偿」,是方差守恒:初始化要让每一层进出的散度一样大。乘过头,前向激活会一层层放大,同样训不动。换激活函数时要换的是初始化,不是随手把数调大。

为什么激活函数要配一套专门的初始化?不配真的训不动吗?

因为深度是指数游戏:初始化管「每层进出有多宽」,激活函数管「过一道门还剩多宽」, 两个数相乘就是每层的倍率。配错了不会报错,只会让你白训——下面那张图里,两条线都贴 1 的只有一格。 屏幕上就是前几层的梯度接近 0、损失一动不动,正是《症状与病因》里查的那种。

上面两条疑问的答案,合成一句话就是:深度是场指数游戏——初始化管「每层进出有多宽」,激活函数管「过一道门还剩多宽」,两个数相乘就是每层的倍率。 拆到底就是一道乘法:每层的宽度倍率 = 初始化的 c × 激活函数的保留率 r。 c 由你选(He 给 2,Xavier 给 1),r 是激活函数天生的(ReLU 砍掉一半样本,r ≈ 1/2)。 一对锁配一把钥匙:c × r ≈ 1 才站得住(这就是方差守恒:让每一层进出的数值散布一样大;乘过头,前向激活会一层层放大,同样训不动)——剩下的全是连乘的事, 每层差 10%,到第 96 层就差几万倍。
这一章只回答「为什么必须配、配错什么样」。
下面把 3 种激活 × 3 种初始化全试一遍:青线是信号(前向)的宽度,琥珀线是梯度(反向)的宽度, 两条都贴着 1 的那一对,才配得上「专门」两个字。

互动 · 配对实验台:9 种搭配,谁站得住

三条规律,图上自己会跳出来: ① 只有 ReLU × He 两条线全程贴 1——对折遇上双倍,正好抵消; ② Sigmoid 换哪一列都没救——梯度线三列一起跳水,那 0.23 是它天生的; ③ 配错有两种死法——c 配小了两条线一起阴跌(不报错,只是学不动), 配大了梯度线直接冲顶(爆炸、NaN,吵,反而好发现)。 难的从来不是发现爆炸,是发现安静地没在学。

初始化里那个 c 到底是什么?为什么叫「方差系数」?

它是初始化发给每层权重的「散布预算」:n 个输入求和,权重标准差就取 √(c/n), 进出宽度才能对齐——c = 1 刚好守恒,c = 2 多发一倍、补回 ReLU 砍掉的那一半。 上面实验台那三个按钮,选的就是这个数。

c 具体是几、公式怎么从方差里反解出来,是《初始化与训练稳定性》第 3 节的活——先看后果,再看推导。

4

ReLU 的坑:神经元会死

ReLU 在负半轴导数恒为 0。如果一个神经元的输入对所有样本都是负的, 它的梯度就永远是 0,这个神经元从此再也不会被更新——俗称「死亡 ReLU」。
下面训练一个 1→24→1 的网络(1 个输入、24 个隐藏神经元、1 个输出),然后数有多少个神经元死了。

互动 · 训练过程,看有多少神经元死了

操作:把学习率滑块从 0.05 拖到 1.5,每换一档点一次「重新初始化」再「开始训练」,就能看完整条曲线。

💡 学习率越大,死得越多

小学习率下只死两三个(不是零),拉到 1.0 附近就一个不剩。 原因是:一个大的梯度更新会把某个神经元的偏置 b 推到很负的地方, 于是它对所有输入的输出都变成 0。而这时它的梯度也是 0,所以它再也回不来了。
这是一个不可逆的过程,也是 LeakyReLU、GELU、Swish 存在的全部理由: 给负半轴留一条小缝,让神经元还有机会爬回来。

5

激活函数家族

函数核心公式改的是哪一处留下的问题
Sigmoid1/(1+e⁻ᶻ) 最早的平滑函数:能求导,输出落在 0~1,可以直接当概率 导数最大 0.25 → 梯度消失;输出非零中心(全是正的,下一层收到的输入总偏一边)
tanh(eᶻ−e⁻ᶻ)/(eᶻ+e⁻ᶻ) 把输出改成有正有负(零中心),收敛更快 两端照样饱和
ReLUmax(0, z) 负的整段扔掉。正半轴导数恒为 1,配上 He 初始化后梯度不再衰减;计算极便宜 死亡 ReLU;输出非零中心
LeakyReLUmax(0.01z, z) 把 ReLU 那个 0 换成 0.01:神经元不会彻底死掉 多了一个超参 α(PyTorch 默认 0.01)
PReLUmax(αz, z) 那个斜率不写死,交给训练自己学 每个通道多了一个要学的斜率
ELUz>0 ? z : α(eᶻ−1) 把负半轴那条直线换成指数曲线:在 0 处平滑、往左慢慢趋到 −α,输出接近零中心 要算 exp,更贵
GELUz · Φ(z) 不用硬开关,按「z 在正态分布下有多大」这个概率去衰减负半轴。处处可导、更平滑,Transformer 的默认 要算 erf(误差函数:形状和 Φ 很像,只是值域是 −1 到 1),稍贵(但实际可忽略)
SiLU / Swishz · sigmoid(z) 和 GELU 同一个套路,只是把概率换成 sigmoid。负半轴有个「小坑」,优化更顺 非单调(曲线先下后上,不是一路往上)
SwiGLU / GeGLUf(xW₁) ⊙ xW₃ 门控就是这个 ⊙(逐元素相乘):一路信号(f 那一支)去调制另一路,结果再过一个输出投影 W₂(投影:乘个矩阵,把宽度换一换)——GeGLU 就是 f 换成 GELU 的那一版。大模型里效果明确更好 多一个投影矩阵,参数量 +50%(第 6 节会算:把前馈维度改成 8/3× 就正好拉回持平)

大模型时代,这一格现在谁在站?答案换过两次: CNN 时代 ReLU → Transformer 早期 GELU → 大模型时代 SwiGLU。 注意最后这一次换的不是「曲线更弯」,是结构——激活函数从主角降级成了门里的零件。

阶段代表模型中间层用什么换它的理由
CNN 时代 · 2012 → 2015AlexNet → ResNetReLU 深了也能训(配 He);一条判断,极便宜
Transformer 早期 · 2018 → 2020BERT、GPT-2 / GPT-3GELU 软开关:按概率衰减负半轴,处处可导
大模型时代 · 2022 → 现在PaLM、LLaMA、Mistral、Qwen、DeepSeekSwiGLU 不是更弯,是多了一个乘号:一路当门、一路当水,逐元素相乘
输出层(所有时代)—不加激活 输出层交给损失函数处理(下一章讲)
SwiGLU 到底在算什么?为什么大模型都用它?

把同一份输入劈成两路:一路学开关、一路学内容,最后逐元素相乘—— 「放多少」由输入自己现场算。三步拆解和流水线图就在下面。

先记一个能复述的画面:值路供水,门路是每根管子上的一只阀门,⊙ 按开度放水——开多大,由流过去的水自己算。

拆开就三步(对着下面的流水线走):

1劈两路同一个 x 分别乘 W₁ 和 W₃——两路都是学出来的投影(d → h),开关和内容可以学出完全不同的东西
2门路过 SwishSwish(u) = u × σ(u)(σ 就是 Sigmoid,输出落在 0~1),拆开就是「内容 u」×「0~1 软开关 σ(u)」:u 负得深就关小,u 为正就放行
3⊙ 相乘,W₂ 压回值路的内容 × 门路的开关系数,逐元素相乘;再由 W₂ 把 h 维压回 d 维——输出的每一位都带着「该放多少」的现场决定

图 · SwiGLU 流水线:一份输入,两路,一个乘号

x (d) W₁ d → h Swish = u × σ(u) 门路 · 学开关 W₃ d → h 值路 · 学内容 ⊙ 逐元素相乘 W₂ h → d 输出 (d)

三个矩阵全是学出来的:W₁ 学「怎么开」、W₃ 学「放什么」、W₂ 把结果压回原宽。 对比 ReLU 那把固定形状的刀——这里的开关是活的,由输入现场决定。

互动 · 拧阀门:每个特征一只,谁先放行由它自己

0.0

SwiGLU 换的只是阀门:σ → Swish(顺滑、处处可导),结构一模一样——再往下那条曲线,画的就是它的标量形状。

互动 · 门控拆开看:一条曲线 × 一路信号

1.00 1.50

把上面流水线中间那个 ⊙ 拉成函数画出来,就是这张曲线图;它读出两条思路的变化: ① 激活函数不再是唯一主角——琥珀色的输出线是青线(门)和蓝线(值)合谋的结果, 单看任何一条都猜不到最后长什么样。 ② 选型从「挑一条曲线」变成「挑一个结构」——所以这一代的论文 (Shazeer 2020,📄 卡里那篇)比的是整族门控搭配,赢的 SwiGLU 后来成了这一代的标配; 它多一个矩阵的代价,上表右下角和第 6 节都已经记过账了。

M

数学 · 一次连乘能传多远

前面几节翻来覆去只有一句话:梯度被一层一层乘回去。可它到底在乘什么? 乘的是每个神经元在它自己那个工作点上的斜率 σ′(z)。 这一节把这件事真的算一遍:公式里的每一个符号,下面图上都有一块看得见的东西。

动画 · 真跑一遍前向,量出每一层真正乘掉的倍率,再把它们连乘起来

σReLU哪把刀 σ′—实测平均斜率 Π 倍率—连乘之后剩多少 max σ′—表格里那个「广告值」

🎯 第 2 节那队传话的人,在这里被真的建了出来

下面这张图不是示意:它真的建了一个网络、喂进去 140 条随机输入,量出每一层每个神经元在自己工作点上的斜率, 再把它们连乘起来——第 2 节说「最后剩多少音量,是所有人的音量相乘」,这里把每个人的音量一个个量给你看。

互动 · 每个符号管图上的哪一块

互动 · 工作点掉进饱和区,斜率就跟着掉下去

图解 · 哪些区段还能传梯度:饱和区到底在哪

互动 · 同一个工作点,七个函数分别把梯度乘掉多少

图解 · 链式法则:梯度每穿过一个神经元,被乘两次
σ′(z) 管「这一刀切掉多少」,x 管「这个权重对结果有多敏感」—— 图里 L 是损失(衡量「错了多少」的那个数,下一章讲),∂ 读作「偏导」,这里就理解为变化率

∂L/∂a 上游传下来的梯度 × σ′(z) 刀在这里切一下 ∂L/∂z 传到前激活值上的梯度 × x 输入也参与 ∂L/∂w 这个权重该改多少
🎬 自己验一遍

把上面「激活函数」切到 Sigmoid,再把「层数」拖到 20,看那条曲线怎么一头栽到最底下; 再切回 ReLU,同样是 20 层,曲线基本是一条平线。
读数条里 max σ′ 和实测平均斜率并排摆着,一眼就能看出「广告值」和「实际值」差多少, ReLU 靠一半的斜率还能把曲线拉平,全靠旁边那个 c = 2(He 初始化)。
c 是激活函数的事,x 是数据的事:链式法则那两次乘法里,只有一次和激活函数有关。

6

没有免费的折纸刀

代价说明
只能表达「连续的分段线性」函数 ReLU 网络的输出一定是连续的折线拼出来的:每一折是直线段,段与段接着。 所以它学不了跳变:目标函数在某一点突然断掉时,网络只能用一条很陡的斜坡去逼近,永远差那一点。 折纸的类比在这里也到头了,纸是连着的,折不出断裂。
SwiGLU 要多花 50% 参数 门控激活需要三个投影矩阵而不是两个(多了一个门)。 但 LLaMA 这类模型把前馈维度从 4× 降到 8/3×,刚好把参数量拉回持平 (FFN = 前馈层,就是 Transformer 里跟在注意力后面的那两层全连接;4× 指隐藏维取输入的 4 倍;d 是输入宽度, 一张 d×4d 的矩阵有 4d² 个数):
标准 FFN(4×)= 4d² + 4d² = 8d²; SwiGLU(8/3×)= 3 × (8/3)d² = 8d²。完全相等。
也就是说 8/3 这个「奇怪的比例」不是拍脑袋的,它的全部意义就是让参数持平。 代价转移到了别处:矩阵变多、显存布局更碎、kernel 融合(把几个小算子合并成一次显存读写)更麻烦
ReLU 不可导且无界 z = 0 处不可导(实际实现里约定导数为 0); 正半轴无上界,深层网络的激活值可能一路涨到溢出
死亡不可逆 如上一节所示,一旦死掉就再也回不来。 LeakyReLU / GELU / Swish 都是在负半轴留一条缝, 代价是负半轴不再恒为 0,输出不再稀疏(ReLU 那一半零输出,本来是个不要钱的正则项)
没有普适最优 CNN 常用 ReLU,Transformer 用 GELU/SwiGLU,RNN 时代用 tanh。 换架构往往要换激活函数,而且没有理论告诉你该换哪个
平滑 ≠ 一定更好 GELU 比 ReLU 平滑,在 Transformer 上确实更好。 但在 ResNet 这类 CNN 上,GELU 原论文(Hendrycks & Gimpel 2016)在 CIFAR-100 的 WideResNet 上只比 ReLU 好约 1 个百分点(错误率 20.74% vs 21.77%,三次中位数)。 「更新、更平滑」不等于「在你的任务上更好」
7

它和哪几章连在一起

章和激活函数的关系
MLP 多层感知机 上一章说了「没有激活函数深度就是幻觉」但没证明。这一章把那个证明补上了(第 1 节那张图)
初始化与训练稳定性 He 初始化里那个「2」就是为 ReLU 准备的。 ReLU 把负的一半直接砍掉,方差减半,所以要乘 √2 补偿——两者是绑定的(第 3 节量过)
归一化层 归一化解决的是「激活值的尺度失控」, 而激活函数决定了「尺度会不会失控」。两者一起决定深层网络能不能训起来
梯度下降与反向传播 反向传播就是那个连乘。激活函数决定每一步乘的数是多少, 所以它直接决定了梯度能不能传到底层
Transformer 前馈层里的 GELU/SwiGLU 就是这一章的函数在真实大模型里的位置
💡 选哪一个(一句话版)

中间层用 ReLU 家族;最后一层通常不加激活——二分类套一个 Sigmoid 就够(第 2 节那张表,只用一次、不存在连乘), 多分类要把一排分数压成概率(加起来等于 1)的 Softmax 则交给损失函数一起算(下一章讲)。
CNN 用 ReLU;Transformer 用 GELU 或 SwiGLU;RNN/LSTM 内部用 tanh。
激活函数的选择很少是性能瓶颈。真正卡住你的是数据、学习率和初始化。 但如果你在训一个很深的网络而它训不动,先检查激活函数和初始化的搭配。

听说「不同的激活函数差别没那么大」,还有论文这么说过——是真的吗?

同代函数之间是真的——理论(都是万能逼近器)和自动搜索(搜出来的 Swish 也只略好一点点、还只在深网络上)都支持; 但代际差和配套差是数量级的:饱和激活在深网里传不动梯度、换刀不换初始化直接训不动,这正是第 3、7 节讲的两件事。

8

小结

这一章看上去是在比七个函数哪个好。但它真正的结论只有一句:没有免费的折纸刀。 而这句话不是顺口说的:下面这张表里每一行都有具体代价。

它对应哪条线 ⑥ 层层组合——没有非线性,叠多少层都塌回一层(第 1 节那张图里 20 层线性网络和 1 层停在同一个函数上); 有了折纸刀,层与层之间才真的能拼出新东西。它同时站在「没有免费午餐」那条线上:没有哪个激活函数对所有架构都是最优的,选它就是在给网络加一条偏好
一句话 激活函数的做法,本质上是在给网络装一把折纸刀:刀的形状决定了网络能折出什么,也决定了梯度能顺着刀刃传回去多远。
它牺牲了什么 牺牲了「平坦好训」和「便宜」(回扣暗线 B)。正半轴导数恒为 1 的那个 ReLU,是把负半轴整段扔掉换来的, 于是它自己丢掉了一半信号(靠初始化补),也埋下了死亡不可逆;要补那条缝就得引入超参;要顺滑就得付参数(SwiGLU 的 +50%,靠 8/3× 才拉回来)。
换来的东西同样实在:深度第一次真的有意义了——否则第 1 节那张图里两边会重合。
💡 检验一下:你现在能指着哪个互动说这句话

回到第 2 节把「探针位置 z」拖到 −5,再回到第 3 节把 ReLU 和 Sigmoid 摆在同一条 20 层的轴上对比:一个是平线,一个一头栽到底。
哪两个数字互相矛盾(max σ′ 和实测平均斜率)、这一章怎么解释它。讲得出来,这一节才算真的带走了。

为什么是「层层组合」,而不是别的线

线为什么这章不是它
② 没有免费午餐 沾边:七个函数各有它不适用的场景(第 6 节那张代价表)。这条线是背景,这一章的主张在 ⑥
⑥ 层层组合 ✅ 这章真正的位置:没有激活,叠多少层线性层还是一个线性层—— 第 1 节那张图里两边停在同一个函数上;有了折纸刀,层与层之间才真的能拼出新东西

它在六条暗线里站在哪

暗线这一章的回答
A 信息流动 激活函数是少数几个不改变张量形状的算子之一:输入 (B, d),输出还是 (B, d) (B 是一批喂进去的样本数,d 是每个样本的特征数),一进一出逐元素算, 不看邻居、也不混合通道。归一化层虽然也保形,但它会跨特征混合;激活函数不混。
形状不变,但数值分布会被改变。这正是为什么它必须和归一化层、初始化尺度一起设计
B 什么被牺牲了 牺牲了数学上的舒服:处处可导、有上界、可逆。 ReLU 在 0 处不可导、正半轴无上界;SwiGLU 多花 50% 参数;死亡不可逆
C 参数账本 激活函数自己没有参数(PReLU 是唯一例外,每个通道 1 个 α,几乎可以忽略)。 但它能改变整个网络的参数量:SwiGLU 把前馈层从 2 个投影变成 3 个, LLaMA 这类模型用 8/3× 的前馈维度把它拉回到 8d² = 8d²,与标准 4× FFN 持平。 计算量上 GELU/SiLU 每个元素多算一次 erf/exp,但在真实模型里这个开销可以忽略
D 跑在什么上 带宽受限,不是算力受限。激活是逐元素运算,算术强度(每从显存搬一个数,能做几次计算)不到 1: 从显存读一个数、做一两次乘加、再写回去。所以它几乎总在等显存。
这也解释了为什么更贵、更平滑的 GELU 在大模型里并不比 ReLU 慢多少:逐元素的激活算得很快,大模型的时间主要花在矩阵乘和搬数据上。完整的算术强度账在 《硬件与算力账本》
E 它假设了什么 假设「非线性应该长成这个形状」。ReLU 赌「负的那半边没用」(稀疏是好事); GELU 赌「负的还有点用,但按概率衰减」;Swish 赌「负半轴该留个小坑」。 它们都是在赌数据的统计形状:换数据集,赌注可能会输
F 违背了哪个直觉 直觉是「导数最大值越大,梯度越不容易消失」。这是错的。 tanh 的最大导数是 1.0,但它在两端照样归零; 真正要看的是「工作点上的斜率 × 初始化给它配的尺度」,第 3 节那个滑块量的就是它, 第 M 节那张图把两个数分开摆在同一个读数条里
🎯 前后钩子

它接住了上一章的什么:《MLP 多层感知机》说了「深度就是幻觉」这个结论, 这一章把它算出来了:20 层线性网络的最大误差停在 1e-13,那是浮点精度,不是模型误差。

它给下一章留了什么:《损失函数》拿这一章折出的数算「错了多少」。

它给更后面留了什么:连乘能不能传下去,还看起点—— 《初始化与训练稳定性》里 He 初始化就为 ReLU 补上那一半, 激活函数和初始化是一对,不能分开选。

一句话带走激活函数

激活函数 = 网络的折纸刀。没有它,深度就是幻觉, 20 层线性网络和 1 层在数学上完全相同,这是算出来的,不是比喻。
ReLU 赢在正半轴导数恒为 1,再配上 He 初始化给的 √2,每层倍率正好回到 1.0, 梯度能穿过几十层不衰减;Sigmoid 每层只剩 0.23,20 层之后归零。差别全在「初始化有没有为它补上那一半」。
ReLU 自己的代价是死亡神经元不可逆:负半轴导数恒为 0,一旦死掉就再也回不来。 LeakyReLU / GELU / Swish 都是给负半轴留缝。
所以呢?看到「更平滑更先进」的激活函数时先别急着换,先确认你的初始化和它是配套的。

9

拓展阅读

上面讲的都是「够用」的版本。想往下挖,这里有三个入口—— 它们不是必修内容,是给想再往前走一步的读者准备的。

📄 这一章的说法从哪来

💻 工业界怎么写

∑ 更严格的形式

正文为了讲清楚,把一处关键的地方简化了。补上这一条,第 3 节那张「每层乘多少」的曲线才算完整, 它也是「ReLU 为什么能训得很深」真正的答案。

第 1 条 · 每层真正乘掉的不是斜率,是「初始化尺度 × 斜率」

正文第 3 节说「每层乘掉一个数」:那个数不是斜率本身,而是上面这个 r。
c 是初始化给这把刀配的权重方差系数:ReLU / GELU / Swish 这类「负半轴基本不吃」的函数用 c = 2(He 初始化),Sigmoid / tanh 用 c = 1(Xavier)。
ReLU 的斜率只有 0.51,但那个 √2 把它补了回来:r = √2 × √0.51 ≈ 1.01,正好是 1。 这才是 He 初始化存在的全部意义:不是为了让网络更深,是为了让梯度能原样传回去。
Sigmoid 没有这半个补丁:r = 1 × √0.055 ≈ 0.235,每层都在漏,20 层之后只剩 10⁻¹³。 第 3 节那条曲线上的数字,量的就是这个 r。

第 2 条 · 那个 √2 是从哪解出来的

一行一行读:n 是这一层有多少个输入,σw 是权重的标准差(这个 σw 和 Sigmoid 的 σ 不是一个东西),Var(x) 是上一层输出的「散度」。
第一行说「输出的散度 = 输入的散度 × n × 权重方差」;第二行说「ReLU 把负的一半砍掉,散度也跟着砍一半」; 第三行说「想让这一层进出的散度一样大」,也就是「不放大也不缩小」。
把三行合起来解一下,就得到 σw² = 2/n。那个 2 不是拍脑袋的,是解出来的。 第 3 节那个「配对实验台」量过两把错钥匙:Sigmoid 套上 He 的 2,梯度照样跌到 10⁻¹⁰;tanh 套上 He 的 2,梯度反而一路涨,20 层就 ×19。