为什么需要激活函数?
神经网络的每一层本质上是一个线性变换:z = Wx + b。如果只有线性变换,那么无论堆多少层,整个网络仍然是一个线性函数——这就像把多个直线叠加在一起,结果还是一条直线。
一个简单的数学事实:
无激活函数的两层网络: y = W₂(W₁x + b₁) + b₂ = (W₂W₁)x + (W₂b₁ + b₂) = W'x + b' 仍然是线性变换!
生活比喻:为什么世界不是直线?
想象一个只能做加法的唯一计算器。你给它 2,它回答 4;给 5,回答 10。这就是线性——输入和输出是简单的正比例关系。但现实世界的问题(图片分类、语音识别、自然语言理解)绝对不是简单的正比例关系。
激活函数的作用:
- 引入非线性:让网络能学习复杂的曲线和模式
- 保持输出范围可控:防止数值爆炸或过小
- 提供源池度:每个激活函数都有可导的形式,支持反向传播
这一章我们将详细学习 5 种最常用的激活函数:Sigmoid、Tanh、ReLU、GELU、Softmax。
Sigmoid 激活函数
Sigmoid是最早期的激活函数之一,它的输出范围是 (0, 1),可以理解为“开关的∞滑版”——不是粗糙的 0/1 开关,而是从 0 到 1 的渐变。
生活比喻:光线调光器
想象一个调光器——你不是只能开或关灯,而是可以缓慢旋转扭扭来调节亮度。当输入值很大时(大力旋扭),灯光达到最亮(1);输入值很小时(反向旋扭),灯光完全熄灭(0);在中间区域(输入接近 0),小幅度旋转会产生显著变化。
公式:
σ(x) = 1 / (1 + e^{-x})导数(记住这个,反向传播会用):
σ'(x) = σ(x) × (1 - σ(x))
Sigmoid 的导数能用输出值本身表示,这是它的一大便利之处。
优缺点:
- ✔ 输出在 (0,1),可作概率解释
- ✔ 平滑可导,导数计算简单
- ✘ 梯度消失(两端导数趋近 0)
- ✘ 输出不是零中心的(所有输出 >0)→ 上一层梯度全部正或全部负
- ✘ 指数计算消耗较大
Sigmoid 公式与参数
<p><b>公式:</b></p><pre>σ(x) = 1 / (1 + e^{-x})</pre><pre>σ'(x) = σ(x)(1 - σ(x))</pre><p><b>参数表:</b></p><table><tr><th>参数</th><th>值</th><th>说明</th></tr><tr><td>输入范围</td><td>(-∞, +∞)</td><td>任意实数</td></tr><tr><td>输出范围</td><td>(0, 1)</td><td>非负,小于1</td></tr><tr><td>f(0)</td><td>0.5</td><td>原点处中间值</td></tr><tr><td>最大导数</td><td>0.25 (x=0时)</td><td>原点处变化最大</td></tr><tr><td>f(5)</td><td>≈ 0.9933</td><td>正方向趋于饱和</td></tr><tr><td>f(-5)</td><td>≈ 0.0067</td><td>负方向趋于饱和</td></tr></table><p><b>步骤化推导过程:</b></p><ol><li>σ(x) = (1 + e^{-x})^{-1}</li><li>设gu = 1 + e^{-x},则σ = u^{-1}</li><li>dσ/du = -u^{-2} = -(1 + e^{-x})^{-2}</li><li>du/dx = -e^{-x}</li><li>链式法则:σ'(x) = -(1 + e^{-x})^{-2} × (-e^{-x}) = e^{-x} / (1 + e^{-x})^2</li><li>化简:σ'(x) = [1/(1+e^{-x})] × [e^{-x}/(1+e^{-x})] = σ(x) × (1 - σ(x)) ✓</li></ol>Sigmoid 数值例子
给定输入 x = [-3, -1, 0, 1, 3],计算每个点的 Sigmoid 值和导数。
步骤 1:计算指数部分
| x | e^{-x} | 1 + e^{-x} | σ(x) | σ'(x) |
|---|---|---|---|---|
| -3 | e^{3} ≈ 20.0855 | 21.0855 | 0.0474 | 0.0452 |
| -1 | e^{1} ≈ 2.7183 | 3.7183 | 0.2689 | 0.1966 |
| 0 | e^{0} = 1.0000 | 2.0000 | 0.5000 | 0.2500 |
| 1 | e^{-1} ≈ 0.3679 | 1.3679 | 0.7311 | 0.1966 |
| 3 | e^{-3} ≈ 0.0498 | 1.0498 | 0.9526 | 0.0452 |
步骤 2:验证导数公式
以 x=0 为例:
σ(0) = 0.5 σ'(0) = 0.5 × (1 - 0.5) = 0.5 × 0.5 = 0.25 ✓
观察:
- x=0 时导数最大 (0.25),变化最敏感
- x=±3 时导数已经很小 (0.045),进入饱和区
- x=±5 时导数≈ 0.0067,基本“死亡”——梯度消失
生活比喻补充:
调光器在最暗和最亮的两端时,你小幅旋转基本看不出变化;但在中间位置(灯光一半亮)时,稍微旋动就能看到显著变化。这就是“中间区域敏感”的直觉。
Sigmoid 练习
Q1:计算 x = 2 时 Sigmoid 的值和导数。
Q2:为什么 Sigmoid 导数最大值是 0.25?请推导证明。
Q3:如果神经网络所有层都用 Sigmoid,深层网络会遇到什么问题?请用数学解释。
Q4:设输入 x = [-10, -0.5, 0, 0.5, 10],并列表计算每个点的 Sigmoid 值。哪些点处于饱和区域?
Q5:Sigmoid 的输出范围在 (0,1),如果我们需要输出在 (-1,1),应该怎么做?(提示:这就是 Tanh)
查看答案
A1:
σ(2) = 1 / (1 + e^{-2}) = 1 / (1 + 0.1353) = 0.8808
σ'(2) = 0.8808 × (1 - 0.8808) = 0.8808 × 0.1192 = 0.1050A2:
设g(x) = σ(x)(1 - σ(x)) = σ(x) - σ(x)^2。对 g 求导:g'(x) = σ'(x) - 2σ(x)σ'(x) = σ'(x)(1 - 2σ(x))。令 g'(x) = 0,得σ(x) = 0.5,即 x = 0。带入:max(σ'(x)) = 0.5 × 0.5 = 0.25。
A3:
梯度消失问题。设网络有 L 层,每层导数最大为 0.25,则链式法则下梯度 < 0.25^L。当 L=10 时,0.25^{10} ≈ 9.5 × 10^{-7},几乎为零,使得深层权重无法更新。这就是为什么深层网络不用 Sigmoid,而用 ReLU。
A4:
| x | e^{-x} | σ(x) | 饱和? |
|---|---|---|---|
| -10 | 22026.4658 | 0.000045 | ✔ 负向饱和 |
| -0.5 | 1.6487 | 0.3775 | ✘ 敏感区 |
| 0 | 1.0000 | 0.5000 | ✘ 敏感区 |
| 0.5 | 0.6065 | 0.6225 | ✘ 敏感区 |
| 10 | 0.000045 | 0.999955 | ✔ 正向饱和 |
只有 |x| 大于约 5 时才进入饱和区域。
A5:
对 Sigmoid 做线性变换:
Tanh(x) = 2 × σ(2x) - 1
这会将输出范围从 (0,1) 映射到 (-1,1)。下一节我们就学习 Tanh。
Tanh 激活函数
Tanh(双曲正切)是 Sigmoid 的“升级版”。它的输出范围是 (-1, 1),中心为 0。这意味着它的输出可以是负数,这对于下一层的学习非常重要。
生活比喻:秋千
秋千从最高点前方 (+1) 经过底部 (0) 到最高点后方 (-1)。它是对称的,能正能负。这就是“零中心”的直觉——输出包含正负信号。
为什么零中心重要?
如果所有输出都是正数(如 Sigmoid),那么上一层的梯度全部正或全部负,导致权重只能往同一个方向更新,收敛慢。Tanh 的零中心特性解决了这个问题。
公式:
tanh(x) = (e^x - e^{-x}) / (e^x + e^{-x})导数:
tanh'(x) = 1 - tanh(x)^2
优缺点:
- ✔ 零中心,收敛速度通常快于 Sigmoid
- ✔ 导数计算简单
- ✘ 仍然存在梯度消失问题(两端导数趋近 0)
- ✘ 指数计算消耗大
Tanh 公式与参数
<p><b>公式:</b></p><pre>tanh(x) = (e^x - e^{-x}) / (e^x + e^{-x})</pre><pre>tanh(x) = (1 - e^{-2x}) / (1 + e^{-2x})</pre><pre>tanh'(x) = 1 - tanh(x)^2 = sech(x)^2</pre><p><b>参数表:</b></p><table><tr><th>参数</th><th>值</th><th>说明</th></tr><tr><td>输入范围</td><td>(-∞, +∞)</td><td>任意实数</td></tr><tr><td>输出范围</td><td>(-1, 1)</td><td>零中心</td></tr><tr><td>f(0)</td><td>0</td><td>原点处为 0</td></tr><tr><td>最大导数</td><td>1 (x=0时)</td><td>比 Sigmoid (0.25) 大 4 倍</td></tr><tr><td>f(2)</td><td>≈ 0.9640</td><td>趋于正向饱和</td></tr><tr><td>f(-2)</td><td>≈ -0.9640</td><td>趋于负向饱和</td></tr></table><p><b>步骤化推导过程(导数):</b></p><ol><li>tanh(x) = (e^x - e^{-x}) / (e^x + e^{-x})</li><li>设u = e^x - e^{-x}, v = e^x + e^{-x},法则:(u/v)' = (u'v - uv')/v^2</li><li>u' = e^x + e^{-x} = v</li><li>v' = e^x - e^{-x} = u</li><li>tanh'(x) = (v·v - u·u) / v^2 = (v^2 - u^2) / v^2 = 1 - (u/v)^2 = 1 - tanh(x)^2 ✓</li></ol>Tanh 数值例子
给定输入 x = [-3, -1, 0, 1, 3],计算 Tanh 值和导数。
Step 1:计算 e^x 和 e^{-x}
| x | e^x | e^{-x} | e^x-e^{-x} | e^x+e^{-x} | tanh(x) | tanh'(x) |
|---|---|---|---|---|---|---|
| -3 | 0.0498 | 20.0855 | -20.0357 | 20.1353 | -0.9951 | 0.0099 |
| -1 | 0.3679 | 2.7183 | -2.3504 | 3.0862 | -0.7616 | 0.4200 |
| 0 | 1.0000 | 1.0000 | 0.0000 | 2.0000 | 0.0000 | 1.0000 |
| 1 | 2.7183 | 0.3679 | 2.3504 | 3.0862 | 0.7616 | 0.4200 |
| 3 | 20.0855 | 0.0498 | 20.0357 | 20.1353 | 0.9951 | 0.0099 |
Step 2:验证导数公式
以 x=1 为例:
tanh(1) = 0.7616 tanh'(1) = 1 - 0.7616^2 = 1 - 0.5800 = 0.4200 ✓
对比 Sigmoid 和 Tanh:
| 性质 | Sigmoid | Tanh |
|---|---|---|
| 输出范围 | (0, 1) | (-1, 1) |
| 是否零中心 | ✘ | ✔ |
| 最大导数 | 0.25 | 1.0 |
| 收敛速度 | 较慢 | 较快 |
Tanh 的导数范围更大(最大为 1),这意味着梯度更强,基本上所有场晨 Tanh 都优于 Sigmoid。
Tanh 练习
Q1:计算 x = 2 时 Tanh 的值和导数。
Q2:用 Sigmoid 表示 Tanh:证明 tanh(x) = 2σ(2x) - 1。
Q3:为什么零中心特性能加速收敛?请从梯度更新角度解释。
Q4:已知神经网络中一层的输出均值为 0.6,用的是 Sigmoid。如果换成 Tanh,对下一层的梯度会有什么影响?
Q5:绘制 Sigmoid 和 Tanh 的函数图像,标出它们的关键差异点。
查看答案
A1:
e^2 = 7.3891, e^{-2} = 0.1353
tanh(2) = (7.3891 - 0.1353) / (7.3891 + 0.1353) = 7.2538 / 7.5244 = 0.9640
tanh'(2) = 1 - 0.9640^2 = 1 - 0.9293 = 0.0707A2:
σ(2x) = 1 / (1 + e^{-2x})
2σ(2x) - 1 = 2/(1+e^{-2x}) - 1 = (2 - (1+e^{-2x}))/(1+e^{-2x}) = (1-e^{-2x})/(1+e^{-2x}) = tanh(x) ✓A3:
设previous layer output 均值为 µ。若µ > 0(如 Sigmoid),则梯度更新 W = W - α·µ·∇L→ 所有权重同方向更新,需要“zigzag”收敛。若µ ≈ 0(Tanh零中心),则梯度更新方向更多样,收敛更快。这类似于PCA白化的效果。
A4:
Sigmoid 输出均值为 0.6,那么所有梯度都乘以了一个偏移量,导致下一层权重更新在某个方向上偏移。换成 Tanh(均值趋近 0)后,梯度分布更均匀,类似于数据标准化的效果。
A5:
关键差异点:
- Tanh 经过原点 (0,0),Sigmoid 经过 (0,0.5)
- Tanh 对称,值域 (-1,1);Sigmoid 非对称,值域 (0,1)
- Tanh 原点处斜率更陡(1 vs 0.25)
ReLU 激活函数
ReLU(修正线性单元,Rectified Linear Unit)是当前最常用的激活函数。它的形式极其简单:正数保持不变,负数变为 0。
公式:
ReLU(x) = max(0, x)
导数:
ReLU'(x) = 1 如果 x > 0, 0 如果 x < 0 在 x = 0 处不可导(实际使用时当作导数为 1)
生活比喻:过滤器网络、水管防回流阀
想象一个只允许水流向一个方向的阀门——正向水压时水通过;反向水压时完全拦截。这就是 ReLU:正信号直接通过,负信号被“截断”。
优缺点:
- ✔ 计算极简单,比 Sigmoid/Tanh 快多了(无指数)
- ✔ 正区间导数恒为 1,无梯度消失问题
- ✔ 勇敢性质使得网络更稀疏(大量神经元输出为 0)
- ✘ Dead ReLU:网络初始化不好或学习率过大时,部分神经元输入始终 < 0,导数为 0,就再也不会更新了
- ✘ 输出不是零中心的
Leaky ReLU(改进版):
LeakyReLU(x) = max(0.01x, x)
让负区间也有一个很小的斜率(0.01),解决 Dead ReLU 问题。另外还有 PReLU(参数化)和 ELU(指数线性单元)。
ReLU 公式与参数
<p><b>公式(包括变种):</b></p><table><tr><th>名称</th><th>公式</th><th>特点</th></tr><tr><td>ReLU</td><td>max(0, x)</td><td>最简单,被证明最有效的基础激活</td></tr><tr><td>Leaky ReLU</td><td>max(αx, x), α=0.01</td><td>负区间小斜率,解决Dead ReLU</td></tr><tr><td>PReLU</td><td>max(αx, x), α可学习</td><td>α是参数,跟权重一起训练</td></tr><tr><td>ELU</td><td>x (x≥0), α(e^x-1) (x<0)</td><td>负区间趋于-α,更稳定</td></tr></table><p><b>参数表(ReLU):</b></p><table><tr><th>参数</th><th>值</th><th>说明</th></tr><tr><td>输入范围</td><td>(-∞, +∞)</td><td>任意实数</td></tr><tr><td>输出范围</td><td>[0, +∞)</td><td>非负</td></tr><tr><td>ReLU(0)</td><td>0</td><td>不可导点</td></tr><tr><td>导数(x>0)</td><td>1</td><td>恒为 1,无梯度消失</td></tr><tr><td>导数(x<0)</td><td>0</td><td>Dead ReLU 原因</td></tr><tr><td>计算量</td><td>O(1)</td><td>一个 if 判断</td></tr></table><p><b>梯度消失对比测试:</b></p><p>设深度为 10 层的网络:</p><pre>Sigmoid: 梯度 < 0.25^10 ≈ 9.5e-7 (死亡) ReLU: 梯度 = 1^10 = 1 (完好)</pre><p>这就是为什么深层网络几乎都用 ReLU 而不用 Sigmoid。</p>
ReLU 数值例子
给定输入 x = [-5, -2, -0.1, 0, 0.5, 3, 10],计算 ReLU 值和导数。
计算表:
| x | ReLU(x) | ReLU'(x) | 状态 |
|---|---|---|---|
| -5 | 0 | 0 | 死亡 |
| -2 | 0 | 0 | 死亡 |
| -0.1 | 0 | 0 | 临界(接近 0) |
| 0 | 0 | 未定义 | 单点不可导 |
| 0.5 | 0.5 | 1 | 活跃 |
| 3 | 3 | 1 | 活跃 |
| 10 | 10 | 1 | 活跃 |
一个完整的前向传播例子:
假设一层神经网络,权重 W = [0.5, -0.3, 0.8],偏置 b = 0.1,输入 x = [2, -1, 3]。
步骤 1: z = W·x + b = 0.5×2 + (-0.3)×(-1) + 0.8×3 + 0.1
= 1.0 + 0.3 + 2.4 + 0.1
= 3.8
步骤 2: a = ReLU(3.8) = max(0, 3.8) = 3.8如果换一组输入 x = [-2, 1, -0.5]:
z = 0.5×(-2) + (-0.3)×1 + 0.8×(-0.5) + 0.1 = -1.0 - 0.3 - 0.4 + 0.1 = -1.6 a = ReLU(-1.6) = 0
这个神经元对于这个样本“死亡”了。如果所有样本对该神经元的 z 都 < 0,它就永远不会更新了——Dead ReLU。
ReLU 练习
Q1:计算如下输入的 ReLU 值:x = [-100, -0.001, 0, 0.001, 100]。请问有几个点的导数为 0?
Q2:什么是 Dead ReLU 现象?如何检测和解决?
Q3:ReLU 在 x=0 处不可导,实际训练中怎么办?
Q4:一层 ReLU 网络有 100 个神经元,输入数据的 80% 使得 z < 0。这意味着什么?如何优化?
Q5:计算一个 ReLU 神经元的反向传播:假设上游梯度 dL/da = 2,输入 z = -1,请问 dL/dz 是多少?如果 z = 3,dL/dz 又是多少?
查看答案
A1:
x = -100 → ReLU = 0, 导数 = 0 x = -0.001 → ReLU = 0, 导数 = 0 x = 0 → ReLU = 0, 导数未定义 x = 0.001 → ReLU = 0.001, 导数 = 1 x = 100 → ReLU = 100, 导数 = 1
2 个点的导数为 0(不算 x=0)。
A2:
当神经元的权重初始化处在“负区域”,或学习率过大导致权重跳到“永远负”的区域时,该神经元对所有输入都输出 0,梯度为 0,再也不会更新。
检测:训练中监控神经元输出为 0 的比例。
解决:用 Leaky ReLU/PReLU,或调整初始化(如 He 初始化)。
A3:
实际中简单处理:当 x > 0 时导数为 1,x ≤ 0 时导数为 0。由于计算机浮点数准确等于 0 的概率极低,这个问题实际上不会出现。
A4:
80% 的神经元“死亡”意味着网络的表示能力大幅下降。可能原因:学习率过大、偏置初始化不当。优化:降低学习率、使用 He 初始化、换 Leaky ReLU。
A5:
反向传播:dL/dz = ReLU'(z) × dL/da
当 z = -1: ReLU'(-1) = 0 → dL/dz = 0 × 2 = 0 当 z = 3: ReLU'(3) = 1 → dL/dz = 1 × 2 = 2
所以 ReLU 的反向传播极其简单——活跃时直接传递梯度,死亡时切断梯度。
GELU 激活函数
GELU(「《嘉德尔》激活函数,Gaussian Error Linear Unit)是 Transformer 时代的标配激活函数。它被 BERT、GPT 系列、LLaMA 等所有现代 LLM 使用。
公式:
GELU(x) = x × Φ(x)
其中 Φ(x) 是标准正态分布的累积分布函数(CDF)。
近似公式(实际使用):
GELU(x) ≈ 0.5x × (1 + tanh(√(2/π) × (x + 0.044715x^3)))
生活比喻:温柔的选择器
ReLU 像一个粗糙的“是”“否”开关。GELU 则像一个小组成员投票——每个输入都根据它的“可能性”被权重虎决。如果 x 正且大(“是”的可能性高),就保持大部分值;如果 x 负且小(“否”的可能性高),就压制到接近 0;如果 x 在 0 附近,则根据正态分布做平滑决策。
优缺点:
- ✔ 平滑且全局可导(比 ReLU 更“自然”)
- ✔ 输出在负区域也有小的非零值,保留部分信息
- ✔ 在 Transformer 中效果经典验证优于 ReLU
- ✘ 计算成本高于 ReLU(需要计算正态 CDF 或 tanh 近似)
Swish/SiLU(另一个相似的激活函数):
Swish(x) = x × σ(x) = x / (1 + e^{-x})GELU 和 Swish 非常接近,在实际应用中(如 Transformer)效果几乎一样。LLaMA 用的 SwiGLU 就是 Swish 的变种。
GELU 公式与参数
<p><b>精确公式:</b></p><pre>GELU(x) = x × Φ(x) = x × P(X ≤ x)
其中 X ~ N(0,1)</pre><p>Φ(x) = ∫_{-\infty}^{x} (1/√(2π)) × e^{-t^2/2} dt</p><p><b>近似公式(Tanh 近似):</b></p><pre>GELU(x) ≈ 0.5x × (1 + tanh(√(2/π) × (x + 0.044715x^3)))</pre><p><b>更简单的近似:</b></p><pre>GELU(x) ≈ x × σ(1.702x)</pre><p>其中 σ 是 Sigmoid,1.702 是最优缩放匹配值。</p><p><b>参数表:</b></p><table><tr><th>参数</th><th>值</th><th>说明</th></tr><tr><td>输入范围</td><td>(-∞, +∞)</td><td>任意实数</td></tr><tr><td>输出范围</td><td>≈ [-0.17, +∞)</td><td>最小值约 -0.17</td></tr><tr><td>GELU(0)</td><td>0</td><td>经过原点</td></tr><tr><td>最小值</td><td>≈ -0.17 (x ≈ -0.75时)</td><td>负区域有小的负值</td></tr><tr><td>正向趋势</td><td>x → +∞, GELU → x</td><td>大正数时近似线性</td></tr><tr><td>负向趋势</td><td>x → -∞, GELU → 0</td><td>大负数时压制为 0</td></tr></table><p><b>导数简介(复杂,真实实现用自动微分):</b></p><pre>GELU'(x) = Φ(x) + x × φ(x)
其中 φ(x) = N(0,1) 的概率密度函数 = (1/√(2π))e^{-x^2/2}</pre>GELU 数值例子
给定输入 x = [-3, -1, -0.75, -0.5, 0, 0.5, 1, 3],用近似公式计算 GELU 值。
近似公式: GELU(x) ≈ 0.5x × (1 + tanh(0.79788 × (x + 0.044715x^3)))
计算步骤(以 x=1 为例):
步骤 1: x^3 = 1^3 = 1 步骤 2: x + 0.044715x^3 = 1 + 0.044715 = 1.044715 步骤 3: √(2/π) ≈ 0.79788 步骤 4: 0.79788 × 1.044715 = 0.8336 步骤 5: tanh(0.8336) ≈ 0.6827 步骤 6: 0.5 × 1 × (1 + 0.6827) = 0.5 × 1.6827 = 0.8414
完整结果:
| x | x + 0.0447x^3 | inner | tanh | GELU(x) |
|---|---|---|---|---|
| -3.00 | -4.207 | -3.357 | -0.998 | 0.003 |
| -1.00 | -1.045 | -0.834 | -0.683 | -0.159 |
| -0.75 | -0.731 | -0.583 | -0.525 | -0.178 |
| -0.50 | -0.506 | -0.404 | -0.384 | -0.154 |
| 0.00 | 0.000 | 0.000 | 0.000 | 0.000 |
| 0.50 | 0.506 | 0.404 | 0.384 | 0.346 |
| 1.00 | 1.045 | 0.834 | 0.683 | 0.841 |
| 3.00 | 4.207 | 3.357 | 0.998 | 2.997 |
关键观察:
- GELU 在负区域有一个小的负最小值≈ -0.17(而 ReLU 为 0)
- 这意味着负值不是直接截断,而是“遵循”地压制
- 这小小的差异让 Transformer 更容易传播梯度
GELU 练习
Q1:用简化近似 GELU(x) ≈ x × σ(1.702x) 计算 x = 2 时的值。
Q2:GELU 和 ReLU 有什么本质区别?为什么 Transformer 选择 GELU 而不是 ReLU?
Q3:计算 GELU 在 x = -0.75 处的值,并解释这个负值对网络有什么作用。
Q4:Swish 和 GELU 有什么关系?试比较 Swish(x) = xσ(x) 和 GELU(x) 的近似形式 xσ(1.702x)。你能看出什么?
Q5:为什么 GELU 的负区域导数不为 0?这对梯度传播有什么好处?
查看答案
A1:
x = 2
1.702x = 3.404
σ(3.404) = 1 / (1 + e^{-3.404}) = 1 / (1 + 0.0333) = 0.9678
GELU(2) ≈ 2 × 0.9678 = 1.9356A2:
ReLU 是硬截断(x<0 时为 0),GELU 是平滑压制(x<0 时仍有非零值、非零导数)。
Transformer 选 GELU 的原因:
- GELU 处处可导,对梯度传播更友好
- 负区域的小非零值保留部分信息
- 在大规模训练中表现更稳定
A3:
由上表,GELU(-0.75) ≈ -0.178
这个负值意味着当输入是负的但负得不多时,神经元仍然传递一个小的负信号。这可以帮助网络学习更精细的模式,而不是粗糙地抛弃所有负信息。
A4:
Swish(x) = xσ(x) = x/(1+e^{-x})。而 GELU 的近似是 xσ(1.702x),也就是说 GELU ≈ Swish(1.702x),仅仅是将 Swish 的输入缩放了约 1.7 倍。两者几乎一样,在实际应用中效果相似。
A5:
GELU 在负区域的导数不为 0,意味着当神经元输入为负时,梯度仍然能够流回去更新权重。这解决了“Dead ReLU”问题,让 Transformer 的深层网络更稳定地训练。
Softmax 激活函数
Softmax不是和前四个一样的“神经元内”激活函数——它通常用在网络的最后一层,将一个任意的实数向量转化为一个概率分布。
生活比喻:投票统计
想象公司选择 CEO,有 3 位候选人:得票数分别是 100、500 2000。如果直接看得票比例:4.5%、22.7%、72.7%。但如果给候选人的“得分”是 80、85、90,直接比例是 31.4%、33.3%、35.3%,差距不大。Softmax 能将“得分差距”放大(通过指数),让高分者获得更大的概率。
公式:
Softmax(z)ᵢ = e^{zᵢ} / ∑ⱼₗ₁ e^{zⱼ}其中 z 是输入向量,zᵢ 是第 i 个元素。
Softmax 特性:
- 输出合为 1:∑ Softmax(z)ᵢ = 1
- 每个输出在 (0, 1) 之间
- Α虑相对大小关系:输入越大,输出概率越大
- 指数操作放大差距(“勇敢”决策)
温度参数版:
Softmaxτ(z)ᵢ = e^{zᵢ/τ} / ∑ e^{zⱼ/τ}τ > 1:分布更“平坦”(温和);τ < 1:分布更“尖锐”(极端)。这在知识蒸馏(Knowledge Distillation)和语言模型的采样中常用。
导数:
∂Sᵢ/∂zⱼ = Sᵢ(δᵢⱼ - Sⱼ) 其中 δᵢⱼ = 1 当 i = j, 否则 0
这意味着:
- 对自己的导数:∂Sᵢ/∂zᵢ = Sᵢ(1 - Sᵢ)
- 对其他的导数:∂Sᵢ/∂zⱼ = -SᵢSⱼ
Softmax 公式与参数
<p><b>公式:</b></p><pre>Softmax(z)ᵢ = e^{zᵢ} / ∑_{j=1}^{k} e^{z_j}</pre><p>其中 z 是长度为 k 的向量。</p><p><b>参数表:</b></p><table><tr><th>参数</th><th>说明</th></tr><tr><td>输入</td><td>任意实数向量 z ∈ ℝ^k</td></tr><tr><td>输出</td><td>概率向量 p ∈ [0,1]^k,∑p = 1</td></tr><tr><td>常用场景</td><td>分类网络最后一层、注意力权重</td></tr><tr><td>配套损失</td><td>Cross-Entropy Loss</td></tr><tr><td>导数优化</td><td>Softmax + CE 的梯度 = ŷ - y(即预测减真实)</td></tr></table><p><b>“Softmax + CrossEntropy”梯度推导:</b></p><p>设y = [0, 1, 0, ..., 0] 为 one-hot 真实标签,ŷ = softmax(z)。</p><pre>Loss = -∑ y_j · log(ŷ_j) = -log(ŷ_c)
其中 c 是真实类别
∂L/∂z = ŷ - y
举例:ŷ = [0.2, 0.7, 0.1], y = [0, 1, 0]
∂L/∂z = [0.2, -0.3, 0.1]</pre><p>这是<a>【最美的公式之一】</a>:分类网络的反向传播梯度简直就是“预测减真实”。</p><p><b>数值稳定性技巧:</b></p><pre>不稳定版: ŷ_i = e^{z_i} / ∑ e^{z_j}
稳定版(推荐):ŷ_i = e^{z_i - max(z)} / ∑ e^{z_j - max(z)}</pre><p>减去最大值不改变结果,但防止 e^{z_i} 溢出。</p>Softmax 数值例子
给定输入向量 z = [1, 2, 3],计算 Softmax 输出。
步骤 1:计算指数
e^1 = 2.7183 e^2 = 7.3891 e^3 = 20.0855 总和 = 2.7183 + 7.3891 + 20.0855 = 30.1929
步骤 2:计算概率
p_1 = 2.7183 / 30.1929 = 0.0900 p_2 = 7.3891 / 30.1929 = 0.2447 p_3 = 20.0855 / 30.1929 = 0.6652 验证:0.0900 + 0.2447 + 0.6652 = 0.9999 ≈ 1.0 ✓
步骤 3:数值稳定版
max(z) = 3
z' = [1-3, 2-3, 3-3] = [-2, -1, 0]
e^{-2} = 0.1353
e^{-1} = 0.3679
e^{0} = 1.0000
总和 = 1.5033
p_1 = 0.1353/1.5033 = 0.0900
p_2 = 0.3679/1.5033 = 0.2447
p_3 = 1.0000/1.5033 = 0.6652 ✓对比:预测 versus 真实
如果真实标签 y = [0, 0, 1],则:
CrossEntropy = -[0×log(0.09) + 0×log(0.245) + 1×log(0.665)]
= -log(0.665) = 0.408梯度 dL/dz = ŷ - y = [0.0900, 0.2447, 0.6652] - [0, 0, 1] = [0.0900, 0.2447, -0.3348]。这意味着第三个类别的输入要下降,前两个要上升。
Softmax 练习
Q1:计算输入 z = [2, 1, 0] 的 Softmax 输出。
Q2:如果真实标签 y = [1, 0, 0],预测 ŷ = Softmax(z) = [0.7, 0.2, 0.1],计算 Cross-Entropy Loss 和梯度。
Q3:什么是“数值稳定性”问题?为什么 Softmax 需要减去最大值?
Q4:温度参数 τ 对 Softmax 有什么影响?计算当 τ = 0.5, τ = 1, τ = 3 时,输入 z = [1, 2, 3] 的 Softmax 分布。
Q5:为什么 Softmax 通常和 Cross-Entropy 一起使用?当 Softmax + CE 组合时,反向传播梯度有什么特殊性?
查看答案
A1:
e^2 = 7.3891, e^1 = 2.7183, e^0 = 1.0000 总和 = 11.1074 p_1 = 7.3891/11.1074 = 0.6652 p_2 = 2.7183/11.1074 = 0.2447 p_3 = 1.0000/11.1074 = 0.0900
A2:
Loss = -[1×log(0.7) + 0×log(0.2) + 0×log(0.1)] = -log(0.7) = 0.3567 梯度 dL/dz = ŷ - y = [0.7, 0.2, 0.1] - [1, 0, 0] = [-0.3, 0.2, 0.1]
A3:
当 z 中有很大的值时(如 z = [1000, 0, 0]),e^{1000} 超出计算机浮点数表示范围(溢出)。减去 max(z) 后,所有指数的幂都≤ 0,最大的 e^0 = 1,不会溢出。因为分子分母同时乘以 e^{-max(z)},结果不变。
A4:
| τ | z/τ | Softmax | 特点 |
|---|---|---|---|
| 0.5 | [2, 4, 6] | [0.015, 0.117, 0.868] | 尖锐,几乎硬分配 |
| 1 | [1, 2, 3] | [0.090, 0.245, 0.665] | 正常 |
| 3 | [0.333, 0.667, 1] | [0.248, 0.314, 0.438] | 平坦,接近均匀 |
A5:
Softmax 和 Cross-Entropy 是“天然配对”,因为组合后的梯度极其简单:dL/dz = ŷ - y(预测减真实)。这意味着反向传播中不需要计算复杂的雅可比矩阵,只需做一个减法。这是数学巧合,也是为什么所有分类网络都用这个组合。
激活函数对比总结
五大激活函数对比表:
| 激活函数 | 公式 | 输出范围 | 最大导数 | 零中心 | 梯度消失 | 常用场景 |
|---|---|---|---|---|---|---|
| Sigmoid | 1/(1+e^{-x}) | (0, 1) | 0.25 | ✘ | 严重 | 二分类输出层 |
| Tanh | (e^x-e^{-x})/(e^x+e^{-x}) | (-1, 1) | 1.0 | ✔ | 严重 | RNN/LSTM |
| ReLU | max(0, x) | [0, ∞) | 1 | ✘ | 无 | CNN/MLP隐藏层 |
| GELU | x×Φ(x) | [-0.17, ∞) | ≈ 1 | 近似 | 无 | Transformer/LLM |
| Softmax | e^{z_i}/∑e^{z_j} | (0,1), sum=1 | ≈ 0.25 | - | 不适用 | 分类输出层/注意力 |
选型指南:
- 隐藏层:优先 ReLU(简单快速),大模型用 GELU
- 二分类输出:Sigmoid
- 多分类输出:Softmax
- RNN 隐藏:Tanh
- Transformer/LLM:GELU(或 SwiGLU)
- Dead ReLU 问题严重:Leaky ReLU 或 ELU
关键心法:
- 激活函数的本质是引入非线性——没有它们,神经网络只是线性回归
- ReLU 解决了梯度消失,但引入 Dead ReLU
- GELU 用平滑的正态累积分替代硬截断,成为 LLM 标配
- Softmax 把“分数”变成“概率”,配套 CE 梯度 = 预测 - 真实
- 在真实项目中:隐藏层 ReLU/GELU,输出层 Sigmoid/Softmax