SEARCH

激活函数有哪些 - 深度学习中不可或缺的非线性转换器

什么是激活函数?——神经网络的“神经”之所在

在深度学习的神经网络中,激活函数(Activation Function)是模型中一个至关重要的非线性组件。它们被引入到神经元的输出端,用于对神经元的输入信号进行转换和映射,决定该神经元是否应该被“激活”以及其输出的强度。如果没有激活函数,或者只使用线性激活函数,无论神经网络有多少层,它都只能学习到输入与输出之间的线性关系,这将大大限制模型的表达能力,使其无法处理复杂的非线性问题,例如图像识别、自然语言处理等。

我们可以将激活函数形象地比喻为生物神经元中的一个“阀门”或“开关”。当接收到的信号(加权和)达到一定阈值时,阀门打开,神经元被激活并传递信息;反之,则保持关闭或传递微弱信号。这种非线性特性赋予了神经网络学习复杂模式和表示的能力,使其能够逼近任意复杂的函数。

为什么神经网络需要激活函数?

神经网络的本质是通过组合一系列简单的线性变换和非线性变换来学习复杂的函数映射。其中,线性变换通常由权重和偏置的乘加运算完成。然而,仅仅堆叠线性层是无法构建深度网络的,原因如下:

  • 打破线性组合的限制: 假设我们没有激活函数,或者使用恒等激活函数(f(x) = x)。那么,无论堆叠多少层,例如:

    第一层输出:Y1 = W1 * X + B1

    第二层输出:Y2 = W2 * Y1 + B2 = W2 * (W1 * X + B1) + B2 = (W2 * W1) * X + (W2 * B1 + B2)

    可以看到,多层线性变换的组合仍然可以表示为一个单一的线性变换。这意味着一个多层网络将退化为单层网络,其学习能力和表达能力与单层感知机无异,无法解决异或(XOR)等非线性问题。

  • 引入非线性特性: 现实世界中的数据和问题往往是非线性的。激活函数的核心作用就是引入非线性,使得神经网络能够学习和模拟任意复杂的非线性关系,从而提高模型的表达能力和泛化能力。
  • 允许梯度下降和反向传播: 大多数激活函数都是可导的(或在几乎所有点上可导),这使得我们可以使用基于梯度的优化算法(如梯度下降)来训练神经网络,通过反向传播算法调整权重和偏置,从而最小化损失函数。

激活函数有哪些?——主流类型与特性详述

随着深度学习的发展,研究人员提出了多种激活函数,每种都有其独特的优点和缺点,适用于不同的场景。以下是当前主流的激活函数及其详细介绍:

1. Sigmoid 函数 (Logistic Function)

Sigmoid 函数是最早被广泛使用的激活函数之一,其数学表达式为:

f(x) = 1 / (1 + e^(-x))

它的输出值介于0到1之间,形状类似一个“S”形曲线。

  • 优点:
    • 将输入值映射到0-1之间,可以解释为概率或某种“激活程度”。
    • 输出值光滑,可导,这对于基于梯度的优化算法至关重要。
  • 缺点:
    • 梯度消失问题(Vanishing Gradient Problem): 当输入值 x 很大或很小时,Sigmoid 函数的导数接近于0。这意味着在反向传播过程中,传递给前一层的梯度会变得非常小,导致神经网络的参数更新缓慢,尤其是在深层网络中,训练会变得非常困难。
    • 输出不以0为中心(Not Zero-Centered): Sigmoid 的输出值恒为正数。这意味着下一层的输入总是正数,可能导致梯度更新的“锯齿”效应,从而减慢收敛速度。
    • 计算开销较大: 包含指数运算,计算相对耗时。
  • 应用场景: 由于梯度消失和非零中心问题,Sigmoid 在隐藏层中已较少使用。它主要用于二分类问题的输出层,将输出转化为0-1之间的概率值。

2. Tanh 函数 (Hyperbolic Tangent Function)

Tanh 函数是Sigmoid 函数的变体,其数学表达式为:

f(x) = (e^x - e^(-x)) / (e^x + e^(-x))

它的输出值介于-1到1之间,形状也类似“S”形曲线,但关于原点对称。

  • 优点:
    • 输出以0为中心: Tanh 的输出值在-1到1之间,均值为0,这有助于解决Sigmoid的非零中心问题,使得梯度更新方向更稳定,加速收敛。
    • 梯度消失问题比Sigmoid稍缓解,但本质上仍然存在。
    • 光滑、可导。
  • 缺点:
    • 梯度消失问题: 与Sigmoid 类似,当输入值 x 很大或很小时,Tanh 函数的导数仍然接近于0,深层网络中梯度消失问题依然显著。
    • 计算开销相对较大。
  • 应用场景: 在早期深度学习中,Tanh 在隐藏层中的表现通常优于Sigmoid,因为它解决了输出非零中心的问题。但随着ReLU的出现,其使用频率也大幅下降。

3. ReLU 函数 (Rectified Linear Unit)

ReLU 函数是目前最常用、最流行的激活函数之一,其数学表达式为:

f(x) = max(0, x)

