Please enable Javascript to view the contents

Activation Function:神经网络里那个很小但很关键的非线性

 ·  ☕ 7 分钟 · 👀... 阅读
Read aloud Ready
0/0

Activation function 看起来只是神经网络层里一个很小的函数。真正重的计算通常是矩阵乘法:

$$z = Wx + b$$

然后逐元素套一个函数:

$$a = \phi(z)$$

很容易把 \(\phi\) 当成一个可以随便替换的名字:sigmoid、tanh、ReLU、GELU、SiLU、Mish,或者几百个变体。但 activation function 不是装饰。它决定了多层网络能不能表达非线性函数,梯度能不能传下去,hidden value 的分布是否稳定,以及为了很小的精度收益是否要付出明显的运行成本。

Kunc 和 Klema 在 2024 年的综述 Three Decades of Activations 里整理了大约 400 个 real-valued activation functions。这个数字本身就说明了一件事:这个领域里有很多命名、变体和重复发明。对一篇博客来说,把 400 个函数逐个列出来只会掩盖真正重要的问题。更好的切入点是:

activation function 到底在解决什么问题?每一类函数的 tradeoff 是什么?

为什么必须有非线性

先看一个两层网络,但把 activation 去掉:

$$h = W_1 x + b_1$$

$$y = W_2 h + b_2$$

把 \(h\) 代入第二个式子:

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

整个两层网络等价于一层线性层。继续堆更多线性层也没有本质区别,因为线性/仿射变换的复合仍然是仿射变换。

Activation function 打破了这个坍缩。加入:

$$h = \phi(W_1x + b_1)$$

之后,第二层看到的就不再是 \(x\) 的简单仿射变换,而是被截断、门控、压缩、弯折或平滑重加权后的特征。这就是 activation function 存在的核心原因。

看一个很小的标量例子。令:

$$h_1 = \phi(2x - 1),\quad h_2 = \phi(-2x - 1),\quad y = h_1 + h_2$$

如果 \(\phi(z)=z\),那么:

$$y = (2x - 1) + (-2x - 1) = -2$$

输入 \(x\) 直接消失了。但如果 \(\phi(z)=\max(0,z)\),那么:

$$y = \max(0,2x-1) + \max(0,-2x-1)$$

这个函数在中间是平的,在两侧增长。两个 rectifier 造出了一个 piecewise-linear 的“弯折”,而单个线性层无法表达这个形状。

flowchart LR
  X[input x] --> A["linear: z = Wx + b"]
  A --> B["activation: a = phi(z)"]
  B --> C["next layer"]
  B -. "changes geometry" .-> D["clip / gate / squash / smooth"]

一个实用分类

2024 年那篇综述把 activation function 分成两大类:fixed activation functionsadaptive activation functions。fixed function 没有可训练的 activation 参数;adaptive activation function 会把某些形状参数也放进训练过程。为了理解主线,我们还可以换一个更实用的分类:这个函数到底怎样改变信号和梯度?

家族例子代表公式主要 tradeoff
Step-likebinary step, sign\(1[z\ge0]\), \(\operatorname{sign}(z)\)有历史意义,但几乎没有可用梯度
Saturating smoothsigmoid, tanh\(\sigma(z)=1/(1+e^{-z})\), \(\tanh(z)\)输出范围稳定,但深层梯度弱
RectifiedReLU, Leaky ReLU, PReLU\(\max(0,z)\), \(\max(\alpha z,z)\)便宜、稀疏,但可能 dead unit
Smooth rectified / gatedGELU, SiLU/Swish, Mish\(z\Phi(z)\), \(z\sigma(z)\)现代网络常用,但计算更贵
Normalizing / output-layersoftmax\(e^{z_i}/\sum_j e^{z_j}\)适合分类 logits,不是普通隐藏层替代品
Adaptive / learnedPReLU, trainable splines, rational activations例如 \(\max(\alpha z,z)\),其中 \(\alpha\) 可训练参数更多,实现和泛化风险更高

重点不是哪一行永远最好,而是每一行把 activation 的预算花在不同地方:硬阈值换来离散决策但失去梯度;sigmoid/tanh 换来有界输出但会饱和;ReLU 换来便宜的梯度通道但丢掉负半轴;GELU/SiLU 换来更平滑的 gate,但计算更贵。

Figure 1: 常见 activation function 及其函数图。标量函数在 z in [-5, 5] 上采样;GELU 使用 exact erf 形式;softmax 是 vector-to-vector 函数,所以用 logits 到 probabilities 的柱状图表示。

Figure 1: 常见 activation function 及其函数图。标量函数在 z in [-5, 5] 上采样;GELU 使用 exact erf 形式;softmax 是 vector-to-vector 函数,所以用 logits 到 probabilities 的柱状图表示。

如果只看 family,很多细节会被压扁。例如 sigmoid 和 tanh 都会饱和,但 tanh 是 zero-centered;ReLU 和 Leaky ReLU 都是 rectified family,但负半轴梯度完全不同;GELU 和 SiLU 都像 smooth gate,但曲线在负半轴的形状也不完全一样。上图的目的不是覆盖 400 个函数,而是把最常见的选择放到同一个视觉坐标系里。

Sigmoid 和 Tanh:有界,但会饱和

logistic sigmoid 是:

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

它把任意输入映射到 \((0,1)\)。当输出需要像概率时,这很自然。它的导数是:

$$\sigma^{\prime}(z) = \sigma(z)(1-\sigma(z))$$

导数在 \(z=0\) 附近最大;当 \(z\) 很大或很小时,导数会变得很小。这就是 saturation problem:如果一个神经元落在左侧或右侧的平坦区域,backprop 传回来的学习信号几乎没有。

