很早之前我们就展开过激活函数的相关内容激活函数。其本质是给神经网络引入非线性。这里再简单复述一遍Sigmoid是最早被广泛使用的激活函数Sigmoid 将任意实数压缩到 区间在隐藏层可以理解为激活概率但现在更常见在分类头等输出层最后表示概率。但它有两个问题输出不是零中心的会导致后一层接收的输入始终为正导致反向传播时权重梯度容易同号梯度更新效率低。两端饱和严重 较大或较小时梯度几乎为零深层网络中容易梯度消失。Tanh缓解了第一个问题很明显它把输出范围压缩到 实现了零中心化。但梯度饱和的问题仍然存在在 绝对值较大的区域梯度依然趋近于零。真正的转折点是 2012 年前后ReLURectified Linear Unit的普及ReLU 的形式极简正半轴保持梯度为 1负半轴直接归零。但这种看似不合理的设计却在隐藏层传播中带来了极大优势正半轴梯度恒为 1梯度消失问题被大幅缓解同时计算更是简单到只需要一个比较操作。ReLU 对训练深层网络起到积极贡献此外还有残差网络因此也是很长一段时间里的默认选择。但 ReLU 也有自己的问题负半轴完全归零会导致死神经元当某个神经元对所有训练样本都输出负值时其梯度将始终为 0参数无法继续更新从而永久停留在负半区。因此出现了一批试图修复这个问题的变体Leaky ReLU负半轴改为一个小斜率 比如 0.01让信息仍然可以流动。PReLU把 变成可学习的参数。ELU负半轴用指数曲线让输出均值接近零。这些变体各自有一些效果但都没有真正取代 ReLU 的主流地位。再往后就来到了 16 年的 Gaussian Error Linear UnitsGELU我们在之前的 ConvNeXt中也简单展开过它 是标准正态分布的累积分布函数。GELU 在 ReLU 的基础上做了平滑负半轴有一个非零的尾巴在 附近也是光滑可导的。它在 NLP 领域很受欢迎BERT 和 GPT 系列都用了它它也逐渐成为 Transformer 系列中 FFN 的默认激活函数。此外17 年 Google 在 Searching for Activation Functions 提出了Swish 激活函数它看起来和 GELU 十分相似Swish 是 Google 实验室在同一个网络中进行只换激活函数的大规模 A/B Test 得到的并没有从理论推导而是纯粹实验发现的优解。从函数形状上看Swish 与 GELU 几乎等价二者性能差距通常很小。历史上 NLP 社区由于 BERT 的成功更偏向 GELU而 CV 领域曾广泛采用实现更简单的 Swish。这种难分伯仲的情况也让研究者开始跳出 “用哪种激活函数” 去发现其他逻辑这也是下部分的内容2. 标准 FFN 的结构局限#简单过了过激活函数后现在我们再来看 Transformer Block 中的 FFN 层其中 是激活函数原版 Transformer 使用 ReLU后续则大多换成了 GELU。这条信息流路径非常直接输入升维激活降维输出原理也很清晰FFN 可以学习特征的重要性在训练过程中权重矩阵 和 会不断调整从而让网络自动学会哪些模式更值得关注。但以事后诸葛亮的视角来看它仍然存在一个隐含的限制完成训练后FFN 学到的是固定的重要性而不是针对当前输入的动态重要性。也就是完成训练后某个隐藏神经元在训练过程中学会了识别某种特征那么无论输入什么样本它都会使用同一套权重进行计算。这与注意力机制形成了鲜明对比在 Attention 逻辑中不同输入会产生不同的注意力分布因此模型能够动态决定哪些信息应该被重点关注、哪些信息应该被弱化甚至忽略。这种根据当前样本实时调整权重的能力我们称之为动态门控思想。既然 Attention 可以动态选择重要信息那么 FFN 能否也拥有类似的能力而答案正是后来逐渐流行起来的门控机制我们之前在 RNN 中介绍过例如 GRU 和 LSTM都利用门控控制信息流动。不久前的 通道注意力系列等其实也是这种门控思想的应用。那么如何实现在 FFN 中实现门控逻辑就是本篇的主角3. SwiGLU#3.1 GLU门控线性单元#GLUGated Linear Unit来自 17 年的论文 Language Modeling with Gated Convolutional Networks。它在标准全连接基础上增加了一个分支其中左边的是 Value 分支。右边是 Gate 分支使用 Sigmoid 函数激活。其实逻辑和之前的SE是十分相似的将输入同步聚合为一组权重再作用在输出上实现门控逻辑。这便是最基础的 GLU 逻辑。3.2 SwiGLU#Sigmoid 门控本身是很符合我们的现实逻辑的但在后续的实践中研究者们却发现它其实不一定是最优选择。20 年论文 GLU Variants Improve Transformer 中做了一个系统的实验把标准 FFN 替换成各种 GLU 变体看门控激活函数选哪个最好而 SwiGLU 表现最好也由此在后续的实践中逐渐发扬光大。SwiGLU 其实就是把 GLU 中的 Sigmoid 激活函数更换为了 Swish 函数DL 论文里经常忽略偏置Transformer 架构里偏置甚至经常在实现中被直接删除。而对于为什么使用 Swish 要强于 sigmoid 比较主流的认知主要集中在两点sigmoid 的 0-1 取值范围只能实现抑制和保留而 Swish 却不受限于 0-1可以实现放大。sigmoid 在网络传播中的梯度问题仍然存在Swish 更好优化。3.3 一个应用 SwiGLU 的 FFN 子层#最终Transformer block 在引入 SwiGLU 后原本的 FFN 子层本的升维层被拆成了两条并行分支随后再正常通过原本的降维层整体表示如下
激活函数的发展历程#
很早之前我们就展开过激活函数的相关内容激活函数。其本质是给神经网络引入非线性。这里再简单复述一遍Sigmoid是最早被广泛使用的激活函数Sigmoid 将任意实数压缩到 区间在隐藏层可以理解为激活概率但现在更常见在分类头等输出层最后表示概率。但它有两个问题输出不是零中心的会导致后一层接收的输入始终为正导致反向传播时权重梯度容易同号梯度更新效率低。两端饱和严重 较大或较小时梯度几乎为零深层网络中容易梯度消失。Tanh缓解了第一个问题很明显它把输出范围压缩到 实现了零中心化。但梯度饱和的问题仍然存在在 绝对值较大的区域梯度依然趋近于零。真正的转折点是 2012 年前后ReLURectified Linear Unit的普及ReLU 的形式极简正半轴保持梯度为 1负半轴直接归零。但这种看似不合理的设计却在隐藏层传播中带来了极大优势正半轴梯度恒为 1梯度消失问题被大幅缓解同时计算更是简单到只需要一个比较操作。ReLU 对训练深层网络起到积极贡献此外还有残差网络因此也是很长一段时间里的默认选择。但 ReLU 也有自己的问题负半轴完全归零会导致死神经元当某个神经元对所有训练样本都输出负值时其梯度将始终为 0参数无法继续更新从而永久停留在负半区。因此出现了一批试图修复这个问题的变体Leaky ReLU负半轴改为一个小斜率 比如 0.01让信息仍然可以流动。PReLU把 变成可学习的参数。ELU负半轴用指数曲线让输出均值接近零。这些变体各自有一些效果但都没有真正取代 ReLU 的主流地位。再往后就来到了 16 年的 Gaussian Error Linear UnitsGELU我们在之前的 ConvNeXt中也简单展开过它 是标准正态分布的累积分布函数。GELU 在 ReLU 的基础上做了平滑负半轴有一个非零的尾巴在 附近也是光滑可导的。它在 NLP 领域很受欢迎BERT 和 GPT 系列都用了它它也逐渐成为 Transformer 系列中 FFN 的默认激活函数。此外17 年 Google 在 Searching for Activation Functions 提出了Swish 激活函数它看起来和 GELU 十分相似Swish 是 Google 实验室在同一个网络中进行只换激活函数的大规模 A/B Test 得到的并没有从理论推导而是纯粹实验发现的优解。从函数形状上看Swish 与 GELU 几乎等价二者性能差距通常很小。历史上 NLP 社区由于 BERT 的成功更偏向 GELU而 CV 领域曾广泛采用实现更简单的 Swish。这种难分伯仲的情况也让研究者开始跳出 “用哪种激活函数” 去发现其他逻辑这也是下部分的内容2. 标准 FFN 的结构局限#简单过了过激活函数后现在我们再来看 Transformer Block 中的 FFN 层其中 是激活函数原版 Transformer 使用 ReLU后续则大多换成了 GELU。这条信息流路径非常直接输入升维激活降维输出原理也很清晰FFN 可以学习特征的重要性在训练过程中权重矩阵 和 会不断调整从而让网络自动学会哪些模式更值得关注。但以事后诸葛亮的视角来看它仍然存在一个隐含的限制完成训练后FFN 学到的是固定的重要性而不是针对当前输入的动态重要性。也就是完成训练后某个隐藏神经元在训练过程中学会了识别某种特征那么无论输入什么样本它都会使用同一套权重进行计算。这与注意力机制形成了鲜明对比在 Attention 逻辑中不同输入会产生不同的注意力分布因此模型能够动态决定哪些信息应该被重点关注、哪些信息应该被弱化甚至忽略。这种根据当前样本实时调整权重的能力我们称之为动态门控思想。既然 Attention 可以动态选择重要信息那么 FFN 能否也拥有类似的能力而答案正是后来逐渐流行起来的门控机制我们之前在 RNN 中介绍过例如 GRU 和 LSTM都利用门控控制信息流动。不久前的 通道注意力系列等其实也是这种门控思想的应用。那么如何实现在 FFN 中实现门控逻辑就是本篇的主角3. SwiGLU#3.1 GLU门控线性单元#GLUGated Linear Unit来自 17 年的论文 Language Modeling with Gated Convolutional Networks。它在标准全连接基础上增加了一个分支其中左边的是 Value 分支。右边是 Gate 分支使用 Sigmoid 函数激活。其实逻辑和之前的SE是十分相似的将输入同步聚合为一组权重再作用在输出上实现门控逻辑。这便是最基础的 GLU 逻辑。3.2 SwiGLU#Sigmoid 门控本身是很符合我们的现实逻辑的但在后续的实践中研究者们却发现它其实不一定是最优选择。20 年论文 GLU Variants Improve Transformer 中做了一个系统的实验把标准 FFN 替换成各种 GLU 变体看门控激活函数选哪个最好而 SwiGLU 表现最好也由此在后续的实践中逐渐发扬光大。SwiGLU 其实就是把 GLU 中的 Sigmoid 激活函数更换为了 Swish 函数DL 论文里经常忽略偏置Transformer 架构里偏置甚至经常在实现中被直接删除。而对于为什么使用 Swish 要强于 sigmoid 比较主流的认知主要集中在两点sigmoid 的 0-1 取值范围只能实现抑制和保留而 Swish 却不受限于 0-1可以实现放大。sigmoid 在网络传播中的梯度问题仍然存在Swish 更好优化。3.3 一个应用 SwiGLU 的 FFN 子层#最终Transformer block 在引入 SwiGLU 后原本的 FFN 子层本的升维层被拆成了两条并行分支随后再正常通过原本的降维层整体表示如下