激活函数是神经网络中每个神经元在加权求和之后再经过的一道非线性变换:输入一个数值,输出一个经过“弯折”或“截断”处理后的数值。它决定神经元在什么条件下被激活、输出信号有多强。没有这一步,神经元做的只是加法和乘法,再多的层叠加起来,效果仍然等价于一层线性变换;有了它,网络才能画出弯曲的分类边界、拟合非线性的关系,进而学会图像、语言里那些无法用一条直线分开的规律。
理解它有一个很直观的类比:线性计算像用直尺画线,再多直尺接在一起,画出的还是直线;激活函数像在每一层都允许把线掰弯一次,掰弯的次数多了,直线就能拼出曲线、圆圈和复杂的分界。神经网络的“深”之所以有用,很大程度上正是因为每一层都有这样一次掰弯的机会。
为什么线性叠加再深也不够
一个神经元先算加权和:把每个输入乘上权重再加起来,得到一个数值。如果直接把这个数值传给下一层,下一层再做一次加权求和,数学上两次线性运算合并后仍然是一次线性运算。十层、一百层线性层叠加,最终还是一个线性函数,只能表达“输入越大、输出按固定比例越大或越小”这类关系。
现实里的规律很少这么简单。判断一张图是不是猫,依据不是某个像素亮度的单调变化;判断一句话是肯定还是否定,也不能只看某个词出现与否。这些任务的边界是弯曲的、组合的,需要模型在每一层都引入非线性,才能逐步把原始输入“折”成可分的表示。激活函数就是提供这种折叠能力的部件,位置通常在每一层的线性计算之后、传给下一层之前。
常见的激活函数,各自在取舍什么
没有一种激活函数在所有任务上都最好,选型本质是在表达能力、训练稳定性和计算成本之间取舍。
| 类型 | 做法 | 优点 | 容易出的问题 |
|---|---|---|---|
| Sigmoid | 把输入压到 0 到 1 之间,形似一条 S 形曲线 | 输出像概率,便于理解 | 两端太平,梯度容易消失;输出不以 0 为中心 |
| Tanh | 把输入压到 -1 到 1 之间 | 以 0 为中心,比 Sigmoid 好训练一些 | 两端同样太平,深层网络里梯度仍会消失 |
| ReLU | 负数输出 0,正数原样输出 | 计算极简单,缓解了梯度消失,是多年来的默认选择 | 负数区间梯度为 0,神经元可能“死掉”不再更新 |
| Leaky ReLU / ELU | 负数区间给一个很小的斜率或平滑过渡 | 减轻神经元死亡问题 | 多了一个需要调的超参数,收益不总是明显 |
| GELU / Swish | 用平滑曲线代替生硬的截断,负数区小幅放行 | 在 Transformer 类模型里表现稳定,是当前大模型的主流选择 | 计算比 ReLU 稍贵,效果依赖具体任务 |
读这张表时注意一个细节:Sigmoid 和 Tanh 的“压到固定区间”在输出层有时是优点,例如二分类需要一个 0 到 1 之间的概率;但在隐藏层里,这种压缩恰恰是梯度消失的来源。同一函数放在不同位置,利弊会翻转。
梯度问题:激活函数如何影响训练
训练靠梯度下降一步步调参数,梯度要从输出层一层层往回传。激活函数的导数直接决定了每一层能分到多少梯度,这也是它最容易拖后腿的地方。
Sigmoid 和 Tanh 在输入很大或很小时,曲线几乎是平的,导数接近 0。梯度每经过这样一层就被乘上一个很小的数,传到前面几层时已经所剩无几,前面的层几乎学不到东西,这叫梯度消失。深层网络早期训练困难,很大一部分原因就出在这里。
ReLU 换了一个思路:正数区间导数恒为 1,梯度可以原样往回传,深层训练因此变得可行。代价是负数区间导数恒为 0,一旦某个神经元的输入长期落在负数区,它的参数就再也收不到梯度,输出永远是 0,等于从网络里“死掉”了。实践中用较小的学习率、合理的初始化和归一化,可以把死亡神经元的数量控制在可接受范围;Leaky ReLU 这类变体则是直接给负数区留一条很小的梯度通道。
还有一个方向容易被忽略:激活函数本身不解决所有训练问题。梯度爆炸、学习率过大、数据分布偏移,都会让训练不稳定,换激活函数只能解决其中属于“每层导数”那一部分。训练出问题时,先看损失曲线和梯度规模,再决定是不是激活函数的责任,比上来就换函数更省时间。
大模型里实际用的是哪种
今天主流大模型的隐藏层里最常见的是 GELU 及其变体,以及 SwiGLU 这类带门控的变体。GELU 的思路是把 ReLU 的生硬截断换成平滑过渡:输入为负时不是一刀切成 0,而是按概率小幅放行一部分,既保留了非线性,又避免了梯度在负数区彻底断掉。SwiGLU 则更进一步,用两路计算相乘、其中一路起门控作用,让网络自己决定放行多少信息。
这并不意味着 ReLU 过时了。小型网络、教学示例和对推理速度敏感的场景里,ReLU 仍然因为简单、快速而被大量使用。选型上可以记住一条经验:读论文或模型卡片时,隐藏层激活函数的写法往往能透露模型的年代和取向——ReLU 多见于经典结构,GELU 和 SwiGLU 多见于近年的 Transformer 大模型;但这只是线索,不是质量高低的判决。
它和相近概念的边界
激活函数最容易和三个概念混淆。第一是权重:权重决定每个输入有多重要,是训练要学习的参数;激活函数是固定的计算规则,本身通常没有可学习参数(个别变体有少量参数),它决定的是“怎么弯折”,不是“重视谁”。第二是归一化:归一化是把一层输出的分布拉回稳定范围,解决的是数值漂移问题;激活函数解决的是“没有非线性就学不会复杂规律”的问题,两者经常前后脚出现,但职责不同。第三是混合专家模型里的“激活专家”:那里说的激活是指每次只启用少数几个专家网络,是一种稀疏计算策略,和激活函数里的非线性变换不是同一个概念,读到“每 token 激活多少参数”时不要按激活函数去理解。
输出层的激活函数也值得单独提一句。分类任务的最后一层常用 Softmax,把一组分数转成加起来等于 1 的概率分布;回归任务的最后一层常常不用激活函数,直接输出数值。隐藏层和输出层的激活函数选择逻辑不同,混为一谈是新手最常见的选型错误。
什么时候需要关心它,什么时候不用
日常使用聊天、写作、绘图产品时,不必追问激活函数是哪种。模型在你的任务上是否稳定、是否注明知识时效、出错时有没有核对路径,这些更实在。激活函数属于“打开盖子看结构”时才需要的那一层知识。
动手训练或微调模型、读模型结构图、复现一篇论文时,它就值得关心了:先看隐藏层用的是 ReLU 还是 GELU 类,再看输出层是否匹配任务类型,最后结合梯度、学习率一起判断训练问题。自己搭小网络做实验时,从 ReLU 起步、遇到死亡神经元或训练不稳再试 Leaky ReLU 或 GELU,是比一上来就堆复杂变体更稳妥的顺序。归根结底,激活函数的价值不在名字新潮,而在它让每一层都有机会把表示掰弯一点——深层网络学到的复杂规律,都是这样一层层弯折出来的。