ReLU 为什么好用?激活函数选择的实践要点
线性修正单元(ReLU)是深度学习中最常用的激活函数,规则是输入大于零时原样输出、小于等于零时输出零。本站另有“ReLU”词条介绍它的定义、历史和主要变体,这里侧重从实践的角度说明它为什么好用,以及使用时需要注意的问题。
为什么它成为默认选择
训练稳定:ReLU 在正数区域的导数恒为 1,梯度在反向传播中不会因为激活函数而衰减,使得较深的网络也能被有效地训练。速度快:前向计算只需要一次比较,反向传播时的导数要么是 0、要么是 1,计算极其简单,在大规模的网络中能节省可观的计算量。分段线性:ReLU 网络实际上是一个分段线性的函数,通过大量的折线拼接来逼近复杂的函数,这种结构便于优化,也便于理论分析。稀疏性:对于任何一个输入,通常只有一部分神经元被激活,这种稀疏的表示在一定程度上提高了效率和泛化能力。由于这些原因,在卷积神经网络和多层感知机的隐藏层中,ReLU 通常是首先尝试的激活函数。
配合合适的初始化
激活函数与权重的初始化方式密切相关。ReLU 会把一半左右的输入变成零,如果使用为 Sigmoid、Tanh 设计的 Xavier 初始化,信号在逐层传递的过程中会逐渐变弱。2015 年,何恺明等人针对 ReLU 提出了 He 初始化:让每一层权重的方差等于 2 除以输入的数量,这样能够让信号的方差在逐层传递时大致保持不变,避免信号在深层网络中消失或爆炸。在主流的深度学习框架中,使用 ReLU 时通常推荐搭配 He 初始化。
需要注意的问题
神经元死亡:如果学习率设置得过大,或者初始化不当,某些神经元的权重可能被更新到一个位置,使得它对所有的输入都输出零,梯度也永远为零,再也无法恢复。可以通过使用较小的学习率、合适的初始化、批归一化,或者改用 Leaky ReLU 等变体来缓解。在训练过程中,可以监控每一层中输出始终为零的神经元所占的比例。输出不以零为中心:ReLU 的输出总是非负的,这会让后一层的输入整体偏正,可能影响优化的效率。归一化层可以在很大程度上缓解这一问题。没有上界:ReLU 在正数区域的输出没有上限,在某些情况下数值可能变得很大,尤其是在使用低精度计算时需要留意数值溢出。一些移动端的模型使用 ReLU6,把输出限制在 0 到 6 之间,便于量化。
什么时候考虑其他激活函数
如果发现有大量的神经元死亡,可以尝试 Leaky ReLU 或 PReLU,它们在负数区域保留了一个很小的斜率。如果希望输出更接近零均值、曲线更平滑,可以尝试 ELU。在 Transformer 和大语言模型中,GELU 和 SiLU(也叫 Swish)更为常用,它们是 ReLU 的平滑版本,在零附近的过渡更加柔和,实验表明在这类模型中效果更好;Llama 等模型的前馈网络使用的 SwiGLU,则结合了 SiLU 与门控机制。在循环神经网络中,由于 ReLU 没有上界,信号可能在时间步之间不断放大,因此通常仍使用 Tanh 和 Sigmoid。
输出层的激活函数
ReLU 主要用于隐藏层,输出层的激活函数应当根据任务来选择:二分类和多标签分类使用 Sigmoid,输出每个类别的概率;多分类使用 Softmax,输出一组和为 1 的概率;回归任务通常不使用激活函数,直接输出一个实数;如果预测的值必须为正,比如价格、计数,可以使用 Softplus 等函数,或者预测它的对数。