当今的深度神经网络能够处理高度复杂的数据集。例如,目标检测器已经能够实时预测各种物体的位置;时间序列模型可以同时处理许多变量,还可以想象到其他许多应用。
问题是:这些网络是如何处理如此复杂性的?更具体地说,它们是如何做到以前机器学习模型所远不能及的事情的?
这个问题有两个答案。主要答案在于神经网络的深度——更深的网络能够处理更复杂的数据。然而,部分答案在于各种激活函数的应用——尤其是当今最常用的非线性激活函数:ReLU、Sigmoid、Tanh和Softmax。
什么是激活函数?
你可能还记得基本神经网络的结构,在深度学习中,它由全连接层组成:
在这个网络中,每个神经元都由一个权重向量和一个偏置值组成。当输入一个新的向量时,它会计算权重和输入向量之间的点积,加上偏置值,并输出标量值。
问题可以很简单地阐述:点积和标量加法都是线性操作。
因此,当你将这个值作为神经元的输出,并且对每个神经元都这样做时,你得到的系统将表现出线性行为。
而你可能知道,大多数数据都是高度非线性的。由于线性神经网络在那些情况下无法生成决策边界,因此在生成预测模型时应用它们将毫无意义。
因此,整个系统必须是非线性的。
输入激活函数。
这个函数直接放置在每个神经元的后面,以线性神经元输出为输入,并基于它生成非线性输出,通常是确定性的(即,当你两次输入相同的值时,你会得到相同的结果)。
这样,由于每个神经元实际上都生成了一个线性但非线性的输出,所以整个系统表现出非线性行为,因此能够处理非线性数据。
激活输出随输入增加而增加
神经网络是受人脑的启发而设计的。虽然它们非常简化,但在某种程度上与人类神经元的工作方式相似:人类神经元也是大型神经网络的一部分,神经元之间有突触(或路径)。在给定神经输入的情况下,人类神经元会激活并向其他神经元传递信号。
整个系统共同构成了我们所知的人类智力。
如果你想在神经网络的激活函数中模仿这种行为,你也需要模仿人类神经元的激活方式。显然,在人类神经网络中,当刺激(或神经元的输入)增加时,输出往往也会增加。因此,在人工神经网络中通常也是如此。
因此,我们正在寻找一种数学公式,它能够接受线性输入,生成非线性输出,并且随时间增加或保持稳定。
当今主流的激活函数
有许多激活函数,其中一些我们在之前的博客中已经介绍过,未来还会介绍更多。如今,最常用的激活函数有三种:Sigmoid函数、双曲正切(tanh)函数和修正线性单元(ReLU)。接下来,我们将更详细地了解它们。
Sigmoid
下面你将看到(通用的)Sigmoid函数,也称为逻辑曲线:
数学上,它可以表示如下:
从图中可以看出,这个函数随着时间的推移缓慢增加,但在x=0附近增加最快。函数的值域是(0, 1),所以当x值很大时,函数值趋近于1,但永远不会等于1。
Sigmoid函数具有多种用途。首先,由于我们知道在Keras中无法创建真正的Rosenblatt感知机,那些古老神经元中使用的阶跃函数是不可微的,因此无法应用梯度下降进行优化。其次,当你自己实现Rosenblatt感知机时,你会发现,在二分类问题中,每个神经元的决策边界都是最优的,并且如果存在可能的边界,它会找到其中一个。使用Sigmoid函数会让这个过程变得更容易,因为它更加平滑。
此外,也许最重要的是,我们使用Sigmoid函数是因为它的输出范围在(0, 1)之间。在估计概率时,这是非常完美的,因为概率的范围也是[0, 1](Sharma,2019)。特别是在二分类问题中,当我们实际上是在估计输出属于某个类的概率时,Sigmoid函数允许我们给出一个非常加权的估计。例如,在类A和类B之间,输出0.623表示“稍微更倾向于B类”。而如果使用阶跃函数,输出可能直接是1,那么这种细微的差别就消失了。
双曲正切:Tanh
另一个广泛使用的激活函数是双曲正切(或双曲正弦/tanh)函数:
代数上,这可以表示如下:
它与Sigmoid函数的工作方式相似,但也有一些不同。
首先,与Sigmoid函数类似,当x接近0时,输出的变化会加速。
它也与Sigmoid函数共享渐近性质:虽然当x的值非常大时,函数趋近于1,但实际上永远不会等于1。
然而,在定义域的较低侧,我们看到了范围上的差异:它趋近于-1,而不是像Sigmoid那样趋近于0作为最小值。
Sigmoid和Tanh之间的关键差异
你现在可能想知道Tanh和Sigmoid之间有什么不同。
显然,如我们之前所见,这两个激活函数的范围是不同的:(0, 1) vs (-1, 1)。
尽管这个差异看起来很小,但它可能对模型性能产生很大影响;特别是模型向最优解收敛的速度。
这与它们关于原点对称的事实有关。因此,它们产生的输出接近零。在优化过程中,接近零的输出是最好的:它们产生的权重波动最小,因此能让你的模型更快收敛。当你的模型非常大时,这将非常有帮助。
如我们所见,Tanh函数关于原点对称,而Sigmoid函数则不是。
Sigmoid和Tanh的挑战
LeCun等人的论文写于1998年,而深度学习领域已经取得了长足的发展……识别出为了推动深度学习领域发展而必须解决的挑战。
首先,我们必须谈谈模型稀疏性。在优化过程中,模型越不复杂,收敛速度就越快,也越有可能及时找到数学上的最优解。
而复杂性可以看作是模型中仍然存在的、不重要的神经元的数量。这些神经元越少,模型就越好——或者说更稀疏。
Sigmoid和Tanh基本上会产生非稀疏模型,因为它们的神经元几乎总是会产生一个输出值:当范围分别是(0, 1)和(-1, 1)时,输出要么不能为零,要么为零的概率非常低。
因此,如果某些神经元在权重方面不那么重要,它们就无法被“移除”,模型也就不稀疏。
这些激活函数的输出范围可能带来的另一个问题是所谓的梯度消失问题。在优化过程中,数据被输入到模型中,然后将输出结果与实际目标值进行比较。这会产生所谓的损失。由于损失可以被认为是一个(可优化的)数学函数,我们可以计算向零导数(即数学最优解)的梯度。
然而,神经网络由多层神经元组成。我们基本上需要针对下游层,对每一层重复这个过程,并将它们串联起来。这就是反向传播。随后,我们可以使用梯度下降或类似的优化器来优化模型。
当神经元的输出非常小(即-1 < 输出 < 1)时,优化过程中产生的链会向上游层逐渐变小。这将导致它们学习得非常慢,甚至让人怀疑它们是否能收敛到最优解。这就是梯度消失问题。
修正线性单元:ReLU
为了改进这些观察结果,引入了另一种激活函数。这种名为修正线性单元(ReLU)的激活函数,如今是大多数深度学习项目的首选。它对上述问题的敏感性要低得多,因此改进了训练过程。
它的形式如下:
并可代数表示为:
或者用更通俗的英语来说,它对所有小于零的输入都产生零输出;而对所有其他输入则产生x。因此,对于所有小于等于0的输入,它都输出零。
稀疏性
这极大地有利于稀疏性:现在,在几乎一半的情况下,神经元都不再激活。这样,如果神经元对模型的预测能力不再那么重要,就可以让它们保持静默。
减少梯度消失
它还减少了梯度消失的影响,因为梯度始终是一个常数:f(x) = 0的导数是0,而f(x) = x的导数是1。因此,模型学习得更快、更均匀。
计算需求
此外,ReLU函数比Sigmoid和Tanh函数需要更少的计算资源。实现ReLU函数基本上只需要执行一个max函数:max(0, x),当x < 0时输出0,当x >= 0时输出x。这就是ReLU!
现在,将这与上面提到的Sigmoid和Tanh函数的公式进行比较:那些公式包含指数运算。计算max函数的输出要比计算指数的输出简单得多,计算成本也低得多。对于一次计算来说,这可能没什么大不了的,但请注意,在深度学习中会进行许多这样的计算。因此,ReLU减少了你对计算资源的需求。
Softmax函数
最后,我们将简要介绍著名的Softmax激活函数。
Softmax可以可视化如下:
Softmax函数是一种在机器学习和深度学习领域广泛使用的出色工具,用于将数字向量转换为概率向量。
这可以代数表示为:
通常,我们在神经网络的最后一层使用这个函数,它用于计算事件在’n’个不同事件上的概率分布。这个函数的主要优点是能够处理多个类别。
当我们比较Sigmoid和Softmax激活函数时,它们会产生不同的结果。
对于Sigmoid:
输入值:-0.5, 1.2, -0.1, 2.4
输出值:0.37, 0.77, 0.48, 0.91
而对于Softmax:
输入值:-0.5, 1.2, -0.1, 2.4
输出值:0.04, 0.21, 0.05, 0.70
Sigmoid产生的概率是独立的,并且它们的和并不受约束,可以不是1:0.37 + 0.77 + 0.48 + 0.91 = 2.53。这是因为Sigmoid是单独看待每一个原始输出值的。而Softmax的输出是相互关联的,Softmax的概率设计上总是和为1:0.04 + 0.21 + 0.05 + 0.70 = 1.00。在这种情况下,如果我们想增加某一个类的概率,其他类的概率就会相应地减少相同的量。
总结
在这篇文章中,我们深入探讨了当今一些标准的激活函数以及它们的优点和可能的缺点。现在,你应该能够根据情况选择使用哪个函数了。不过,通常最好的做法是先从ReLU开始尝试,然后是tanh和Sigmoid,最后再考虑新的激活函数。这样,你可以通过实验找到哪个函数效果最好。但是,请注意你所需的资源,因为你可能无法尝试所有的选择。