当输入 x 大于0时,输出 x;当输入 x 小于或等于0时,输出0。

  • 优点:
    • 缓解梯度消失问题: 当 x > 0 时,导数恒为1,这使得梯度可以无衰减地传播,有效缓解了Sigmoid和Tanh的梯度消失问题,从而加速了模型的收敛。
    • 计算效率高: 只需要判断正负,计算非常简单,远快于Sigmoid和Tanh。
    • 引入稀疏性: 当 x <= 0 时,神经元输出为0,这导致一部分神经元的激活值为0,从而在网络中创建稀疏性。稀疏激活有助于减少参数之间的相互依赖,从而减少过拟合的风险。
  • 缺点:
    • “死亡ReLU”问题(Dying ReLU Problem): 当输入 x 永远为负数时(例如,如果学习率设置过大,导致权重更新后神经元输出始终为负),ReLU 的梯度在 x <= 0 时恒为0。这意味着该神经元将不再对任何输入进行激活,权重也无法再更新,就好像“死掉”了一样。一旦一个神经元“死亡”,它将永远无法被激活。
    • 输出不以0为中心。
  • 应用场景: 在绝大多数深度神经网络的隐藏层中,ReLU 及其变体是首选的激活函数。它在图像识别、自然语言处理等领域取得了巨大成功。

4. Leaky ReLU 函数 (Leaky Rectified Linear Unit)

Leaky ReLU 是为解决“死亡ReLU”问题而提出的一种变体,其数学表达式为:

f(x) = max(αx, x) 或 f(x) = x (if x > 0), αx (if x <= 0)

其中,α 是一个小的正数常数,通常取 0.01。当输入 x 小于或等于0时,Leaky ReLU 不会像ReLU那样直接输出0,而是输出一个很小的负值(αx)。

  • 优点:
    • 解决了“死亡ReLU”问题,因为在 x <= 0 时仍然有一个小的非零梯度,允许负输入有一些信息流过,从而避免神经元完全“死亡”。
    • 计算效率依然很高。
  • 缺点:
    • 尽管解决了死亡ReLU,但效果不总是比标准ReLU好很多,且 α 的选择有时需要凭经验。
  • 应用场景: 当发现ReLU模型出现大量“死亡”神经元时,可以尝试使用Leaky ReLU。

5. PReLU 函数 (Parametric Rectified Linear Unit)

PReLU 是 Leaky ReLU 的进一步泛化,将 α 设置为一个可学习的参数,而不是固定的常数。其数学表达式与Leaky ReLU 相同,但 α 是通过反向传播学习得到的。

  • 优点:
    • PReLU 允许模型根据数据自适应地学习负半轴的斜率,从而可能获得比固定 α 更好的性能。
    • 解决了“死亡ReLU”问题。
  • 缺点:
    • 引入了一个额外的可学习参数,增加了模型的复杂性。
  • 应用场景: 适用于需要模型更灵活地学习激活行为的场景,尤其是在深度网络中。

6. ELU 函数 (Exponential Linear Unit)

ELU 函数旨在结合ReLU的优点并解决其缺点,其数学表达式为:

f(x) = x (if x > 0)
f(x) = α * (e^x - 1) (if x <= 0)

其中 α 是一个正数常数,通常设置为1.0。

  • 优点:
    • 解决了“死亡ReLU”问题: 在负输入区域,ELU 具有一个负的输出,避免了输出为0导致神经元死亡。
    • 输出接近0均值: 使得ELU的输出均值更接近0,有助于缓解非零中心问题,加速收敛。
    • 在负区域具有饱和特性(趋近于-α),使得对噪声更鲁棒。
  • 缺点:
    • 包含指数运算,计算复杂度高于ReLU和Leaky ReLU。
  • 应用场景: 在某些情况下,ELU 表现优于ReLU和Leaky ReLU,尤其是在训练深层网络时,因为它能够更好地处理负输入和零均值输出。

7. GELU 函数 (Gaussian Error Linear Unit)

GELU 函数是近期在Transformer模型中非常流行的激活函数,它结合了ReLU的稀疏性和ELU的平滑性。其数学表达式为:

f(x) = x * P(X <= x)

其中 P(X <= x) 是标准正态分布的累积分布函数(CDF)。

  • 优点:
    • 平滑性: GELU 是一个平滑的非单调函数,在负值部分更加平滑,有助于梯度下降。
    • 与Dropout兼容: GELU 的设计是基于输入乘以一个“门控”值,这个门控值取决于输入。它被认为是ReLU和Dropout的一个自然替代品,在某些随机正则化方式下表现更好。
    • 在Transformer模型中表现出色,尤其是在大规模预训练模型(如BERT, GPT)中被广泛采用。
  • 缺点:
    • 计算比ReLU更复杂,需要计算CDF。
  • 应用场景: 主要用于Transformer和大型语言模型中,在自然语言处理领域取得了显著成功。

8. Swish 函数

Swish 函数是由谷歌大脑团队提出的一种激活函数,其数学表达式为:

f(x) = x * Sigmoid(βx)

