跳至主要内容

ReLU(修正线性单元)新手指南

了解这一最受欢迎的神经网络激活函数之一的基础知识
Javier Canales Luna
Javier Canales Luna

创建您的免费账户

实践并学习路径你的进步。

使用 Google 继续继续即表示您接受我们的 使用条款,我们的 隐私政策 ,并且您的数据存储在美国。

诸如 ReLU(修正线性单元)之类的激活函数是现代神经网络的基石。没有它们,许多现实世界的 AI 应用——从图像识别到推荐系统——都将无法实现。本文将介绍 ReLU 的基础、优点、局限性及其实现。

ReLU 基础

许多最强大的 AI 应用离不开人工神经网络。神经网络是受人脑启发的计算模型,由相互连接的节点(“神经元”)组成,共同处理信息并做出决策。使神经网络“深”的是输入与输出之间的层数。深度神经网络包含多个层,能够学习更复杂的特征并做出更准确的预测。

Deep neural network

深度神经网络。来源: DataCamp

然而,这些模型远不止是简单的层堆叠。还有其他组件对神经网络发挥作用同样至关重要。

其中之一就是激活函数。您可以将激活函数看作“决策者”;它们决定哪些信息应传递到下一层,引入新的复杂度,使神经网络能够做出细致入微的判断。

本文将介绍最受欢迎且应用最广的激活函数之一:修正线性单元(ReLU)。我们将讲解这一激活函数及其部分变体的基础知识、优点与局限,并展示如何用 PyTorch 实现。继续阅读吧。

什么是激活函数?

激活函数是神经网络不可或缺的构件。它们将神经网络中某个节点的输入信号变换为输出信号,再传递至下一层。没有激活函数,神经网络将只能建模输入与输出之间的线性关系,例如通过矩阵乘法。

但大多数现实世界的数据无法用线性关系来建模。非线性能够捕捉这样的模式:从没有孩子到有一个孩子,对您的银行交易的影响可能不同于从三个孩子到四个孩子。如果神经网络没有激活函数,它们将无法学习现实事件中存在的复杂非线性模式。

Linear vs nonlinear functions

线性与非线性函数。来源: DataCamp

激活函数通过引入非线性行为,使神经网络能够学习这些关系。换言之,激活函数设定数值阈值以决定是否激活某个神经元,从而引入关键的灵活性,帮助神经网络对复杂而细腻的数据建模。

什么是 ReLU?

ReLU(修正线性单元)是最流行、应用最广的激活函数之一。与其他激活函数一样,它为模型提供非线性,从而提升计算性能。

ReLU 激活函数的形式为:

f(x) = max(0, x)

如图所示,ReLU 的输出为其输入与 0 之间的最大值。对于正输入,函数输出等于输入;对于严格为负的输入,函数输出等于 0。

Rectified Linear Unit (ReLU) activation function.

修正线性单元(ReLU)激活函数。来源: DataCamp

使用 ReLU 的优势

ReLU 最大的优势之一在于有助于缓解梯度消失问题。梯度消失是使用反向传播训练深度神经网络时出现的挑战:用于更新网络权重的梯度在向后传播时变得非常小,甚至“消失”。这会阻碍权重得到有效更新,从而减慢甚至停止学习过程。您可以在我们的PyTorch 深度学习入门课程中阅读对梯度消失问题的完整解释。

由于 ReLU 函数没有上界,且当 x 取较大值时梯度不会收敛为零,ReLU 能克服使用 sigmoid 与 softmax 激活函数时常见的梯度消失问题。想了解更多流行的激活函数,请查看我们的相关文章。

此外,ReLU 对所有负输入输出为 0,自然会产生稀疏激活。换言之,训练过程中只有一部分神经元被激活,从而提高计算效率。

最后,与 tanh 或 sigmoid 等更复杂的函数相比,这种行为使网络能够扩展到更多层,而不会显著增加计算负担。这使得 ReLU 成为最常用的默认激活函数;当您不确定在模型中使用何种激活函数时,通常选择 ReLU 是不错的。

