人工智能深度学习激活函数综述

368 阅读6分钟

一、激活函数的定义

在人工智能的神经网络算法中,激活函数(Activation Function)是一种数学函数,用于在神经网络的神经元中引入非线性因素。(一个神经元主要涉及两个过程,一是线性回归的过程,也就相当于对样本数据做线性变换,另一个就是逻辑回归,也就相当于对经过线性变换处理的数据做非线性变换,因为很多数据无法用线性变换来表示和拟合,所以需要引入非线性的函数来处理)。激活函数的主要作用是决定一个神经元是否应该被激活,以及激活的程度,没有激活函数,神经网络将仅仅是一个线性模型,无法解决复杂的非线性问题。

二、激活函数的特性

激活函数的一些关键特性包括:

  1. 非线性(最主要特性):激活函数引入非线性,使得神经网络能够学习和模拟复杂的函数映射。(其实也就是和线性回归的线性变换配合起来一起处理输入的数据,进一步提取特征,更好地拟化参数)

  2. 可导性:大多数激活函数是可微分的,这对于使用梯度下降等优化算法进行网络训练至关重要。

  3. 单调性:许多激活函数是单调的,这意味着随着输入的增加,输出也增加或减少。

  4. 范围限制:一些激活函数将输出限制在特定的范围内,如SigmoidSigmoidTanhTanh函数将输出限制在0和1之间,或-1和1之间。

