返回学习地图
llmPhase A · 第 4

03. 激活函数

Sigmoid/Tanh/ReLU/GELU/Softmax:激活函数全面详解,每层的非线性变换

22 个章节·按类别展开/折叠
知识

为什么需要激活函数?

神经网络的每一层本质上是一个线性变换: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:计算指数部分

xe^{-x}1 + e^{-x}σ(x)σ'(x)
-3e^{3} ≈ 20.085521.08550.04740.0452
-1e^{1} ≈ 2.71833.71830.26890.1966
0e^{0} = 1.00002.00000.50000.2500
1e^{-1} ≈ 0.36791.36790.73110.1966
3e^{-3} ≈ 0.04981.04980.95260.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.1050

A2:

设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:

xe^{-x}σ(x)饱和?
-1022026.46580.000045✔ 负向饱和
-0.51.64870.3775✘ 敏感区
01.00000.5000✘ 敏感区
0.50.60650.6225✘ 敏感区
100.0000450.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}

xe^xe^{-x}e^x-e^{-x}e^x+e^{-x}tanh(x)tanh'(x)
-30.049820.0855-20.035720.1353-0.99510.0099
-10.36792.7183-2.35043.0862-0.76160.4200
01.00001.00000.00002.00000.00001.0000
12.71830.36792.35043.08620.76160.4200
320.08550.049820.035720.13530.99510.0099

Step 2:验证导数公式

以 x=1 为例:

tanh(1) = 0.7616
tanh'(1) = 1 - 0.7616^2 = 1 - 0.5800 = 0.4200 ✓

对比 Sigmoid 和 Tanh:

性质SigmoidTanh
输出范围(0, 1)(-1, 1)
是否零中心
最大导数0.251.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.0707

A2:

σ(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 值和导数。

计算表:

xReLU(x)ReLU'(x)状态
-500死亡
-200死亡
-0.100临界(接近 0)
00未定义单点不可导
0.50.51活跃
331活跃
10101活跃

一个完整的前向传播例子:

假设一层神经网络,权重 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

完整结果:

xx + 0.0447x^3innertanhGELU(x)
-3.00-4.207-3.357-0.9980.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.000.0000.0000.0000.000
0.500.5060.4040.3840.346
1.001.0450.8340.6830.841
3.004.2073.3570.9982.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.9356

A2:

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(预测减真实)。这意味着反向传播中不需要计算复杂的雅可比矩阵,只需做一个减法。这是数学巧合,也是为什么所有分类网络都用这个组合。

知识

激活函数对比总结

五大激活函数对比表:

激活函数公式输出范围最大导数零中心梯度消失常用场景
Sigmoid1/(1+e^{-x})(0, 1)0.25严重二分类输出层
Tanh(e^x-e^{-x})/(e^x+e^{-x})(-1, 1)1.0严重RNN/LSTM
ReLUmax(0, x)[0, ∞)1CNN/MLP隐藏层
GELUx×Φ(x)[-0.17, ∞)≈ 1近似Transformer/LLM
Softmaxe^{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

关键心法:

  1. 激活函数的本质是引入非线性——没有它们,神经网络只是线性回归
  2. ReLU 解决了梯度消失,但引入 Dead ReLU
  3. GELU 用平滑的正态累积分替代硬截断,成为 LLM 标配
  4. Softmax 把“分数”变成“概率”,配套 CE 梯度 = 预测 - 真实
  5. 在真实项目中:隐藏层 ReLU/GELU,输出层 Sigmoid/Softmax