在 PyTorch 中实现 ReLU

在 PyTorch 中实现 ReLU 相当容易。您只需使用 nn.ReLU() 创建该函数并将其加入模型。

在下面的示例中,我们将 ReLU 应用于一个简单的神经元,并在负值情况下计算梯度。

# Create a ReLU function with PyTorch
relu_pytorch = nn.ReLU()

# Apply your ReLU function on x, and calculate gradients
x = torch.tensor(-1.0, requires_grad=True)
y = relu_pytorch(x)
y.backward()

# Print the gradient of the ReLU function for x
gradient = x.grad
print(gradient)
>>> tensor(0.)

请注意,输入值为 -1,ReLU 函数返回了 0。回想一下,对于负的 x 值,ReLU 的输出始终为 0;确实,由于在任何负值的 x 上函数都没有变化,梯度在这些位置也处处为 0。

ReLU 的变体

ReLU 可以说是使用最广的激活函数,但有时它可能并不适用于您要解决的问题。幸运的是,深度学习研究者提出了若干 ReLU 变体,值得在您的模型中尝试。以下是最常见的替代方案:

Leaky ReLU

Leaky ReLU 的形式为:

f(x) = max(0.01x, x)

Leaky ReLU 的目标是解决所谓的“ReLU 失活(dying ReLU)”问题。我们已提到,ReLU 对负输入总是输出 0。这样会导致具有负值的节点在余下训练过程中梯度被置为 0,从而无法继续学习。为克服这一挑战,Leaky ReLU 对负输入引入了一个乘法因子。结果是,函数不再为 0,而是具有一个很小的负斜率,如下图所示:

Leaky ReLU activation function.

Leaky ReLU 激活函数。来源: DataCamp

参数化 ReLU(PReLU)

Leaky ReLU 通过乘法因子来克服 ReLU 失活问题。参数化 ReLU(PReLU)更进一步,用一个可学习的参数 a 取代常数来计算负输入的值:

f(x) = max(ax, x)

与 ReLU 和 Leaky ReLU 相比,PReLU 在准确性与适应性方面有所改进(它尤其适合捕捉诸如计算机视觉或语音识别等复杂任务中的模式),但也为模型带来了更多复杂性。训练这一参数可能耗时,并需要谨慎的调参与正则化。

Parametric ReLU activation function

参数化 ReLU 激活函数。来源: DataCamp

指数线性单元(ELU)

另一种优秀的 ReLU 替代方案是指数线性单元(ELU),其公式如下:

与 ReLU 相比,ELU 允许负值输出,使其能够将单元激活的均值推向零,从而降低梯度消失的风险。此外,均值激活更接近于零也会带来更快的学习速度与收敛。

ELU activation function

ELU 激活函数。来源: DataCamp

ReLU 的常见问题

ReLU 是一个很棒的激活函数,但并非万能。特别是,它可能会遭遇两类广为人知的问题。

其一是 ReLU 失活问题。如前所述,ReLU 对负输入总输出为 0。这会导致权重以某种方式更新,使该神经元此后再也不会在任何数据点上被激活。

一旦发生这种情况,流经该单元的梯度从那一刻起将永远为 0,从而阻止该参数继续学习。为解决这一问题,人们提出了 Leaky ReLU 和 PReLU 等 ReLU 变体。

另一端也可能出现不稳定的梯度。梯度爆炸问题发生在梯度越来越大时,导致参数更新幅度巨大、训练发散。

在这种情况下,较大的误差梯度不断累积,模型权重会过大。该问题可能导致训练时间延长、模型表现不佳。应对梯度爆炸的技术包括梯度裁剪与批量归一化等。

ReLU 在神经网络中的应用