三、常见的激活函数包括:

  1. Sigmoid:将输入映射到0和1之间,公式为 σ(x)=11+ex\sigma(x) = \frac{1}{1 + e^{-x}}。它在二分类问题中常用作输出层的激活函数。

  2. Tanh(双曲正切):将输入映射到-1和1之间,公式为tanh(x)=21+e2x1\tanh(x) = \frac{2}{1 + e^{-2x}} - 1。它比Sigmoid函数的输出范围更宽,有时可以提供更好的数值稳定性。

  3. ReLU(Rectified Linear Unit):公式为ReLU(x)=max(0,x) \text{ReLU}(x) = \max(0, x)。它在正区间是线性的,在负区间输出为0。ReLU函数在训练深度神经网络时非常流行,因为它可以减少梯度消失问题,并且计算效率高。

  4. Leaky ReLU:是ReLU的变种,允许负数有一个非零的梯度,公式为:

    LeakyReLU(x)=max(0.01x,x)\text{LeakyReLU}(x) = \max(0.01x, x)

  5. Parametric ReLU (PReLU) :是Leaky ReLU的扩展,其中的斜率是一个可学习的参数。

  6. Exponential Linear Unit (ELU) :公式为 ELU(x)={xif x>0α(ex1)if x0\text{ELU}(x) = \begin{cases} x & \text{if } x > 0 \\ \alpha(e^x - 1) & \text{if } x \leq 0 \end{cases},它在负值域内有一个非零的输出,有助于缓解梯度消失问题。

  7. Softmax:通常用于多分类问题的输出层,将输出转换为概率分布,公式为Softmax(xi)=exijexj\text{Softmax}(x_i) = \frac{e^{x_i}}{\sum_{j} e^{x_j}}

激活函数的选择对神经网络的性能有重要影响,不同的网络结构和任务可能需要不同的激活函数。笔者需要提醒大家的是,并不是越复杂的激活函数就越好,需要对应每一个具体的使用场景,并且,一些函数对于神经网络的层数和深度也是有要求的,有些函数在浅层神经网络上可能存在失效或无法正常运算的情况。

如果大家到这里不理解的话,老规矩,上例子!

四、实例说明激活函数

想象一下,你正在建造一个自动门,这个门需要根据某些条件自动开启和关闭。这个自动门的控制系统就像是神经网络中的一个神经元,而激活函数就像是控制门开关的逻辑。门打开的最终目的就是为了数据能够平滑地传递下去,使神经网络完整完善,不断提取学习输入数据的特征。

1. 线性激活函数(如:Identity Function)

假设我们的门有一个非常简单的开关逻辑:如果有人接近门(输入信号),门就打开;如果没有人,门就保持关闭。这就像是线性激活函数,它直接将输入信号传递出去,不做任何转换。在数学上,这可以表示为 f(x)=xf(x) = x

问题:这种门可能会在没有人的时候因为风吹草动而误开,或者在有人的时候因为信号太弱而不开。

2. 阶跃激活函数(如:Step Function)

为了改进,我们可以让门只在有人接近时打开,没有人时保持关闭。这就像是阶跃激活函数,它在输入信号超过某个阈值时输出一个固定值(比如1表示门开),否则输出另一个固定值(比如0表示门关)。在数学上,这可以表示为: f(x)={1if x>00otherwisef(x) = \begin{cases} 1 & \text{if } x > 0 \\ 0 & \text{otherwise} \end{cases}

问题:这种门虽然解决了误开的问题,但它不能平滑地处理信号,比如人慢慢接近门时,门不能平滑地打开。

3. Sigmoid激活函数

为了使门的开启更加平滑和连续,我们可以使用Sigmoid激活函数。这种门会根据输入信号的强度平滑地调整门的开启程度。Sigmoid函数的输出值在0到1之间,可以表示门的开启程度。在数学上,Sigmoid函数可以表示为: f(x)=11+exf(x) = \frac{1}{1 + e^{-x}}

优点:这种门可以根据输入信号的强度平滑地调整门的开启程度,使得门的开启更加自然和连续。

4. ReLU激活函数

但是,Sigmoid函数在输入值非常大或非常小的时候,输出的变化会非常缓慢,这在神经网络中会导致梯度消失问题。为了解决这个问题,我们可以使用ReLU(Rectified Linear Unit)激活函数。这种门在输入信号为正时直接传递信号,为负时则保持关闭。在数学上,ReLU函数可以表示为: f(x)=max(0,x)f(x) = \max(0, x)

优点:这种门在处理正信号时非常有效,计算简单,速度快,而且避免了梯度消失问题。

通过这些例子,我们可以看到不同的激活函数就像不同的门控制逻辑,它们决定了神经网络如何处理和响应输入信号。其中的每种激活函数都有其特定的应用场景和优缺点。

五、各激活函数对应的应用和优势情况

选择激活函数通常取决于特定的任务需求、网络结构和训练目标。

  1. Sigmoid(在处理输入结果为0和1这两种的 二分类 问题有优势,其他方面不常用) :

    1. 适用情况:二分类问题中的输出层,因为输出值在0到1之间,可以被解释为概率。

    2. 注意:在隐藏层中使用时,可能会遇到梯度消失问题,因为Sigmoid函数在输入值非常大或非常小的时候梯度接近0。

  2. Tanh(多的较多较广泛) :

    1. 适用情况:类似于Sigmoid,但输出值在-1到1之间,这有助于数据在训练过程中保持中心化,减少学习时间。

    2. 注意:同样可能遇到梯度消失问题。

  3. ReLU ( Rectified Linear Unit ) :

    1. 适用情况:大多数情况下的隐藏层,因为它解决了梯度消失问题,并且计算效率高。

    2. 注意:可能会遇到“死亡ReLU”问题,即在训练过程中某些神经元可能永远不会激活。

  4. Leaky ReLU:

    1. 适用情况:当ReLU遇到死亡神经元问题时,Leaky ReLU提供了一个非零的梯度,使得网络可以继续学习。

    2. 注意:需要调整负斜率参数。

  5. Parametric ReLU (PReLU) :

    1. 适用情况:与Leaky ReLU类似,但斜率参数是可学习的,可以更好地适应不同的数据集。

    2. 注意:增加了模型的复杂度。

  6. Exponential Linear Unit (ELU) :

    1. 适用情况:当需要减少激活函数输出的方差时,ELU在负值域内输出非零值,有助于缓解梯度消失问题。

    2. 注意:计算复杂度略高于ReLU。

  7. Softmax:

    1. 适用情况:多分类问题的输出层,将输出转换为概率分布。

    2. 注意:在处理具有大量类别的问题时,计算量可能较大。

  8. Swish:

    1. 适用情况:作为隐藏层的激活函数,Swish函数在某些任务中表现优于ReLU。

    2. 注意:计算复杂度高于ReLU。

  9. GELU (Gaussian Error Linear Unit) :

    1. 适用情况:在自然语言处理任务中,特别是在BERT等Transformer模型中,GELU作为激活函数取得了良好的效果。

    2. 注意:计算复杂度较高。

  10. Mish:

    1. 适用情况:作为隐藏层的激活函数,Mish在某些任务中表现优于ReLU和Swish。

    2. 注意:计算复杂度高于ReLU。

选择激活函数时,还需要考虑网络的深度、数据的特性以及训练的稳定性。通常,ReLU及其变种因其简单和高效而在实践中非常受欢迎。然而,对于特定的任务,可能需要实验不同的激活函数以找到最佳选择。

六、常见激活函数代码示例

以下是使用Python语言和NumPy库编写的一些常见激活函数:

1. Sigmoid 激活函数

import numpy as np

def sigmoid(x):
    return 1 / (1 + np.exp(-x))

2. ReLU 激活函数

def relu(x):
    return np.maximum(0, x)

3. Leaky ReLU 激活函数

def leaky_relu(x, alpha=0.01):
    return np.where(x > 0, x, x * alpha)

4. Tanh 激活函数

def tanh(x):
    return np.tanh(x)

5. Softmax 激活函数

Softmax 通常用于多分类问题的输出层,将输出转换为概率分布。

def softmax(x):
    e_x = np.exp(x - np.max(x))  # 减去最大值提高数值稳定性
    return e_x / e_x.sum(axis=0)

6. Swish 激活函数

Swish 是一种自门控的激活函数,由谷歌提出。

def swish(x):
    return x * np.sigmoid(x)

使用示例

# 测试数据
x = np.array([-1, 0, 1])

# 测试激活函数
print("Sigmoid:", sigmoid(x))
print("ReLU:", relu(x))
print("Leaky ReLU:", leaky_relu(x))
print("Tanh:", tanh(x))
print("Softmax:", softmax(x))
print("Swish:", swish(x))

这些代码展示了如何在Python中实现和使用各种激活函数。大家可以通过修改 x 的值来测试不同的输入对激活函数的影响。

以上就是笔者关于人工智能深度学习激活函数的综述,同时大家如果对单个激活函数不理解的话也不用着急,后续笔者也将对常见的每一个激活函数进行深度且详细的分析和解释,欢迎大家点赞,收藏,交流和关注,O(∩_∩)O谢谢!