激活函数篇 01 —— 激活函数在神经网络的作用
欢迎来到我的主页:【Echo-Nie】
本篇文章收录于专栏【机器学习】
以下是激活函数系列的相关的所有内容:
激活函数篇 01 —— 一文搞懂激活函数在神经网络中的作用
逻辑回归:Sigmoid函数在分类问题中的应用
1 激活函数的作用
1.1 引入非线性
激活函数为神经元引入了非线性,使得神经网络能够学习和模拟复杂的非线性关系。如果没有激活函数,神经网络将只能学习线性关系,其表达能力将大大受限。例如,一个没有激活函数的神经网络本质上是一个线性变换,无法解决像 XOR 这样的非线性问题。
数学上,如果没有激活函数,神经网络的输出可以表示为:
y
=
W
2
(
W
1
x
+
b
1
)
+
b
2
y=W_2(W_1x+b1)+b2
y=W2(W1x+b1)+b2
这仍然是一个线性变换。而引入激活函数后,输出变为:
y
=
W
2
σ
(
W
1
x
+
b
1
)
+
b
2
y=W_2σ(W_1x+b1)+b2
y=W2σ(W1x+b1)+b2
其中
σ
σ
σ 是激活函数,使得模型能够学习非线性关系。
1.2 控制输出范围
激活函数可以控制神经元的输出范围,防止输出值过大或过小,从而避免梯度消失或梯度爆炸问题。例如,Sigmoid 函数将输出值限制在 (0,1) 之间,Tanh 函数将输出值限制在 (−1,1) 之间。
这种控制有助于保持梯度的稳定,使得模型在训练过程中能够更好地收敛。
1.3 引入稀疏性
一些激活函数(如 ReLU)可以引入稀疏性,即输出值中有许多零值。这有助于减少模型的复杂度,提高计算效率,并防止过拟合。
例如,ReLU 函数的输出在输入小于零时为零,这使得网络中的许多神经元在某些输入下不激活,从而引入稀疏性。
1.4 提供可导性
激活函数需要是可导的,以便在训练过程中进行反向传播。通过计算激活函数的导数,可以更新网络权重,从而优化模型性能。
例如,Sigmoid 函数的导数为:
σ
′
(
x
)
=
σ
(
x
)
⋅
(
1
−
σ
(
x
)
)
σ′(x)=σ(x)⋅(1−σ(x))
σ′(x)=σ(x)⋅(1−σ(x))
这使得在反向传播过程中可以计算梯度并更新权重。
2 为什么需要激活函数
线性模型的局限性
线性模型在数学上可以简单地表示为 y = W x + b y=Wx+b y=Wx+b,其中 W W W 是权重矩阵, x x x 是输入向量, b b b 是偏置项。这种形式的模型只能捕捉输入与输出之间的线性关系,无法处理复杂的非线性问题。例如,XOR问题是典型的非线性问题,不能通过任何线性模型解决。这是因为线性变换(如上述公式)只能将数据映射到一个线性空间中,而无法捕捉到更复杂的数据结构。
如果我们考虑一个多层感知机(MLP),没有激活函数的情况下,即使增加层数,整个网络仍然只能执行一系列线性变换,最终等价于单层的线性变换。这意味着无论网络有多深,它都无法学习和表达复杂的非线性模式。
非线性问题的普遍性
现实世界中的大多数问题都是非线性的,比如图像识别、语音识别和自然语言处理等领域。以图像识别为例,图像中的边缘、纹理和其他特征通常是通过非线性方式组合在一起的。因此,为了使神经网络能够有效地学习这些特征,必须引入非线性组件——即激活函数。
激活函数使得每一层神经元的输出不再是简单的线性组合,而是经过了一个非线性转换。这允许网络学习到输入数据之间更加复杂的依赖关系,并提高其泛化能力。例如,在卷积神经网络(CNNs)中,使用ReLU激活函数可以帮助模型有效地捕捉图像中的局部特征。
梯度消失和梯度爆炸
在深层神经网络中,反向传播算法用于更新网络中的权重。这个过程涉及到计算损失函数相对于每个权重的梯度,并使用这些梯度来调整权重。然而,某些激活函数可能会导致梯度消失或梯度爆炸的问题,特别是在使用Sigmoid或Tanh这样的激活函数时。
-
梯度消失:当使用Sigmoid作为激活函数时,如果输入值较大或较小,该函数的导数接近于0。这意味着在网络的较深层中,梯度信息会变得非常小,几乎无法对权重进行有效更新,从而减慢了训练速度甚至导致训练停滞。
-
梯度爆炸:相反的情况是梯度爆炸,当梯度过大时会导致权重更新过大,从而使训练过程不稳定。
ReLU激活函数在这方面表现出色,因为它在 x > 0 x>0 x>0时保持导数为1,避免了梯度消失的问题。然而,ReLU也有自己的局限性,比如可能导致某些神经元永远不被激活(称为“死神经元”)。为此,发展出了Leaky ReLU、ELU等变体来克服这些问题。
3 激活函数的用途
1. 隐藏层:
在神经网络的隐藏层中,激活函数用于引入非线性,使网络能够学习复杂的特征表示。常用的激活函数包括 ReLU、Tanh 和 Sigmoid。
例如,ReLU 函数在隐藏层中广泛使用,因为它计算简单,不易出现梯度消失问题。
2. 输出层:
在神经网络的输出层中,激活函数用于将网络的输出值映射到特定的范围内。
二分类问题:使用 Sigmoid 函数,将输出值映射到
(
0
,
1
)
(0,1)
(0,1) 之间,表示概率。
多分类问题:使用 Softmax 函数,将输出值映射到概率分布。
回归问题:通常不使用激活函数,或者使用线性激活函数。
3. 特定任务
一些特定任务可能需要特定的激活函数。例如:
图像生成:使用 GELU 或 Swish 函数,这些函数在生成任务中表现较好。
自然语言处理:使用 ReLU 或 GELU 函数,这些函数在处理序列数据时表现较好。
4 常见激活函数及其特点
- Sigmoid 函数:
σ ( x ) = 1 1 + e − x \sigma(x) = \frac{1}{1 + e^{-x}} σ(x)=1+e−x1
输出范围在 ( 0 , 1 ) (0, 1) (0,1) 之间,常用于二分类问题。但容易出现梯度消失问题。
-
Tanh 函数:
tanh ( x ) = e x − e − x e x + e − x \tanh(x) = \frac{e^x - e^{-x}}{e^x + e^{-x}} tanh(x)=ex+e−xex−e−x
输出范围在 ( − 1 , 1 ) (-1, 1) (−1,1) 之间,常用于隐藏层。但同样容易出现梯度消失问题。
-
ReLU 函数:
ReLU ( x ) = max ( 0 , x ) \text{ReLU}(x) = \max(0, x) ReLU(x)=max(0,x)
输出范围在 [ 0 , ∞ ) [0, \infty) [0,∞) 之间,计算简单,不易出现梯度消失问题。但可能导致神经元死亡(即输出恒为零)。
-
Leaky ReLU 函数:
Leaky ReLU ( x ) = { x if x > 0 α x if x ≤ 0 \text{Leaky ReLU}(x) = \begin{cases} x & \text{if } x > 0 \\ \alpha x & \text{if } x \leq 0 \end{cases} Leaky ReLU(x)={xαxif x>0if x≤0
解决了 ReLU 的神经元死亡问题,输出范围在 ( − ∞ , ∞ ) (-\infty, \infty) (−∞,∞) 之间。但参数 α \alpha α 需要调优。
-
ELU 函数:
ELU ( x ) = { x if x > 0 α ( exp ( x ) − 1 ) if x ≤ 0 \text{ELU}(x) = \begin{cases} x & \text{if } x > 0 \\ \alpha (\exp(x) - 1) & \text{if } x \leq 0 \end{cases} ELU(x)={xα(exp(x)−1)if x>0if x≤0
在 x ≤ 0 x \leq 0 x≤0 时有平滑的指数衰减,解决了 ReLU 的神经元死亡问题,输出范围在 ( − ∞ , ∞ ) (-\infty, \infty) (−∞,∞) 之间。
-
Softmax 函数:
Softmax ( x i ) = e x i ∑ j = 1 n e x j \text{Softmax}(x_i) = \frac{e^{x_i}}{\sum_{j=1}^n e^{x_j}} Softmax(xi)=∑j=1nexjexi
将输出值映射到概率分布,常用于多分类问题。
-
Swish 函数:
Swish ( x ) = x ⋅ σ ( x ) \text{Swish}(x) = x \cdot \sigma(x) Swish(x)=x⋅σ(x)
自门控激活函数,性能优于 ReLU,计算复杂度稍高。
-
GELU 函数:
GELU ( x ) = x ⋅ Φ ( x ) \text{GELU}(x) = x \cdot \Phi(x) GELU(x)=x⋅Φ(x)
高斯误差线性单元,性能优于 ReLU,常用于 Transformer 模型。
5 关于XOR问题
XOR(Exclusive OR,异或)问题是逻辑运算中的一个经典问题,它展示了为什么简单的线性模型不足以解决某些类型的分类问题。XOR操作符是一个二进制运算符,其结果为真仅当两个输入的值不相等时。具体来说,对于两个二进制输入A和B,XOR的结果如下:
输入A | 输入B | 输出 |
---|---|---|
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 0 |
XOR问题是非线性可分的。这意味着不能通过一条直线(在二维空间中)或超平面(在多维空间中)将两类数据点完全分开。如果我们将XOR问题的数据点画在一个二维平面上,你会发现无法找到一条直线将输出为1的点与输出为0的点区分开来。
例如,在上述表格中,(0,0) 和 (1,1) 的输出是0,而 (0,1) 和 (1,0) 的输出是1。如果我们尝试用一条直线划分这些点,我们会发现这是不可能的,因为这两类点交错在一起。
XOR问题常用来说明为什么需要使用具有激活函数的多层感知机(MLP),而不是单层感知机。单层感知机只能处理线性可分的问题,即可以通过一条直线或超平面将不同类别的数据点分开的问题。然而,如上所述,XOR问题是线性不可分的。
引入非线性激活函数并增加至少一层隐藏层的神经网络能够解决这个问题。隐藏层中的非线性变换允许网络学习到更复杂的特征表示,从而有效地解决像XOR这样的非线性问题。实际上,一个多层感知机(MLP)通过结合多个线性变换和非线性激活函数,能够逼近任何连续函数,包括解决XOR问题。