凭借其独特特性,ReLU 已成为最受欢迎的激活函数,是 PyTorch 和 TensorFlow 等框架中的默认选项,并被广泛应用于许多深度学习场景,包括:

  • 图像识别:ReLU 是卷积神经网络(CNN)的关键组成部分。CNN 是常用于特征提取与图像处理的专用网络。
  • NLP:ReLU 也用于许多自然语言处理(NLP)任务。该激活函数在语音识别与音频处理等领域成功提供了非线性。
  • 推荐系统:ReLU 被用于推荐系统中,以提供个性化推荐。

结论

我们探讨了 ReLU 激活函数在神经网络训练中的关键作用。尽管简单,ReLU 依然是最有效的激活函数之一,也可以说是最受欢迎的。

随着神经网络不断演进,对激活函数的探索无疑也会扩展,可能会出现新的形式,以应对新兴架构的特定挑战。

对激活函数的精心选择是一种平衡——既需要科学理解,也需要直觉拿捏——并会显著影响神经网络的性能。

想进一步学习深度学习?查看我们的精选资料,为迎接这一最具变革性的 AI 技术做好准备:

ReLU 常见问答

ReLU 与 sigmoid 和 tanh 激活函数有何不同?

ReLU 与 sigmoid 和 tanh 的不同之处在于,它不会将输出压缩到固定区间(例如 sigmoid 的 [0,1] 或 tanh 的 [-1,1])。相反,它对正值直接输出输入本身,对负值输出 0。其简洁性使 ReLU 在计算上高效,并有助于解决 sigmoid 与 tanh 常见的梯度消失问题。

在什么情况下我应优先使用 ReLU 而不是其他激活函数?

对于深度神经网络的大多数隐藏层,尤其是在训练大型模型或处理具有复杂非线性关系的数据集时,ReLU 是一个很好的默认选择。但如果您遇到“ReLU 失活”等问题或模型表现不佳,可考虑尝试 Leaky ReLU、PReLU 或 ELU 等变体。

ReLU 可以用于神经网络的输出层吗?

ReLU 通常不用于神经网络的输出层,因为其取值范围无上界,可能导致输出难以解释。输出层常见的选择包括:

  • Sigmoid:用于二分类问题。
  • Softmax:用于多分类问题。
  • 线性激活:用于回归任务。
ReLU 如何促成稀疏激活?这为何重要?

ReLU 通过对所有负输入输出 0 来促成稀疏激活,这意味着任意时刻只有一部分神经元处于激活状态。稀疏激活可以降低计算开销、防止过拟合,并促使网络聚焦于数据中最相关的特征。

有哪些实用技巧可用于调试训练中由 ReLU 引发的问题?

以下是一些建议:

  • 检查 ReLU 失活问题:在训练期间监控激活值。如果大量神经元持续输出 0,考虑使用 Leaky ReLU 或 PReLU。
  • 使用批量归一化:有助于稳定梯度,并防止当 ReLU 输出较大正值时可能出现的梯度爆炸等问题。
  • 梯度裁剪:若发生梯度爆炸,通过裁剪将梯度幅度限制到指定值,可提升稳定性。
  • 尝试不同的权重初始化:合适的初始化(如 He 初始化)可降低死神经元或收敛缓慢等问题的可能性。
Javier Canales Luna

作者

Javier Canales Luna

我是一名自由职业的数据分析师,与全球各地的公司和组织合作开展数据科学项目。我也担任数据科学讲师,拥有2年以上授课经验。我经常用英语和西班牙语撰写与数据科学相关的文章,其中一些已发表在 DataCamp、Towards Data Science 和 Analytics Vidhya 等知名网站上。作为一名具有政治学与法律背景的数据科学家,我的目标是在公共政策、法律与技术的交汇处开展工作,借助思想的力量推动创新解决方案与叙事,帮助我们应对紧迫挑战,尤其是气候危机。我认为自己是自学成才、不断进步的人,坚定支持跨学科合作。学习新事物永远不嫌晚。

主题