Tanh 可以看作 sigmoid 的平移和缩放:

$$\tanh(z) = 2\sigma(2z) - 1$$

它把值映射到 \((-1,1)\),并且以 0 为中心,所以作为 hidden activation 往往比 sigmoid 更舒服。但它仍然会饱和。这就是为什么在深层 feed-forward network 里,sigmoid 和 tanh 通常不是默认 hidden activation;不过它们在 gate、recurrent network 和概率输出头里仍然很重要。

ReLU:稀疏、便宜,而且很有效

ReLU 是:

$$\operatorname{ReLU}(z) = \max(0,z)$$

它的导数很简单:

$$\operatorname{ReLU}^{\prime}(z) = \begin{cases} 1, & z > 0 \\ 0, & z < 0 \end{cases}$$

相比 sigmoid 和 tanh,ReLU 在正半轴不会饱和。只要 \(z>0\),梯度就可以原样通过。它也很便宜:没有指数、没有除法、没有查表。

ReLU 的弱点也很直接。负半轴输出精确为 0,梯度也是 0。如果某个 unit 被推到几乎永远为负的区域,它就可能变成 dead ReLU。Leaky ReLU 把负半轴从 0 改成一个小斜率:

$$\operatorname{LeakyReLU}(z) = \begin{cases} z, & z > 0 \\ \alpha z, & z \le 0 \end{cases}$$

PReLU 则让 \(\alpha\) 变成可训练参数。这就是 fixed 和 adaptive 区别的一个小例子:非线性的形状不再完全由研究者手动指定,其中一部分交给训练过程学习。

GELU 和 SiLU:从硬门控到平滑门控

现代 Transformer 风格模型经常使用 smooth rectified 或 gated activation。两个常见例子是 GELU 和 SiLU。

SiLU,有些论文在带参数形式下也叫 Swish,是:

$$\operatorname{SiLU}(z) = z\sigma(z)$$

它不是硬截断负值,而是用一个 \((0,1)\) 之间的平滑 gate 乘上输入。大的正值几乎原样通过;大的负值大多被抑制;0 附近的值被平滑混合。

GELU 常写成:

$$\operatorname{GELU}(z) = z\Phi(z)$$

其中 \(\Phi\) 是标准正态分布的 CDF。直觉类似:输入被一个平滑的、类似概率的 gate 加权。

很多 LLM 的 MLP block 里,用的甚至不只是 GELU/SiLU 本身,而是 SwiGLU 这样的 gated feed-forward 形式:

$$\operatorname{SwiGLU}(x) = (xW_1) \odot \operatorname{SiLU}(xW_2)$$

activation 此时已经是 learned gate 的一部分:一个 projection 产生 value,另一个 projection 产生平滑 gate,再通过逐元素乘法决定哪些 feature 继续向前传。

代价是系统层面的:sigmoid、tanh、erf 或近似计算都比一个 max 操作更贵。在 GPU 上,这个成本可能被 fused kernel 掩盖,但实现仍然重要。

怎么选择 Activation Function

不存在永远最好的 activation。实际选择应该先看这一层承担什么角色。

场景默认选择原因
简单 MLP/CNN baselineReLU 或 Leaky ReLU便宜、稳定、容易 debug
Transformer MLPGELU、SiLU 或 SwiGLU-style gatesmooth gating 在现代架构里常见且有效
二分类概率输出sigmoid输出落在 \((0,1)\)
多分类 logits在 loss/output 边界使用 softmax把 logits 转成相互耦合的类别概率
带 normalization 的深层网络跟随架构默认选择initialization、normalization、activation 通常一起调过
硬件受限推理ReLU 或常见 fused activationruntime cost 和 kernel support 很重要
做 activation 研究把 400-function survey 当地图避免重复发明已有变体

比函数名字更重要的是两条工程规则。

第一,activation、initialization 和 normalization 是耦合的。一个配合 BatchNorm 或 LayerNorm 表现好的函数,去掉 normalization 后可能完全不同。一个均值不为 0 的函数,会改变下一层看到的分布。一个强饱和函数,需要输入尽量停留在敏感区域。

第二,不要孤立 benchmark activation 后过度泛化。小型 CIFAR 实验、Transformer language model、physics-informed network 和嵌入式推理模型的瓶颈都不同。accuracy、gradient flow、memory bandwidth、vectorization、kernel fusion 可能会指向不同选择。

怎么读 400 个 Activation 的综述

Kunc 和 Klema 的综述很有价值,因为它让 activation-function space 变得可搜索。它也提醒我们一个研究实践问题:很多函数只是 slope、shift、gate、learned parameter 或 smooth approximation 的不同组合,有些想法会被换个名字重新发明。

对实践者来说,这篇 paper 最适合这样读:

  • 当字典用:遇到陌生 activation 名字时,先查它属于哪一类。
  • 看 fixed/adaptive 分割:判断它是否有可训练的 shape 参数。
  • 把 400 这个数量当提醒:声称“新 activation”的论文需要非常仔细的 baseline 和 ablation。

日常建模时,真正有用的 mental model 小得多:

维度要问的问题
Nonlinearity多层网络能不能组合出需要的弯折和门控?
Gradient flowbackprop 传回来的信号会不会在饱和区或截断区消失?
Value distribution下一层看到的 activation 分布是否稳定、是否偏移太多?
Compute and kernel support这个函数的指数、erf、查表或分支成本是否会影响推理?

Activation function 是一个局部标量函数,但它改变的是全局的优化行为和表示能力。正确的问题不是“400 个里面哪个最好”,而是:

这个网络需要什么样的几何形状、梯度行为和系统成本?

分享