其中 β 是一个可学习的参数或固定为1。

  • 优点:
    • 平滑性: Swish 是一个平滑的非单调函数,这意味着它在某些区域可以同时增加和减少,这使得它能够更好地捕获数据中的复杂模式。
    • 无上限且有下限: 与ReLU不同,Swish 在正向无上限,在负向有下限,这有助于防止梯度爆炸并提供一定的稀疏性。
    • 在大量实验中,Swish 及其变体(如 h-Swish)在图像分类等任务上表现优于ReLU。
  • 缺点:
    • 包含Sigmoid 函数,计算复杂度高于ReLU。
  • 应用场景: 在图像分类任务中取得了不错的成果,尤其是在MobileNet V3等轻量级网络中使用了其近似版本h-Swish。

9. Softmax 函数

Softmax 函数通常用于神经网络的输出层,特别是多分类问题。它将一个包含 K 个实数的向量归一化为 K 个概率值,这些概率值的和为1。其数学表达式为:

S_i = e^(z_i) / Σ(e^(z_j)) (for j from 1 to K)

其中 z 是网络的原始输出向量(logits),S_i 是第 i 个类别的预测概率。

  • 优点:
    • 将任意实数向量转换为概率分布,使得所有输出值的和为1。
    • “赢者通吃”特性:最大的输入值会得到最高的概率,同时抑制其他较小的值,使得分类结果更清晰。
    • 可导,方便梯度下降。
  • 缺点:
    • 主要用于输出层,不适用于隐藏层。
    • 包含指数运算,计算相对复杂。
  • 应用场景: 多分类问题的输出层。

如何选择合适的激活函数?

选择合适的激活函数没有一劳永逸的规则,通常需要根据具体问题、网络架构和经验进行尝试。以下是一些通用的指导原则:

  1. 隐藏层:
    • ReLU 是首选: 在大多数情况下,ReLU 及其变体(Leaky ReLU、PReLU、ELU)是隐藏层的最佳选择。它们计算效率高,且能有效缓解梯度消失问题。
    • 处理“死亡ReLU”: 如果发现 ReLU 模型训练不稳定或出现大量“死亡”神经元,可以尝试使用 Leaky ReLU、PReLU 或 ELU 来解决。
    • 尝试较新的函数: 对于特定任务(如NLP中的Transformer),GELU 和 Swish 可能会带来更好的性能,值得尝试。
    • 避免 Sigmoid 和 Tanh: 在深度网络的隐藏层中,应尽量避免使用 Sigmoid 和 Tanh,因为它们容易导致梯度消失,使得网络难以训练。
  2. 输出层:
    • 二分类问题: 通常使用 Sigmoid 函数,将输出映射到0-1的概率值。
    • 多分类问题: 使用 Softmax 函数,将输出映射为各类别的概率分布。
    • 回归问题: 通常不使用激活函数(即使用恒等函数或线性激活),因为输出可以是任意实数值。
  3. 实验与调优: 最佳的激活函数选择往往需要通过实验来确定。在实际项目中,可以尝试不同的激活函数组合,并通过交叉验证来评估其性能。
  4. 考虑计算资源: 虽然某些复杂的激活函数可能提供更好的性能,但其计算开销也可能更大,需要权衡模型的性能和计算效率。

常见问题 (FAQ)

「为何激活函数是非线性的?」

如果激活函数是线性的,那么无论神经网络有多少层,它都只能表示一个线性的变换。多层线性变换的组合仍然是线性的,这将导致深层网络退化为单层网络,无法学习和逼近现实世界中复杂的非线性关系。非线性激活函数赋予了神经网络学习复杂模式的能力。

「如何避免ReLU的“死亡”问题?」

避免ReLU“死亡”问题的方法包括:使用较小的学习率;初始化权重时避免过大的负值;或者采用ReLU的变体,如Leaky ReLU(在负半轴有一个小的斜率,使负输入也能有非零梯度)、PReLU(负半轴斜率可学习)或ELU(在负半轴趋于饱和,但有非零值)。

「为何不同的网络层可能需要不同的激活函数?」

通常情况下,隐藏层和输出层对激活函数的需求不同。隐藏层主要用于引入非线性、提取特征,因此需要像ReLU及其变体这样能有效传播梯度、计算高效的函数。而输出层则需要根据任务类型(如二分类、多分类或回归)将网络输出转换为有意义的形式,例如概率值(Sigmoid/Softmax)或连续值(线性函数)。

「如何选择适合自己模型的激活函数?」

选择激活函数没有绝对的“最佳”答案。通常的策略是:首先尝试ReLU,因为它在大多数情况下表现良好且计算高效。如果遇到梯度消失或“死亡ReLU”问题,可以考虑Leaky ReLU、PReLU或ELU。对于特定任务(如NLP中的Transformer模型),可以尝试GELU或Swish。最终的选择往往需要通过实际的模型训练和性能评估来确定。

「为何Sigmoid和Tanh在深层网络中表现不佳?」

Sigmoid和Tanh函数在输入值过大或过小时,其导数会趋近于0,这导致在反向传播时,梯度会变得非常小,难以传递到网络的深层,从而出现梯度消失问题。这使得深层网络的权重更新非常缓慢,甚至停滞,导致模型难以收敛和学习。

激活函数有哪些