当训练监督机器学习模型时,经常会听到最小化的、必须选择的损失函数(loss function)等等。术语“成本函数(cost function)”也等效地使用。
但是损失是什么?损失函数又是什么?
首先介绍高级监督学习过程,以奠定基础。这包括训练监督模型时训练、验证和测试数据的作用。了解了这些内容后,将介绍损失。回答什么是损失?什么是损失函数?
高级监督学习过程
在真正引入损失的概念之前,必须先了解一下高级监督机器学习过程。所有监督训练方法都属于这一过程,这意味着它对于深度神经网络(如 MLP 或ConvNets)和支持向量机(Support Vector Machines)都是一样的。来看看这个训练过程,它本质上是循环的。
前向传播(Forward pass)
从特征和目标开始,它们也称为数据集。在训练过程开始之前,该数据集被分成三个部分:训练数据、验证数据和测试数据。训练数据在训练过程中使用;更具体地说,在前向传递期间生成预测。但是,在每个训练周期之后,必须测试模型的预测性能。这就是验证数据的用途——它有助于模型优化(model optimization)。
然后是测试数据。假设验证数据(本质上是统计样本)与它在统计术语中描述的总体不完全匹配。也就是说,样本不能完全代表它,因此样本的平均值和方差(希望)与实际总体平均值和方差略有不同。因此,每次使用验证数据优化模型时,都会在模型中引入一点偏差。虽然它在预测能力方面可能仍然非常有效,但它可能会失去其能力概括。在这种情况下,它将不再适用于从未见过的数据,例如来自不同样本的数据。测试数据用于在整个训练过程完成后(即仅在最后一个周期之后)测试模型,并允许我们讲述一些关于我们的机器学习模型的泛化能力的事情。
训练数据在所谓的正向传递中被输入到机器学习模型中。这个名字的由来非常简单:数据只是被输入到网络中,这意味着它以正向的方式通过网络。最终结果是一组预测,每个样本一个预测。这意味着当训练集由 1000 个特征向量(或具有特征的行)组成,并伴有 1000 个目标时,在正向传递后将有 1000 个预测。
损失(Loss)
想知道模型相对于最初设定的目标的表现如何。表现良好的模型对于生产使用很有吸引力,而表现不佳的模型必须经过优化才能实际使用。此时,损失的概念便进入了方程。
一般而言,损失使我们能够比较一些实际目标和预测目标。如果预测偏离实际目标,则对每个预测施加“成本”(或使用不同的术语“损失”)。
从概念上来说,计算损失相对容易:就机器学习预测的一些成本达成一致,将 1000 个目标与 1000 个预测进行比较,计算 1000 个成本,然后将所有内容加在一起,得出整体损失。
训练机器学习模型时我们的目标是什么?尽量减小损失。原因很简单:损失越低,目标集和预测集就越相似。它们越相似,机器学习模型的表现就越好。
如上图所示,机器学习过程中的箭头指向机器学习模型。它们的目标是:略微优化模型的内部结构,使其在下一个周期(或迭代,或称为时代)中表现更好。
反向传播(Backwards pass)
计算出损失后,必须改进模型。这是通过将误差反向传播到模型结构(例如模型的权重)来实现的。这关闭了向前传播数据、生成预测和改进数据之间的学习周期——通过调整权重,模型可能会得到改进(有时改进很多,有时改进不多),因此学习就会发生。
根据所用模型类型,有许多方法可以优化模型,即反向传播误差。在神经网络中,通常使用基于梯度下降(gradient descent)的方法和反向传播的组合:梯度下降等优化器用于计算梯度或优化方向,反向传播用于实际误差传播。
在其他模型类型中,例如支持向量机,严格来说,实际上并没有向后传播误差。但是,使用二次优化(quadratic optimization)等方法来找到数学最优值,考虑到数据的线性可分性(无论是在常规空间还是核空间中),这个最优值必须存在。但是,将其可视化为“通过计算一些误差来调整权重”有助于理解。
损失函数(Loss functions)
将介绍各种各样的损失函数:其中一些用于回归,另一些用于分类。
回归(regression)的损失函数
监督学习问题主要有两种类型:分类和回归。第一种情况下,目标是将样本归类到正确的类别中,例如归类到“糖尿病”或“非糖尿病”类别中。然而,在后一种情况下,不是在分类,而是在估计某个实数。试图做的是从一些输入数据中回归一个数学函数,因此这被称为回归。对于回归问题,有许多可用的损失函数。
平均绝对误差(L1 损失)(Mean Absolute Error (L1 loss))
平均绝对误差(MAE)就是其中之一。它看起来像这样:
在公式中看到的那个奇怪的 E 形符号就是所谓的 Sigma 符号,它总结了其背后的内容:|Ei|,在例子中,Ei是误差(预测值和实际值之间的差异),并且 | 符号表示取绝对值,或者将 -3 转换为 3 且 3 仍为 3。
在这种情况下,求和意味着将n用于训练模型的所有样本的所有误差相加。因此,这样做之后,最终会得到一个非常大的数字。将这个数字除以n,即使用的样本数,以找到平均值,即平均绝对误差:平均绝对误差或 MAE。
在多种回归场景中,MAE 的使用非常有可能(Rich, n.d.)。但是,如果平均误差非常小,则最好使用接下来将介绍的均方误差。
更重要的是,这一点很重要:当在使用梯度下降的优化中使用 MAE 时,会面临梯度持续增大的事实(Grover,2019)。由于当损失较低时也会发生这种情况(因此,只需要移动一点点),这对学习不利——很容易连续超过最小值,找到次优模型。如果遇到这个问题,请考虑Huber 损失(更多内容见下文)。
均方误差(Mean Squared Error)
回归中经常使用的另一个损失函数是均方误差(MSE),公式(Binieli,2018):
将上述公式分为三个部分,这样就可以理解每个元素以及它们如何协同产生 MSE。
MSE 的主要部分是中间部分,称为 Sigma 符号或求和符号。它的作用非常简单:从i到n计数,每次计数时执行其后面写的内容。在本例中,这是第三部分—(Yi - Y'i)的平方。
在例子中,i从 1 开始,n尚未定义。相反,n是训练集中的样本数量,因此也是已做出的预测数量。在上面描述的场景中,n将是 1000。
然后是第三部分。它实际上是之前直观学到的数学符号:它是样本的实际目标(Yi)与预测目标(Y'i)之间的差值,其中后者从前者中减去。
有一个细微的差别:此计算的最终结果是平方。此属性在优化过程中带来了一些数学上的好处(Rich, n.d.)。特别是,MSE 是连续可微的,而 MAE 不是(在 x = 0 处)。这意味着优化 MSE 比优化 MAE 更容易。
此外,大误差带来的成本比小误差大得多(因为差值是平方的,大误差产生的平方比小误差大得多)。这既是好事也是坏事(Rich, n.d.)。当误差很小时,这是一个很好的特性,因为优化会随之推进(Quora,n.d.)。但是,使用 MSE 而不是 MAE 等会使你的 ML 模型容易受到异常值的影响,这会严重干扰训练(通过引入大误差)。
尽管结论可能不太令人满意,但在 MAE 和 MSE 之间进行选择通常在很大程度上取决于使用的数据集,因此需要在开始训练过程之前进行一些先验检查。
最后,当得到平方误差的总和时,将其除以 n—得到均方误差。
平均绝对百分比误差(Mean Absolute Percentage Error)
平均绝对百分比误差 (MAPE) 实际上与 MAE 类似,尽管公式看起来有些不同:
使用 MAPE 时,不计算绝对误差,而是计算相对于实际值的平均误差百分比。也就是说,假设预测是 12,而实际目标是 10,则此预测的 MAPE 为 | (10–12 ) / 10 | = 0.2。
与 MAE 类似,将所有样本的误差相加,但随后面临不同的计算:100%/n。这看起来很难,但可以再次将此计算分解为更容易理解的部分。更具体地说,可以将其写成 100% 和 1/n 的乘积。将后者与总和相乘时,会发现结果与将其除以相同n,就像对 MAE 所做的那样。
现在只剩下将整体乘以 100%。为什么要这样做?很简单:因为计算出的误差是一个比率,而不是百分比。就像上面的例子一样,误差是 0.2,不想找到比率,而是百分比。0.2 x 100% 是……不出所料……20%!因此,将平均比率误差乘以百分比以找到 MAPE!
如果也可以使用 MAE,为什么要使用 MAPE?
首先,这是一个非常直观的值。与绝对误差相反,当可以用百分比来表示误差时,可以了解模型的表现有多好或有多差。100 的误差可能看起来很大,但如果实际目标是 1,000,000,而估计值为 1,000,100。
其次,它能够比较不同数据集上回归模型的性能(Watson,2019)。假设目标是在 NASDAQ ETF 和荷兰 AEX ETF 上训练回归模型。由于它们的绝对值相差很大,因此使用 MAE 对比较模型的性能没有太大帮助。另一方面,MAPE 以百分比的形式显示误差——无论将其应用于 NASDAQ 还是 AEX,百分比就是百分比。这样,就可以比较统计上不同的数据集中的模型性能。
均方根误差(L2 损失)(Root Mean Squared Error (L2 loss))
还记得 MSE 吗?
还有一种称为 RMSE 的指标,即均方根误差或均方根偏差 (RMSD)。其含义如下:
它只是 MSE,然后是它的平方根值。
这有什么帮助?MSE 的误差是平方的。
RMSE 或 RMSD 误差是平方的平方根—因此回到了原始目标的尺度 (Dragos, 2018)。这让您对目标方面的误差有了更好的直觉。
Logcosh
“Log-cosh 是预测误差的双曲余弦的对数。”(Grover,2019)
数学公式:
现在来介绍一些直观的解释。TensorFlow 文档对Logcosh 损失有如下描述:
log(cosh(x))对于较小值x,近似等于(x ** 2) / 2;对于较大值x,近似等于abs(x) - log(2)。这意味着 'logcosh' 的工作原理与均方误差非常相似,但不会受到偶尔出现的严重错误预测的强烈影响。
它似乎比 MSE 或 L2 损失有所改进。回想一下,如果数据集包含相当大的错误,MSE 比 MAE(L1 损失)有所改进,因为它可以更好地捕获这些错误。然而,这也意味着它比 MAE 对错误更敏感。Logcosh 有助于解决这个问题:
对于相对较小的误差(即使误差相对较小但较大,这就是为什么 MSE 比 MAE 更适合解决 ML 问题的原因),它的输出大约等于 x² / 2 — 这与 MSE 的 x² 输出非常相等。
对于较大的误差,即异常值,MSE 会产生极大的误差((10⁶)² = 10¹²),Logcosh 趋近于 |x| - log(2)。它类似于(也不同于)MAE,但随后被log稍微修正。
因此,如果既有需要检测的较大错误,又有可能无法从数据集中删除的异常值,请考虑使用 Logcosh!它在许多框架中都可用,例如 TensorFlow,但也可以在Keras中使用。
Huber los
继续讨论 Huber 损失,已经在有关 MAE 的部分中暗示过它:
在解释公式时,会看到两个部分:
1/2 x (tp)²,当 |tp| ≤ δ 时。这听起来很复杂,但可以轻松地将其分解成几个部分。
|tp| 是绝对误差:目标 t 和预测 p 之间的差异。
将其平方并除以二。
然而,只有当绝对误差小于或等于某个 δ(也称为 delta,可以配置)时,才会这样做!接下来将看到为什么这很好。
当绝对误差大于δ时,按如下方式计算误差:δ x |tp| - (δ²/2)。
再分解一下。将 delta 与绝对误差相乘,然后去掉 delta 平方的一半。
这些数学的效果如何?
看一下上面的可视化效果。
对于相对较小的增量(在例子中,δ = 0.25,会看到损失函数变得相对平坦。即使预测越来越大,损失也需要相当长的时间才会增加。
对于较大的 delta,函数的斜率会增加。delta 越大,斜率的增加越慢:最终,对于非常大的 δ,损失的斜率趋于收敛到某个最大值。
如果仔细观察,会注意到以下几点:
当 δ 较小时,损失对较大的误差和异常值变得相对不敏感。如果有这些,这可能是件好事,但如果平均而言误差较小,那就不好了。
当 δ 较大时,损失对较大的误差和异常值会变得越来越敏感。如果误差较小,这可能是好事,但当数据集包含异常值时,就会遇到麻烦。
难道之前没见过吗?
是的:在关于 MAE(对较大误差不敏感)和 MSE(修复了这个问题,但面临对异常值的敏感性)的讨论中。
Grover(2019)对此进行了很好的描述:
当 𝛿 ~ 0 时,Huber 损失接近 MAE,当 𝛿 ~ ∞ (大数)时,Huber 损失接近 MSE。
这就是 δ 的作用!现在,可以控制在损失函数中引入的 MAE 与 MSE 的“程度”。当因异常值而面临较大误差时,可以尝试使用较低的 δ;如果误差太小而无法被 Huber 损失发现,可以增加 delta。
在讨论 MAE 时也提到过:当通过梯度下降优化模型时,即使误差很小,它也会产生很大的梯度(Grover,2019)。这对模型性能不利,因为可能会超出模型的数学最优值。使用 MSE 时不会遇到这个问题,因为它往往会向实际最小值下降(Grover,2019)。如果从 MAE 切换到 Huber 损失,可能会发现这是一个额外的好处。
原因如下:当接近数学最优值时,Huber 损失与 MSE 一样也会减小(Grover,2019)。这意味着可以结合两全其美的优势:MAE 对较大误差的不敏感性与 MSE 的敏感性及其对梯度下降的适用性。
那为什么这不是完美的损失函数呢?
因为 δ 的好处也成为了瓶颈(Grover,2019)。由于必须手动配置它们(或者可能使用一些自动化工具),将不得不花费时间和资源来为数据集找到最优化的 δ。这是一个迭代问题,在极端情况下,它可能会变得不切实际,在最坏的情况下代价高昂。然而,在大多数情况下,最好只是进行实验!
在上文中介绍了损失、损失是什么以及一些用于回归的基本损失函数。接下去将介绍一些在分类任务中经常使用的损失函数。
分类(classification)损失函数
损失函数也适用于分类器。
假设将未成熟的西红柿与成熟的西红柿区分开来。有人可能会说,这是一项重要的工作,因为我们不想向顾客出售他们无法加工成晚餐的西红柿。这项工作非常适合说明人类分类器会做什么。
人类的眼睛可以发现未成熟或有其他缺陷(如腐烂)的西红柿。人类会根据这些西红柿的特点来判断它们,例如颜色、气味和形状:
- 如果是绿色的,很可能还没熟(或者卖不出去);
- 如果有异味,很可能卖不出去;
- 如果是白色或者上面有真菌,也可能卖不出去。
如果上述情况均未发生,那么西红柿很可能可以出售。现在有两个类别:可出售的西红柿和不可出售的西红柿。人工分类器决定一个物体(西红柿)属于哪个类别。同样的原理也出现在机器学习和深度学习中。
用机器学习模型代替人类。然后使用机器学习进行分类,或者决定某个“模型输入”属于“哪个类别”。
Hinge loss
Hinge损失定义如下(维基百科,2011):
它只是取 0 或计算1- txy中的最大值,其中t是机器学习输出值(介于 -1 和 +1 之间),y是真实目标(-1 或 +1)。
当目标等于预测时,计算txy始终为 1:1 x 1 = -1 x -1 = 1)。本质上,因为 1 - txy = 1-1 = 1,所以函数max取最大值max(0, 0),当然是 0。
即:当实际目标满足预测时,loss为零,不存在负loss,当目标!=预测时,loss值会增加。
对于t = 1或 1 是你的目标,hinge损失如下所示:
现在考虑可能发生的三种情况,假设目标t = 1 (Kompella,2017;Wikipedia,2011):
预测是正确的,当 y ≥ 1.0 时发生。
这个预测非常不正确,当 y < 0.0 时就会发生这种情况(因为符号互换,在例子中是从正数变为负数)。
预测并不正确,但正在接近目标(0.0 ≤ y < 1.0)。
在第一种情况下,例如当 y = 1.2 时, 1 - txy的输出将为 1 - ( 1 x 1.2 ) = 1-1.2 = -0.2。那么损失将为 max(0, -0.2) = 0。因此,对于所有正确的预测 —— 即使它们过于正确,损失也为零。在过于正确的情况下,分类器只是非常确定预测是正确的(Peltarion,n.d.)。
在第二种情况下,例如当 y = -0.5 时,损失方程的输出将为 1 - (1 \ x -0.5) = 1 - (-0.5) = 1.5,因此损失将为 max(0, 1.5) = 1.5。因此,非常错误的预测会受到hinge损失函数的严重惩罚。
在第三种情况下,例如当 y = 0.9 时,损失输出函数将为 1 - (1 x 0.9) = 1- 0.9 = 0.1。损失将为 max(0, 0.1) = 0.1。这也由小但不为零的损失表明。
这本质上勾勒出了一个试图最大化的边际:当预测正确甚至过于正确时,这并不重要,但当预测不正确时,纠正过程一直持续到预测完全正确(或当人类告诉改进停止时)。因此,找到了最优的决策边界,并因此执行了最大边际操作。
因此,hinge损失是支持向量机(Kompella, 2017)中最常用的损失函数之一。此外,hinge损失本身不能与梯度下降(如用于训练(深度)神经网络的优化器)一起使用。这是因为它不是连续可微的,更准确地说,在无损失/最小损失之间的“边界”上。幸运的是,hinge损失函数的子梯度可以优化,因此它(尽管形式不同)仍然可以在当今的深度学习模型中使用(维基百科,2011)。例如,hinge损失可用作Keras 中的损失函数。
Squared hinge
Squared hinge损失类似于上面显示的hinge公式,但是 max() 函数输出是平方。
这有助于实现两件事:
首先,它使损失值对异常值更加敏感,就像在 MSE 与 MAE 中看到的那样。大误差会比小误差更显著地增加损失。请注意,同样,这也可能意味着需要先检查数据集是否存在此类异常值。
其次,Squared hinge损失是可微的,而hinge损失则不可微(Tay,nd)。hinge损失的定义方式使其在图表的“边界”点处不可微——另请参阅这个完美的答案来说明这一点。另一方面,Squared hinge损失是可微的,这仅仅是因为它的平方和它在微分过程中引入的数学优势。这让我们更容易在基于梯度的优化中使用类似hinge的损失——只需取Squared hinge即可。
分类(Categorical)/多类hinge
普通hinge损失和quared hinge损失仅适用于实际目标值为 +1 或 -1 的二元分类问题。虽然当遇到此类问题时(例如之前研究过的糖尿病是/否问题),这完全没问题,但还有许多其他问题无法以二元方式解决。
(请注意,创建多类分类器(尤其是使用 SVM)的一种方法是创建多个二元分类器,将数据提供给每个分类器并计算类别,最终将最多的选择类作为输出 —— 不言而喻,这不是很有效。)
然而,在神经网络以及基于梯度的优化问题中,对此不感兴趣。这意味着必须训练许多网络,这会严重影响我们的 ML 训练问题的时间性能。相反,可以使用研究人员 Weston 和 Watkins (Wikipedia,2011) 引入的多类hinge:
这意味着:
对于所有不等于 t 的 y(输出)值,计算损失。最后,将它们相加以求得多类hinge损失。
请注意,这并不意味着要对y 的所有可能值(即除 t 之外的所有实数)求和,而是要计算ML 模型在前向传播过程中生成的所有输出的总和。即所有预测。只有当 y ≠ t 时,才需要计算损失。从效率的角度来看,这是显而易见的:当 y = t 时,损失始终为零,因此无需计算 max() 操作即可找到零。
Keras 将多类hinge损失实现为分类hinge损失,需要首先通过将目标转换为分类格式(one-hot编码格式)to_categorical。
二元交叉熵(Binary crossentropy)
当今神经网络中经常使用的损失函数是二元交叉熵。正如所猜测的,它是二元分类问题的损失函数,即存在两个类别的情况。它主要可用于神经网络的输出介于 0 和 1 之间的情况,例如通过 Sigmoid 层。
它的公式如下:
更直观的方式解释
公式中的 t 是目标(0 或 1),p 是预测(0 和 1 之间的实数,例如 0.12326)。
当将两者输入公式时,将计算与目标和预测相关的损失。在上面的可视化中,目标是 1,很明显损失是 0。但是,当向左移动时,损失趋于增加。更重要的是,它增加得越来越快。因此,它不仅倾向于惩罚错误的预测,而且也倾向于惩罚非常自信的错误预测(即,如果模型非常确信它是 0,而它是 1,那么它受到的惩罚要比它认为它在两者之间时要严厉得多,例如 0.5)。后一种特性使二元交叉熵成为分类问题中有价值的损失函数。
当目标为 0 时,可以看到损失被镜像了——这正是想要的:
分类交叉熵(Categorical crossentropy)
现在,如果没有二元分类问题,而是多类分类问题,该怎么办?
因此:输出可以属于 > 2 个类之一。
利用 Keras 和 MNIST 数据集创建的 CNN 就是这个问题的一个很好的例子。使用了不同的损失函数——分类交叉熵。它仍然是交叉熵,但后来适应了多类问题。
这是计算分类交叉熵的公式。简单来说,对系统中所有的类别求和,计算观察目标和观察预测,并用观察预测的自然对数计算观察目标。
答案在于交叉熵是分类的,因此使用分类数据并采用one-hot编码。
假设有一个数据集,它显示了五年后患糖尿病的几率,就像之前使用的皮马印第安人数据集一样。然而,这次添加了另一个类别,即“可能患有糖尿病”,根据目前的测量结果,为五年后的病情提供了三个类别:
0:无糖尿病
1:可能患有糖尿病
2:糖尿病
该数据集如下所示:
但是,分类交叉熵不能简单地使用整数作为目标,因为它的公式不支持这一点。相反,必须应用one-hot编码,它将整数目标转换为分类向量,这些向量只是显示所有类别以及它是否属于某个类的向量:
0:[1, 0, 0]
1:[0,1,0]
2:[0,0,1]
这就是to_categorical在 Keras 中一直在做的事情。
数据集如下所示:
现在,可以用观察来解释。
再次看一下这个公式,并回想一下,迭代所有可能的输出类 —— 对于每个做出的预测迭代一次,并有一些真实的目标:
现在假设训练的模型输出特征集 { ... } 或非常相似的特征集,其目标为 [0, 1, 0],概率分布为 [0.25, 0.50, 0.25]——这就是这些模型所做的,它们不选择任何类,而是计算它是分类向量中特定类的概率。
计算损失,对于 c = 1,目标值是多少?它是 0:在t = [0, 1, 0] 中,第 0 类的目标值为 0。
预测结果是多少?按照同样的逻辑,预测结果为 0.25。
将这两个观测值称为相对于总体预测的观测值。通过查看所有观测值并将它们合并在一起,可以找到整个预测的损失值。
将目标值与对数相乘。但是等一下!将对数与 0 相乘 —— 因此该目标的损失值为 0。
除了一个目标之外,所有目标都会发生这种情况,这并不奇怪——其中目标值为 1:在上面的预测中,那将是第二个目标。
请注意,当求和完成后,将其乘以 -1 以找到真正的分类交叉熵损失。
因此,损失是由样本的实际目标观察而不是所有非目标驱动的。然而,公式的结构允许利用交叉熵进行多类机器学习训练。
稀疏分类交叉熵(Sparse categorical crossentropy)
但是,如果不想将整数目标转换为分类格式怎么办?可以改用稀疏分类交叉熵(Lin,2019)。
它的表现方式与常规分类交叉熵损失非常相似,但允许使用整数目标!
Kullback-Leibler 散度
有时,机器学习问题涉及两个概率分布之间的比较。一个示例比较是下面的情况,其中的问题是均匀分布与二项式(10, 0.2)分布有多大差异。
当想要比较两个概率分布时,可以使用 Kullback-Leibler 散度,又名 KL 散度(Wikipedia,2004):
KL 散度是熵(entropy)的一种变换,熵是信息论领域的一种常用度量(Wikipedia, 2004; Wikipedia, 2001; Count Bayesie, 2017)。直观地说,熵告诉一些关于“信息量”的信息,而 KL 散度告诉一些关于“分布改变时数量的变化”的信息。
机器学习问题中的目标是确保变化≈0。
KL 散度在实践中使用吗?是的!生成机器学习模型的工作原理是从编码的潜在空间中抽取样本,这实际上表示了潜在的概率分布。在其他情况下,可能希望使用在输出层使用 Softmax 激活的神经网络执行多类分类,从而有效地生成跨类别的概率分布。在这些情况下,可以在训练期间使用 KL 散度损失。它将训练数据所表示的概率分布与前向传播期间生成的概率分布进行比较,并计算两个概率分布之间的散度(差异,尽管当交换分布时,由于 KL 散度的不对称,该值会发生变化 —— 因此它不是完全的差异)。这是损失值。因此,最小化损失值本质上会将神经网络引向训练集中所表示的概率分布,这正是想要的。
当今的深度神经网络可以处理高度复杂的数据集。例如,物体检测器已经能够实时预测各种物体的位置;时间序列模型可以同时处理许多变量,并且可以想象许多其他应用。
问题是:这些网络如何处理如此复杂的问题?更具体地说,它们如何做到以前的机器学习模型无法做到的事情?
这个问题有两个答案。主要答案在于神经网络的深度——更大的深度允许网络处理更复杂的数据。然而,答案的一部分在于各种激活函数(activation functions)的应用——特别是当今最常用的非线性函数:ReLU、Sigmoid、Tanh 和 Softmax。
什么是激活函数(activation functions)?
一个基本的神经网络的结构,用深度学习术语来说,它由以下部分组成:密集连接层:
基本神经网络
在这个网络中,每个神经元都由一个权重向量和一个偏差值组成。当输入一个新向量时,它会计算权重和输入向量之间的点积,加上偏差值并输出标量值。
…直到它不再存在。
问题可以很简单地表述:点积和标量加法都是线性运算。
因此,当将此值作为神经元输出并对每个神经元执行此操作时,将拥有一个线性行为的系统。
大多数数据都是高度非线性的。由于线性神经网络在这些情况下无法生成决策边界,因此在生成预测模型时应用它们毫无意义。
因此整个系统必定是非线性的。
输入激活函数。
该函数位于每个神经元的正后方,以线性神经元的输出作为输入,并基于此生成非线性输出,通常是确定性的(即,当输入两次相同的值时,将得到相同的结果)。
这样,每个神经元实际上都会产生一个线性但非线性的输出,系统的行为呈非线性,因此能够处理非线性数据。
激活输出随输入增加
神经网络的灵感来自人类大脑。尽管非常简单,但它们的工作方式与人类神经元有些相似:人类神经元也是大型神经网络的一部分,中间有突触(或通路)。当接收到神经输入时,人类神经元会激活并向其他神经元传递信号。
整个系统产生了我们所知的人类智力。
如果希望在神经网络激活函数中模仿这种行为,还需要模仿人类神经元激活。显而易见,在人类神经网络中,当刺激或神经元输入增加时,输出往往会增加。因此,在人工神经网络中也经常出现这种情况。
因此,我们正在寻找采用线性输入、产生非线性输出并随时间增加或保持稳定的数学公式。
激活函数有很多种,如今,三种激活函数使用最为广泛:Sigmoid 函数、Tangens 双曲函数或 tanh 和 Rectified Linear Unit 或 ReLU。
Sigmoid
(通用的) Sigmoid 型函数,也称为逻辑曲线:
从数学上来说,它可以表示如下:
正如在图中看到的,函数随着时间的推移缓慢增加,但最大的增幅可以在 x = 0 附近找到。函数的范围是 (0, 1),因此对于 x 的高值,函数接近 1,但永远不会等于它。
Sigmoid 函数可以做很多事情。首先,因为知道在 Keras 中无法创建真正的 Rosenblatt 感知器,所以这些古老神经元中使用的阶跃函数不可微分,因此无法应用梯度下降进行优化。其次,当你自己实现 Rosenblatt 感知器时,会注意到,在二元分类问题中,决策边界是针对每个神经元进行优化的,并且会找到一个可能的边界(如果存在的话)。使用 Sigmoid 函数会更容易,因为它更平滑(Majidi,n.d.)。
此外,也许最主要的是,使用 Sigmoid 函数是因为它的输出范围在 (0, 1) 内。在估计概率时,这是完美的选择,因为概率的范围非常相似,都是 [0, 1] (Sharma, 2019)。特别是在二元分类问题中,当有效地估计输出属于某个类的概率时,Sigmoid 函数允许给出一个非常加权的估计。A 类和 B 类之间的输出 0.623 表示“B 类略多”。使用阶跃函数,输出很可能是 1,细微差别就消失了。
双曲正切(Tangens hyperbolicus): Tanh
另一个广泛使用的激活函数是双曲正切函数或双曲正切/tanh 函数:
从代数上来说,这可以表示如下:
它的工作原理与 Sigmoid 函数类似,但有一些区别。
首先,输出的变化在接近 x = 0 时加速,这与 Sigmoid 函数类似。
它还与 Sigmoid 具有相同的渐近性质:尽管对于非常大的 x 值,函数趋近于 1,但实际上永远不会等于 1。
然而,在域的下侧,看到范围的差异:它不是接近 0 作为最小值,而是接近 -1。
Sigmoid 和 Tanh 之间的主要区别
显然,激活函数的范围不同:(0,1)与(-1,1)。
虽然这种差异看起来很小,但它可能会对模型性能产生很大的影响;具体来说,就是模型收敛到最优解决方案的速度有多快(LeCun 等,1998)。
这与它们关于原点对称有关。因此,它们产生的输出接近于零。接近于零的输出是最好的:在优化过程中,它们产生的权重波动最小,因此让模型收敛得更快。当模型非常大时,这确实很有帮助。
可以看出,tanh 函数关于原点对称,而 Sigmoid 函数不是。因此应该始终选择 tanh 吗?
不,它带来了一系列问题,或者更积极的一点是,带来了一系列挑战。
Sigmoid 和 Tanh 的挑战
LeCun 等人的论文发表于 1998 年,深度学习领域已经取得了长足的进步……确定了推动深度学习领域发展所必须解决的挑战。
首先,必须讨论模型稀疏性(DaemonMaker,n.d.)。优化过程中模型越不复杂,收敛速度就越快,并且越有可能及时找到数学最优解。
复杂性可以视为模型中不重要的神经元的数量。神经元数量越少,模型就越好(或者说越稀疏)。
Sigmoid 和 Tanh 本质上产生非稀疏模型,因为它们的神经元几乎总是产生输出值:当范围分别为 (0, 1) 和 (-1, 1) 时,输出不能为零,或者以非常低的概率为零。
因此,如果某些神经元在权重方面不太重要,就无法将其“移除”,并且模型不是稀疏的。
这些激活函数的输出范围的另一个可能问题是所谓的消失梯度(vanishing gradients)问题( DaemonMaker,n.d.)。在优化过程中,数据通过模型输入,然后将结果与实际目标值进行比较。这会产生所谓的损失。由于损失可以被视为(可优化的)数学函数,可以计算朝向零导数的梯度,即数学最优值。
然而,神经网络由多层神经元组成。本质上必须对下游的每一层重复这个过程,然后将它们串联起来。这就是反向传播。随后,可以使用梯度下降或类似的优化器来优化模型。
当神经元输出非常小(即 -1 < 输出 < 1)时,优化过程中产生的链将向上游层越来越小。这将导致它们学习非常缓慢,并且令人怀疑它们是否会收敛到最优值。这就是梯度消失问题。
整流线性单元(Rectified Linear Unit):ReLU
为了改进这些观察结果,引入了另一种激活函数。这种激活函数称为整流线性单元 (ReLU),是当今大多数深度学习项目事实上的首选。它对上述问题的敏感度要低得多,因此可以改善训练过程。
它看起来如下:
并且可以用代数形式表示如下:
或者,用简单的英语来说,它对所有小于零的输入产生零输出;对所有其他输入产生 x。因此,对于所有 <= 0 的输入,它都会产生零输出。
稀疏性(Sparsity)
这对稀疏性大有裨益:现在几乎一半的情况下,神经元不再激发。这样,如果神经元对模型的预测能力的贡献不再那么重要,就可以让它们保持沉默。
更少的消失梯度
它还减少了梯度消失的影响,因为梯度始终是一个常数:f(x) = 0 的导数为 0,而 f(x) = x 的导数为 1。因此,模型学习得更快、更均匀。
计算要求
此外,ReLU 所需的计算资源确实比 Sigmoid 和 Tanh 函数少得多(Jaideep,n.d.)。实现 ReLU 所需的函数本质上是 max 函数:max(0, x),当 x < 0 时生成 0,当 x >= 0 时生成 x。
现在将其与上面介绍的 Sigmoid 和 tanh 函数的公式进行比较:它们包含指数。计算 max 函数的输出比计算指数的输出要简单得多,计算成本也更低。对于一次计算来说,这并不重要,但请注意,在深度学习中会进行许多这样的计算。因此,ReLU 减少了对计算资源的需求。
ReLU 也面临挑战
但这并不意味着 ReLU 本身没有面临某些挑战:
首先,由于其在域的上侧不受限制,它往往会产生非常大的值 (Jaideep, n.d.)。从理论上讲,无限的输入会产生无限的输出。
其次,将面临ReLU 死亡问题(Jaideep,n.d.)。如果神经元的权重向零输出移动,则它们最终可能不再能够从中恢复。然后它们将不断输出零。当网络初始化不佳或数据标准化不佳时尤其如此,因为第一轮优化将产生较大的权重波动。当太多神经元输出零时,最终会得到一个死神经网络——ReLU 死亡问题。
第三, 小值,即使是非正值,也可能有价值;它们可以帮助捕捉数据集背后的模式。使用 ReLU 无法做到这一点,因为所有小于零的输出都是零。
第四,从 f(x) = 0 到 f(x) = x 的过渡点并不平滑。这将影响优化过程中的损失情况,而损失情况也不会平滑。这可能会(虽然影响很大,但略有)妨碍模型优化,并略微减慢收敛速度。
仅举几个问题。
幸运的是,新的激活函数已被设计出来以克服这些问题,特别是在非常大和/或非常深的网络中。此类函数的一个典型示例是 Swish;另一个是 Leaky ReLU。
Softmax 函数
这里简要介绍的最后一个激活函数是著名的Softmax 激活函数。
Softmax 的可视化形式如下:
Softmax 函数是一种非常棒的工具,主要用于机器学习和深度学习领域,将数字向量转换为概率向量。
这可以用代数形式表示如下:
通常,在神经网络的最后一层使用此函数,该函数计算事件在“n”个不同事件中的概率分布。该函数的主要优点是它能够处理多个类。
当比较 sigmoid 和 softmax 激活函数时,它们会产生不同的结果。
Sigmoid 输入值:-0.5、1.2、-0.1、2.4
Sigmoid 输出值:0.37、0.77、0.48、0.91
然而
SoftMax 输入值:-0.5、1.2、-0.1、2.4
SoftMax输出值:0.04、0.21、0.05、0.70
Sigmoid 产生的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。在这种情况下,如果我们想增加一个类的可能性,另一个类就必须减少相同的量。
参考
Chollet, F. (2017). Deep Learning with Python. New York, NY: Manning Publications.
Keras. (n.d.). Losses. Retrieved from https://keras.io/losses/
Binieli, M. (2018, October 8). Machine learning: an introduction to mean squared error and regression lines. Retrieved from https://www.freecodecamp.org/news/machine-learning-mean-squared-error-regression-line-c7dde9a26b93/
Rich. (n.d.). Why square the difference instead of taking the absolute value in standard deviation? Retrieved from https://stats.stackexchange.com/a/121
Quora. (n.d.). What is the difference between squared error and absolute error? Retrieved from https://www.quora.com/What-is-the-difference-between-squared-error-and-absolute-error
Watson, N. (2019, June 14). Using Mean Absolute Error to Forecast Accuracy. Retrieved from https://canworksmart.com/using-mean-absolute-error-forecast-accuracy/
Drakos, G. (2018, December 5). How to select the Right Evaluation Metric for Machine Learning Models: Part 1 Regression Metrics. Retrieved from https://towardsdatascience.com/how-to-select-the-right-evaluation-metric-for-machine-learning-models-part-1-regrression-metrics-3606e25beae0
Wikipedia. (2011, September 16). Hinge loss. Retrieved from https://en.wikipedia.org/wiki/Hinge_loss
Kompella, R. (2017, October 19). Support vector machines ( intuitive understanding ) ? Part#1. Retrieved from https://towardsdatascience.com/support-vector-machines-intuitive-understanding-part-1-3fb049df4ba1
Peltarion. (n.d.). Squared hinge. Retrieved from https://peltarion.com/knowledge-center/documentation/modeling-view/build-an-ai-model/loss-functions/squared-hinge
Tay, J. (n.d.). Why is squared hinge loss differentiable? Retrieved from https://www.quora.com/Why-is-squared-hinge-loss-differentiable
Rakhlin, A. (n.d.). Online Methods in Machine Learning. Retrieved from http://www.mit.edu/~rakhlin/6.883/lectures/lecture05.pdf
Grover, P. (2019, September 25). 5 Regression Loss Functions All Machine Learners Should Know. Retrieved from https://heartbeat.fritz.ai/5-regression-loss-functions-all-machine-learners-should-know-4fb140e9d4b0
TensorFlow. (n.d.). tf.keras.losses.logcosh. Retrieved from https://www.tensorflow.org/api_docs/python/tf/keras/losses/logcosh
ML Cheatsheet documentation. (n.d.). Loss Functions. Retrieved from https://ml-cheatsheet.readthedocs.io/en/latest/loss_functions.html
Peltarion. (n.d.). Categorical crossentropy. Retrieved from https://peltarion.com/knowledge-center/documentation/modeling-view/build-an-ai-model/loss-functions/categorical-crossentropy
Lin, J. (2019, September 17). categorical_crossentropy VS. sparse_categorical_crossentropy. Retrieved from https://jovianlin.io/cat-crossentropy-vs-sparse-cat-crossentropy/
Wikipedia. (2004, February 13). Kullback–Leibler divergence. Retrieved from https://en.wikipedia.org/wiki/Kullback%E2%80%93Leibler_divergence
Wikipedia. (2001, July 9). Entropy (information theory). Retrieved from https://en.wikipedia.org/wiki/Entropy_(information_theory)
Count Bayesie. (2017, May 10). Kullback-Leibler Divergence Explained. Retrieved from https://www.countbayesie.com/blog/2017/5/9/kullback-leibler-divergence-explained
Panchal, S. (n.d.). What are the benefits of using a sigmoid function? Retrieved from https://stackoverflow.com/a/56334780
Majidi, A. (n.d.). What are the benefits of using a sigmoid function? Retrieved from https://stackoverflow.com/a/56337905
Sharma, S. (2019, February 14). Activation Functions in Neural Networks. Retrieved from https://towardsdatascience.com/activation-functions-neural-networks-1cbd9f8d91d6
LeCun, Y., Bottou, L., Orr, G. B., & Müller, K. -. (1998). Efficient BackProp. Lecture Notes in Computer Science, 9–50. doi:10.1007/3–540–49430–8_2
DaemonMaker. (n.d.). What are the advantages of ReLU over sigmoid function in deep neural networks? Retrieved from https://stats.stackexchange.com/a/126362
Jaideep. (n.d.). What are the advantages of ReLU over sigmoid function in deep neural networks? Retrieved from https://stats.stackexchange.com/questions/126238/what-are-the-advantages-of-relu-over-sigmoid-function-in-deep-neural-networks