神经网络中的激活函数
深入解析神经网络激活函数的奥秘
简介
激活函数是神经网络出色能力的秘密武器。它们是决策者,根据接收到的输入确定神经元是否应该“触发”或保持休眠。虽然这听起来像是一个复杂的技术细节,但了解激活函数对于任何涉足人工神经网络的人来说都是至关重要的。
在这篇博文中,我们将以易于理解的方式揭开激活函数的神秘面纱,即使你对机器学习还不熟悉。把它看作是解锁神经网络隐藏潜力的关键。在阅读完本文之后,你将理解激活函数是什么,以及它们在深度学习中的重要性。
因此,无论你是一个初出茅庐的数据科学家,一个热衷于机器学习的爱好者,还是对那些神经网络内部发生的魔法好奇,系好安全带,让我们踏上探寻人工智能核心的旅程:激活函数。
学习目标
- 了解激活函数在神经网络中的作用和转换。
- 探索常用的激活函数及其优缺点。
- 识别特定激活函数的应用场景及其对梯度流的影响。
本文是作为 数据科学博客马拉松 的一部分发表。
什么是激活函数?
激活函数是神经网络中的决策者。它们附加在每个神经元上,起着决定神经元是否应被激活的关键作用。这个激活决策取决于神经元接收到的输入是否与网络的预测相关。
激活函数充当了守门员的角色,只允许特定的信息通过并对网络的输出做出贡献。它们为神经网络添加了一个不可或缺的非线性层,使其能够学习和表示数据中的复杂模式。
要深入了解这个关键概念,探索一些常用的激活函数及其独特特性。激活函数还在规范化每个神经元的输出方面起着重要作用,将其限制在特定范围内,通常是0到1之间或-1到1之间。
在神经网络中,输入被提供给输入层中的神经元。每个神经元与一个权重相关联,神经元的输出是通过将输入与其相应的权重相乘计算得出的。然后将该输出传递到下一层。
激活函数是当前神经元输入和传递到后续层的输出之间的数学“门”。它可以是一个简单的步函数,根据定义的规则或阈值有效地开关神经元的输出。
关键是,神经网络使用非线性激活函数。这些函数对于使网络理解复杂的数据模式、计算和学习与给定问题相关的几乎任何函数以及最终做出精确预测至关重要。
了解更多信息:Activation Functions | Fundamentals Of Deep Learning
常用的激活函数
- Sigmoid函数
- tanh函数
- ReLU函数
- Leaky ReLU函数
- ELU(指数线性单元)函数
Sigmoid函数
Sigmoid函数的公式和曲线如下所示,
Sigmoid函数是深度学习初期最常用的激活函数。它是一个易于推导的平滑函数。
sigmoid函数的输出在开区间(0,1)内。我们可以将其视为概率,但严格来说,不要将其视为概率。sigmoid函数曾经更为广泛地应用。我们可以将其视为神经元的激活率。在斜率相对较大的中间区域是神经元的敏感区域。神经元的抑制区域位于两侧,具有缓和的斜率。
将Sigmoid函数视为描述神经网络中神经元活跃程度或“激发程度”的一种方式。想象一下,在您的网络中有一个神经元,就像一台开关。
- 当Sigmoid函数的输出接近1时,您可以将神经元想象成高度敏感的状态,就像它准备强烈地对输入做出响应。
- 在斜率很陡的中间区域,神经元是最敏感的。如果您稍微改变输入,神经元的输出将发生显著变化。
- 在斜率较缓和的两侧,就像是神经元处于抑制区域。在这里,即使您稍微改变输入,神经元的反应也不大。在这些区域,它不太敏感。
这个函数本身存在某些缺陷。
- 当输入稍微偏离坐标原点时,函数的梯度变得非常小,几乎为零。
- 为什么值为零或可以忽略不计?
- Sigmoid函数输出的区间为0或1。Sigmoid函数的公式是F(x) = 1 / (1 + e^-z),所以我们将值z = 0或1代入其中。(1 + e^-z)始终更大。但是这个术语出现在分母上,因此整体计算非常小。
- 因此,梯度函数的值非常小或几乎为零。
- 在神经网络中的反向传播中,我们依靠求导数的链式法则来计算每个权重(w)的梯度。然而,当反向传播通过Sigmoid函数时,链式法则中的梯度可以变得非常小。而且,如果这种情况发生在具有Sigmoid函数的多个层次上,可能会导致权重(w)对损失函数产生最小影响。这种情况对于权重优化来说是不利的,通常称为“梯度饱和”或“梯度消失”。
- 考虑一个层次……
2. 函数输出不以0为中心,这可能降低权重更新的效率。
3. Sigmoid函数涉及指数运算,对计算机而言可能计算速度较慢。
Sigmoid函数的优点和缺点
Tanh函数
Tanh函数的公式和曲线如下:
Tanh代表双曲正切,是与Sigmoid函数密切相关的激活函数。虽然tanh和sigmoid函数的曲线相似,但有值得注意的区别。让我们进行比较。
一个共同的特点是,当输入值非常大或非常小时,两个函数都会产生几乎平滑的输出,梯度很小。这可能对训练过程中的有效权重更新构成挑战。然而,关键区别在于它们的输出区间。
Tanh的输出区间范围从-1到1,整个函数都以0为中心,这使其与Sigmoid函数区分开来。
在许多情况下,tanh函数适用于神经网络的隐藏层。相比之下,Sigmoid函数通常用于输出层,尤其是二元分类任务。然而,这些选择并非绝对,应根据具体问题进行调整或通过实验和调优确定。
Tanh函数的优点和缺点
ReLU函数
ReLU函数的公式和曲线如下:
ReLU函数,全称修正线性单元,在深度学习中是一个相对较新且具有很大影响力的激活函数。与其他一些激活函数不同,ReLU非常直观。它简单地输出输入值与零之间的最大值。虽然ReLU缺乏完全可微性,但我们可以采用次梯度方法处理其导数,如上图所示。
近年来,ReLU获得了广泛的受欢迎度,原因是有充分的理由。它与sigmoid和tanh等传统激活函数相比具有突出优势。
ReLU函数的优势和劣势
Leaky ReLU函数
Leaky ReLU函数的公式和曲线如下所示:
为了解决“死亡ReLU问题”,研究人员提出了几种解决方案。一种直观的方法是将ReLU的前半部分设置为一个小的正值,如0.01x,而不是严格的零。另一种方法是引入可学习参数alpha的参数化ReLU。参数化ReLU函数是f(x)=max(alpha * x, x)。通过反向传播,网络可以确定alpha的最佳值(为选择alpha值,请选择最小值)。
从理论上讲,Leaky ReLU提供了ReLU的所有优势,同时消除了与“死亡ReLU”相关的问题。Leaky ReLU允许负输入具有一个小的非零梯度,防止神经元变得不活跃。然而,Leaky ReLU是否始终优于ReLU取决于具体的问题和架构。没有一种通用的答案,选择ReLU及其变种通常需要经验测试和微调。
这些ReLU函数的变体展示了增强神经网络性能和鲁棒性的持续追求,满足深度学习中各种应用和挑战的需求。
Leaky ReLU函数的优势和劣势
ELU(指数线性单元)函数
ELU函数的公式和曲线如下所示:
它是另一个激活函数,旨在解决ReLU引发的一些挑战。
ELU函数的优势和劣势
使用激活函数训练神经网络
在神经网络中选择激活函数对训练过程有重大影响。激活函数在确定神经网络如何学习以及它们能否有效地模拟数据中的复杂关系方面至关重要。在这里,我们将讨论激活函数如何影响训练,解决诸如梯度消失问题以及某些激活函数如何缓解这些挑战。
激活函数对训练的影响:
- 激活函数确定神经元在前向传播过程中如何将输入信号转换为输出激活。
- 在反向传播过程中,每层的梯度计算取决于激活函数的导数。
- 激活函数的选择影响神经网络的整体训练速度、稳定性和收敛性。
梯度消失问题:
- 梯度消失问题发生在激活函数的导数变得非常小的情况下,导致训练的收敛速度缓慢或停滞。
- sigmoid和tanh激活函数以在深度网络中引起梯度消失而闻名。
缓解梯度消失问题:
- 修正线性单元(ReLU)及其变体,如Leaky ReLU,通过为正输入提供非零梯度来解决梯度消失问题。
- 当输入为正时,ReLU函数导致更快的收敛速度,因为没有梯度消失问题。
零中心激活函数的作用:
- 像ELU这样提供零中心输出的激活函数通过提供正负梯度来缓解梯度消失问题。
- 零中心函数有助于在训练期间实现稳定的权重更新和优化。
自适应激活选择:
- 激活函数的选择应与网络结构和特定问题的要求相吻合。
- 必须通过实验证明不同的激活函数,以确定适合给定任务的最合适的函数。
实际示例
使用TensorFlow和Keras
import tensorflow as tffrom tensorflow.keras.layers import Densefrom tensorflow.keras.models import Sequential# 示例数据x = [[-1.0, 0.0, 1.0], [-2.0, 2.0, 3.0]]# Sigmoid激活model_sigmoid = Sequential([Dense(3, activation='sigmoid', input_shape=(3,))])output_sigmoid = model_sigmoid.predict(x)# Tanh激活model_tanh = Sequential([Dense(3, activation='tanh', input_shape=(3,))])output_tanh = model_tanh.predict(x)# ReLU激活model_relu = Sequential([Dense(3, activation='relu', input_shape=(3,))])output_relu = model_relu.predict(x)# Leaky ReLU激活model_leaky_relu = Sequential([Dense(3, activation=tf.nn.leaky_relu, input_shape=(3,))])output_leaky_relu = model_leaky_relu.predict(x)# ELU激活model_elu = Sequential([Dense(3, activation='elu', input_shape=(3,))])output_elu = model_elu.predict(x)print("Sigmoid输出:\n", output_sigmoid)print("Tanh输出:\n", output_tanh)print("ReLU输出:\n", output_relu)print("Leaky ReLU输出:\n", output_leaky_relu)print("ELU输出:\n", output_elu)#import csv
使用PyTorch
import torchimport torch.nn as nn# 示例数据x = torch.tensor([[-1.0, 0.0, 1.0], [-2.0, 2.0, 3.0]], dtype=torch.float32)# Sigmoid激活sigmoid = nn.Sigmoid()output_sigmoid = sigmoid(x)# Tanh激活tanh = nn.Tanh()output_tanh = tanh(x)# ReLU激活relu = nn.ReLU()output_relu = relu(x)# Leaky ReLU激活leaky_relu = nn.LeakyReLU(negative_slope=0.01)output_leaky_relu = leaky_relu(x)# ELU激活elu = nn.ELU()output_elu = elu(x)print("Sigmoid输出:\n", output_sigmoid)print("Tanh输出:\n", output_tanh)print("ReLU输出:\n", output_relu)print("Leaky ReLU输出:\n", output_leaky_relu)print("ELU输出:\n", output_elu)
以下是使用不同激活函数的提供的代码示例的输出:
Sigmoid输出:
Sigmoid输出: [[0.26894143 0.5 0.7310586 ] [ 0.11920292 0.8807971 0.95257413]]
Tanh输出:
Tanh输出: [[-0.7615942 0. 0.7615942] [-0.9640276 0.9640276 0.9950547]]
ReLU输出:
ReLU输出: [[0. 2. 3.] [ 0. 2. 3.]]
Leaky ReLU输出:
Leaky ReLU输出: [[-0.01 0. 1. ] [-0.02 2. 3. ]]
ELU输出:
ELU输出: [[-0.63212055 0. 1. ] [-1.2642411 2. 3. ]]
结论
激活函数是神经网络的命脉,决定了这些计算系统如何处理信息。从经典的Sigmoid和Tanh到ReLU及其变种的高效性,我们探讨了它们在塑造神经网络行为方面的作用。每个函数都具有独特的优点和缺点,选择合适的函数取决于数据的性质和您正在解决的具体问题。通过实际实现的见解,您现在有能力做出明智的决策,利用这些函数来优化神经网络的性能,释放深度学习在您的项目中的潜力。
主要收获:
- 激活函数对于神经网络是基础的,它们可以转换输入信号并使复杂的数据关系得以学习。
- 常见的激活函数包括Sigmoid、Tanh、ReLU、Leaky ReLU和ELU,每种函数都具有独特的特点和用途。
- 了解激活函数的优缺点有助于选择最适合特定神经网络任务的函数。
- 激活函数在反向传播过程中解决梯度问题(如梯度消失)至关重要。
常见问题解答(FAQs)
本文中显示的媒体不归Analytics Vidhya所有,而是由作者自行决定使用。