机器学习(ML)(六) — 探析

偏差和方差

开发机器学习系统的典型工作流程是什么?当训练机器学习模型时。在给定数据集,如果想用直线去拟合它,可能做得并不好。我们说这个算法有很高的偏差,或者它对这个数据集的拟合不足,也可以称为欠拟合。如果要拟合一个四阶多项式,那么它有很高的方差,或者称为过拟合。如果拟合一个二次多项式,那么它看起来相当不错。如下图所示:

但是如果有很多特征,就无法绘制图形来查看,不如诊断或查找算法在训练集和交叉验证集上是否具有高偏差高方差来的更有效。让我们看一个例子。如果要计算,从上图可看出这里的很高,因为真实值和预测值之间存在相当大的误差。算法在它以前没有见过的例子上也表现不佳,所以会很高。具有高偏差欠拟合)的算法的一个特征是它在训练集上的表现不是很好。当很高时,这是该算法具有高偏差的显性指标。如果要计算,它在训练集上实际上表现很好。与训练数据非常吻合。这里的值会很低。但是如果你在训练集中没有的样本上评估这个模型,你会发现交叉验证误差()很高。你的算法具有高方差的特征签名将会使高得多。换句话说,它在见过的数据上的表现比没见过的数据上要好得多。这是该算法具有高方差的显性指标。再次强调,这样做的目的是计算,看看是否很高,或者是否比高很多。即使无法绘制函数,也能了解算法是具有高偏差还是高方差。最后,如果查看的值非常低,因此在训练集上表现相当不错。如果查看交叉验证集的示例,您会发现也非常低。不太高表明它没有高偏差问题,而不比高很多,这表明它也没有高方差的问题。总结一下,当线性多项式的时,很高,也很高。当时,较低,但较高。当时,两者都相当低。

如下图所示,其中横轴是,是拟合数据的多项式的次数。在左边,将对应的一个小值,比如,这对应于拟合直线。在右边,将对应。会发现,当拟合次数越来越高的多项式时,这里我假设不使用正则化,训练误差会趋于下降,当有一个非常简单的线性函数时,它不能很好地拟合训练数据,当拟合二次函数或三阶多项式或四阶多项式时,拟合数据越来越好。随着多项式的次数增加,通常会下降。我们看到,当时,当多项式的次数非常低时,很高,因为它欠拟合,所以它在交叉验证集上表现不佳。如果改变多项式的次数,你实际上会得到一条像这样的曲线,先下降然后又上升。如果多项式的次数太低,它就会欠拟合,因此无法进行交叉验证集;如果次数太高,它就会过拟合,在交叉验证集上的表现也不会很好。只有当它处于中间位置时,它才是恰到好处的,这就是为什么我们例子中的二阶多项式最终会得到较低的交叉验证误差,既不会出现高偏差也不会出现高方差的原因。

总结一下,你如何诊断是否具有高偏差?如果你的学习算法有高偏差的数据,关键指标将是是否很高。这对应于曲线的最左边部分,也就是很高的地方。你如何诊断是否有高方差?而高方差的关键指标将是是否大于的两倍。当我们将一个非常高阶多项式拟合到这个小数据集时,就会发生这种情况。在某些情况下,同时存在高偏差高方差是可能的。对于线性回归,你不会看到这种情况发生,如果训练一个神经网络,有些场景下存在高偏差高方差。如果很高,那么在训练集上的表现就不是很好,交叉验证误差远大于训练集。高偏差意味着在训练集上的表现都不好,而高方差意味着在交叉验证集上的表现比训练集差得多。

让我们看看正则化,特别是正则化参数的选择如何去影响偏差方差,从而影响算法的整体性能。当您想要为算法选择一个正则化参数值时,将会起到很大的作用。在这个例子中,使用四阶多项式,使用正则化拟合这个模型。这里的值是正则化参数。假设。当非常大,那么算法就会倾向于将这些参数保持在非常小的水平,因此会得到,实际上所有这些参数都非常接近于零。模型最终会得到近似于一个常数值。这个模型显然具有很高的偏差,并且它与训练数据不相符,因为它在训练集上的表现不好,而且很大。让我们看看另一个极端。假设设置为一个非常小的值。事实上,在值很小的情况下,将设置为零。选择这种时,没有正则化,只是拟合一个没有正则化的四阶多项式,最终会得到之前看到的过度拟合数据的曲线。当拥有这样的一个模型时,很小,但大得多。这表明方差很大,并且过度拟合了数据。那么您如何选择一个好的值?这将类似于使用交叉验证选择多项式的次数的过程。具体来说,假设尝试使用来拟合模型。我们将使用来最小化成本函数,最终得到一些参数,然后可以计算交叉验证误差。假设尝。然后,最小化成本函数提供第二组参数,依此类推。在这个例子中,当,这样得到,依此类推。经过多次加倍后,,将提供参数 。通过尝试的大量可能值,使用这些不同的正则化参数拟合参数,然后评估交叉验证集上的性能。让我们看看训练误差交叉验证误差如何随参数的变化而变化。

在下图中,再次更改了轴。这里的轴标注的是正则化参数值,因此最终得到了这条非常弯曲的曲线。如果 很小,甚至为零,在这种情况下,有一个高方差模型会很小,而会很大,它在训练数据上表现很好。假设,最终会拟合出一个看起来像这样的模型。这具有很高的偏差,它与数据不相符,结果是会很高,也会很高。事实上,你会发现会像这样上升,因为在优化成本函数中,越大,正则化项的权重越大,因此对训练集上表现良好的关注就越少。越试图保持参数很小,它在最小化训练误差方面做得越差。这就是为什么随着的增加,训练误差会趋于增加。交叉验证误差会怎么样?如果太小或太大,那么它在交叉验证集上的表现就越差。它要么在左侧过度拟合,要么在右侧欠拟合会有一些中间值,使算法表现最佳。交叉验证所做的就是尝试许多不同的值。尝试许多不同的值,并评估许多不同点的交叉验证误差,然后选择一个具有较低交叉验证误差的值。这条曲线的左侧部分对应于欠拟合和高偏差,右侧部分对应于过拟合和高方差。而在这个图中,高方差在左边,高偏差在右边。但这就是为什么这两个图像有点像彼此的镜像。但在这两种情况下,交叉验证评估不同的值都可以帮助你选择一个好的值。这就是正则化参数选择如何影响算法的偏差方差以及整体性能过程,掌握了如何使用交叉验证来为正则化参数做出一个好的选择。

让我们看看的具体数值,看看如何判断学习算法是具有高偏差还是高方差的。许多在手机上进行搜索的用户会使用语音识别,而不是在手机的小键盘上打字,因为对着手机说话通常比打字更快。比如“今天的天气怎么样?”或者像这样,“我附近的咖啡店。”语音识别算法的工作就是输出为文本。现在,如果要训练语音识别系统并测量训练误差,训练误差意味着训练集中,算法无法正确转录的音频片段的百分比是多少。假设此数据集的训练误差为10.8%,意味着它可以完美转录89.2%的训练集,但会犯10.8%的训练集错误。如果您还要在单独的交叉验证集上测量语音识别算法的性能,假设其错误率为14.8%。你会发现训练误差非常高,错误率为10%,然后交叉验证误差更高,但即使训练集有10%的错误,这个错误率似乎相当高。它具有很高的偏差,但事实证明,在分析语音识别时,测量另一件事也很有用,那就是人类的表现水平如何?换句话说,人类从这些音频片段中转录语音的准确程度如何?具体来说,假设你测量了流利说话者转录音频片段的能力,发现人类水平的表现达到了10.6%的错误率。为什么人类水平的错误率这么高?对于网络搜索,有很多音频片段有很多嘈杂的音频,由于音频中的噪音,实际上没有人能够准确地转录所说的内容。如果连人类都会犯10.6%的错误率,那么似乎很难指望学习算法能做得更好。为了判断训练错误是否很高,看看训练错误是否远远高于人类水平的表现会更有用,在这个例子中,它的表现只比人类差0.2%。但相比之下,之间的差距要大得多。实际上,两者之间的差距为4%。当我们将其与人类水平的表现进行比较时,我们发现该算法在训练集上的表现实际上相当不错,但更大的问题是交叉验证误差远高于训练误差,这就是为什么我会得出结论,该算法实际上存在更多的方差问题而不是偏差问题。判断训练误差是否高通常有助于确定性能的基准水平,而我所说的性能基准水平是指学习算法最终达到的错误水平。确定性能基准水平的一种常见方法是衡量人类在这项任务上的表现如何,因为人类非常擅长理解语音数据、处理图像或理解文本。当您使用非结构化数据(例如:音频、图像或文本)时,人类水平的表现通常是一个很好的基准。估计基准性能水平的另一种方法是,如果存在某种竞争算法,可能是其他人已经实现的先前实现,甚至是竞争对手的算法,那么如果可以测量基准性能水平,则可以建立基准性能水平。如果可以访问此基准性能水平,那么可以合理地希望达到的错误水平是多少?然后,在判断算法是否具有高偏差方差时,查看基准性能水平训练误差交叉验证误差。然后要测量的两个关键数值是:训练误差与希望获得的基准水平之间的差异是多少?如果这个数值很大,那么会是一个高偏差问题。然后查看训练误差和交叉验证误差之间的差异是多少?如果这个差异很大,那么会是一个高方差问题。第二个例子,如果基准水平的表现;即人类水平的表现,训练误差交叉验证误差差距是4.4%。训练误差远高于人类所能达到的水平和我们希望达到的水平,而交叉验证误差只比训练误差大一点。这个算法有高偏差问题。通过查看训练误差和交叉验证误差可以直观地了解算法有高偏差高方差问题的程度。有时,性能的基准水平可能是0%。如果目标是实现比基准水平更好的性能,那么性能的基准水平可能是0%,但对于某些应用程序(例如语音识别应用程序),其中一些音频只是嘈杂的,那么性能的基准水平可能远高于零。您的算法可能存在高偏差高方差。基线和训练误差之间的差距4.4%,训练误差和交叉验证误差之间的差距是4.7%。则算法具有高偏差高方差。总而言之,查看训练误差是否很大是判断算法是否具有高偏差的一种方法,但数据有时只是嘈杂且无法期望获得零误差,建立这个基准性能水平很有用。同样,查看交叉验证误差是否比训练误差大得多,可以让您了解算法是否存在高方差问题

学习曲线是一种帮助理解学习算法并如何根据其经验量(例如,它拥有的训练示例数量)来执行的方法。如下图所示,绘制一个适合二次函数模型的学习曲线。绘制交叉验证误差)和训练误差)。

在上图中,横轴是。代表训练集大小。纵轴代表误差()。随着(训练集大小)变大,这将学习到更好的模型,因此交叉验证误差会下降。现在绘制训练误差随着训练集大小变大会增加。从一个例子开始,当你只有一个训练示例时。如果用二次模型拟合直线,你的训练误差将为零。如果有两个这样的训练示例呢?可以再次拟合一条直线并实现零训练误差。事实上,如果有三个训练示例,二次函数仍然可以很好地拟合它并获得几乎为零的训练误差,但现在训练集稍微大一点,比如说有四个训练示例,那么完美地拟合所有四个示例就会变得有点困难。当将训练集大小增加到4时,训练误差会稍微增加一点。假设有5个训练样本,要完美拟合所有样本就更难了。总结一下,当你只有很少的训练样本,比如1、2、3个时,相对容易得到零或非常小的训练误差,但是当有更大的训练集时,二次函数很难完美拟合所有训练样本。这就是为什么随着训练集变大,训练误差会增加,因为完美拟合所有训练样本变得更加困难。请注意,交叉验证误差通常会高于训练误差,因为将参数拟合到训练集上。期望在训练集上的表现至少会比在交叉验证集上的表现好一点,或者当m较小时,甚至可能会好很多。现在让我们看看高偏差高方差学习曲线是什么样的?先从高偏差的情况开始。如果绘制训练误差,那么训练误差就会像预期的那样上升。这条训练误差曲线可能会开始趋于平缓。我们称之为平台期,意思是一段时间后趋于平缓。这是因为在拟合简单的线性函数时,随着得到越来越多的训练样本,模型实际上并没有发生太大的变化。这就是为什么平均训练误差在一段时间后趋于平缓的原因。同样,交叉验证误差也会在一段时间后下降并变大,这就是为什么再次高于,但会在超过某个点后,即使获得再多的样本示例,拟合的直线也不会发生太大变化。因为模型太简单了,无法适应这么多数据。这就是为什么这两条曲线,一段时间后都会趋于平坦的原因。如果您对该基准水平的表现有一个衡量标准,例如人类水平的表现,那么它们往往会低于当下的。基准水平和之间存在很大差距,这是我们对该算法具有高偏差的指标。也就是说,如果能够拟合一个比直线更复杂的函数,模型做的更加好。如果这里有更大的训练集,情况会怎样?如果将这两条曲线向右延伸,它们都会变平,而且它们可能都会一直保持这种平坦状态。无论向图表右侧延伸多远,这两条曲线都永远不会以某种方式下降到人类水平的表现,无论训练集有多大,它们几乎都会永远保持这种平坦状态。

这得出了一个结论,如果你的算法具有高偏差,那么唯一能做的就是向其投入更多训练数据,但这永远不会将错误率降到很低。这就是为什么在投入大量精力收集更多训练数据之前,需要检查你的学习算法是否具有高偏差高方差的学习曲线又会是什么样的?如果用来拟合四阶多项式,那么会得到一条看起来像这样的曲线,即使它非常适合训练数据,但它并不具有泛化能力会随着训练集大小的增加而上升,所以你会得到一条看起来像这样的曲线,而会高得多,所以交叉验证误差训练误差高得多。这种高方差在训练集上的表现比在交叉验证集上要好得多。如果要绘制一个基准水平的表现,比如人类水平的表现,可能会发现,有时甚至低于人类水平的表现。但是过度拟合可能会很好地拟合训练集,得到一个不切实际的低误差,当方差较大时,增加训练集大小有很大帮助,训练误差继续上升,交叉验证误差下降并接近。因此,在这种情况下,可能只需增加训练集大小即可降低交叉验证误差并使算法的表现越来越好。总而言之,如果学习算法存在高方差,那么获取更多训练数据确实会有所帮助。因为会发现会继续下降。在这个例子中,只需获取更多训练数据,算法就可以从相对较高的交叉验证误差转变为更接近人类水平的表现。如果你正在构建机器学习模型,可以根据需要绘制学习曲线,也就是说,可以采用训练集的不同子集(有1,000个训练示例,可以仅使用100个训练示例训练模型并查看训练误差和交叉验证误差,然后使用200个示例训练模型,保留800个示例并暂时不使用它们),然后绘制等重复并绘制学习曲线。以这种方式将其可视化,应该是另一种查看学习曲线高偏差还是高方差的方法。但有一个缺点是,使用不同大小的训练集子集来训练如此多不同的模型在计算上非常昂贵,因此在实践中,并不经常这样做。

通过查看,即训练误差交叉验证误差,或者绘制学习曲线,可以了解学习算法是否具有高偏差高方差。这将帮助我更好地决定下一步该做什么,来提高学习算法的性能。可以看一个例子,线性回归来预测房价,但算法在预测中产生了不可接受的错误,接下来应该怎么做?想到的方法是获取更多训练示例,尝试少量特征,附加特征等等。如果学习算法有高偏差,或高方差,第一个方法是获得更多的训练样本。如果算法有高偏差,那么唯一能做的就是获得更多的训练数据,但这对于高偏差不起作用。相反,如果算法有高方差,比如说它对一个非常小的训练集过度拟合,那么获得更多的训练样本将大有帮助。第一个方法(获得更多的训练样本)有助于解决高方差问题。第二个方法是减少特征数量,如果学习算法有太多的特征,那么它会给算法带来太多的灵活性,而适应非常复杂的模型。这有点像等等。如果消除其中的几个,那么模型就不会变得那么复杂,也不会有那么高的方差。减少特征数量将有助于降低算法过度拟合数据的灵活性。这是一种可以帮助解决高方差的策略。第三种方法是添加额外的特征。这将帮助您解决高偏差问题。举一个具体的例子,如果仅根据房屋大小来预测房屋的价格,但事实证明房屋的价格也取决于卧室数量、楼层数量和房屋年龄,那么除非添加这些额外的特征,否则算法永远不会做得更好。这是一个高偏差问题,添加额外的特征是解决高偏差问题的一种方法。第四种方法是添加额外的多项式特征可以在训练集上做得更好,是一种解决高偏差问题的方法。第五种方法是降低(正则化参数值)将减少对这个项的关注,而更多地关注其它项,这有助于你解决高偏差问题。最后,第六种方式是增加值,如果过度拟合训练集,增加是有意义的,只是投入了太多的注意力来拟合训练集,但以牺牲对新示例的推广为代价,因此增加会使算法拟合的更平滑,这有助于解决高方差问题

如果你发现算法存在高方差,那么主要的方法是:要么获得更多的训练数据,要么简化模型。简化模型的意思是,要么获取一组较小的特征,要么增加正则化参数。相反,如果算法存在高偏差,主要的方法是让模型更灵活地拟合更复杂或更弯曲的函数。添加额外的特征或添加多项式特征,或者降低正则化参数值。如果减少训练集的大小,训练集的拟合效果会更好,但这往往会降低交叉验证误差和学习算法的性能,因此不要为了解决高偏差问题而随意丢弃训练样本。偏差方差是非常强大的概念之一。

我们发现高偏差高方差都是不好的,因为它们会损害算法的性能。如果用不同阶的多项式拟合一个数据集,一个非常简单的模型,它可能有高偏差,而如果要拟合一个复杂的模型,它可能有高方差。偏差和方差之间存在这种权衡,选择二阶多项式可以帮助做出权衡。如果你的模型太简单,偏差就会很高,如果模型太复杂,方差就会很高。这时必须在它们之间找到一个权衡,才能找到最好的结果。但神经网络提供了一种摆脱这种必须权衡偏差方差的困境的方法,大型神经网络在小型中等规模的数据集上训练时是低偏差。如果你你的神经网络足够大,总是可以很好地拟合训练集。可以根据需要尝试减少偏差或减少方差,而无需在两者之间进行权衡。

首先在训练集上训练算法,然后询问它在训练集上的表现是否良好。测量并查看它是否很高(高是指相对于人类水平的表现或某些基准水平的表现,如果它表现不佳,那么你就有高偏差问题,高训练误差)。减少偏差的一种方法是使用更大的神经网络,更大的神经网络是指更多的隐藏层或每层更多的隐藏单元。然后,继续这个循环,神经网络越来越大,直到它在训练集中达到的错误水平大致与希望达到的目标错误水平相当,这可能是人类水平的表现。之间的巨大差距表明存在高方差问题,如果存在高方差问题,那么尝试修复它的一种方法是获取更多数据。获取更多数据并返回并重新训练模型,然后仔细检查,只需要训练集吗?如果不是,则使用更大的网络,或者看看它在交叉验证集上是否确实如此,如果不是,则获取更多数据。如果继续循环往复,直到最终它在交叉验证集上表现良好。当然,这种方法的应用存在局限性,训练更大的神经网络不会减少偏差,但在某些时候它确实会消耗大量计算资源。这就是为什么神经网络的兴起确实得益于超高速计算机的兴起,尤其是GPU。它对加速神经网络也非常有用。但即使使用硬件加速器,超过一定程度,神经网络也会变得非常庞大,需要很长时间进行训练,变得不可行。当然,另一个限制是更多的数据。有时只能获得这么多数据,超过一定程度就很难获得更多数据。但在增加神经网络之后,会发现方差很大,在这种情况下,可能会收集更多数据。当您训练神经网络时,经过精心选择的正则化的大型神经网络通常与小型神经网络一样好或更好。有一个警告,那就是当训练大型神经网络时,它的计算成本会更高。所以它的主要坏处是,它会减慢训练和推理过程,并且非常短暂地对神经网络进行正则化。如果神经网络的成本函数是平均损失,所以这里的损失可能是平方误差逻辑损失

然后,神经网络的正则化项看起来与期望的非常相似,即,其中这是神经网络中所有权重的总和,与线性回归逻辑回归正则化类似,通常不会对神经网络中的参数进行正则化。在TensorFlow中实现正则化的方式是回想一下,手写数字分类模型的代码。创建三个层,其中包含多个拟合单元激活,然后创建一个包含三个层的顺序模型。添加正则化L2(0.001),为了简单起见,可以为所有权重和所有不同的层选择相同的值。首先适当地进行正则化,拥有更大的神经网络几乎不会有什么坏处。一个警告是,拥有更大的神经网络会减慢你的算法。其次,只要训练集不是太大。那么更大的神经网络通常是低偏差的。所以深度学习的兴起确实改变了机器学习从业者对偏差方差的看法。

1
2
3
4
5
6
7
8
9
import tensorflow as tf
from tensorflow.keras import Sequential
from tensorflow.keras.layouts import Dense

model = Squential([
Dense(units = 25,activation='relu', kernel_regularizer = L2(0.01)), # layer 1
Dense(units = 15,activation='relu', kernel_regularizer = L2(0.01)), # layer 2
Dense(units = 1, activation='sigmoid', kernel_regularizer = L2(0.01))]) # layer 3

开发流程

开发机器学习模型,首先,要决定系统的整体架构。选择机器学习模型以及决定使用哪些数据,也许还要选择超参数等等。然后,根据这些决定,训练模型。正如之前提到的,当第一次训练模型时,它几乎永远不会按照希望的那样工作。建议下一步是查看一些诊断,例如查看算法的偏差方差以及误差分析。根据诊断结果做出决定,例如是否要扩大神经网络、变更正则化参数、添加更多数据、添加更多特征、减少特征等。然后,使用新选择的架构再次进行此循环,并且通常需要多次迭代才能达到所需的性能。让我们看一个构建电子邮件垃圾邮件分类器的示例。左侧的示例是垃圾邮件的典型样子。本周特价,劳力士手表。垃圾邮件发送者有时会故意拼错这些单词,例如手表、药品和抵押贷款,以试图让垃圾邮件识别器出错。相比之下,右边的这封电子邮件是真实电子邮件。如何构建分类器来识别垃圾邮件和非垃圾邮件?一种方法是训练监督学习算法,其中输入特征将是电子邮件的特征,输出标签将是10,具体取决于它是垃圾邮件还是非垃圾邮件。构建电子邮件特征的一种方法是,取出英语或其他词典中的前10,000个单词,并使用它们来定义特征。例如,右侧的电子邮件有以下单词列表a、Andrew buy deal discount等等。将这些特征设置为01,具体取决于该词是否出现。构建特征向量的方法有很多。另一种方法是让这些数字不仅仅是10,而是计算给定单词在电子邮件中出现的次数。如果buy出现了两次,将其设置为2,有了这些特征,您就可以训练分类算法(例如逻辑回归模型神经网络)来根据这些特征来预测。训练完初始模型后,如果它的效果不如您所愿,可能会有多种改进学习算法性能的想法。例如,收集更多数据。例如,如果算法具有高偏差而不是高方差,花费数月时间收集数据效果甚微。但如果您的算法具有高方差,那么收集更多数据可能会大有帮助。

假设有交叉验证示例,并且算法错误分类了其中100个交叉验证示例。误差分析过程只是手动查看这100个示例并了解算法出错的地方。从交叉验证集中找到一组算法错误分类的示例,并将它们分组为共同的属性或共同的特征。例如,如果注意到错误分类的垃圾邮件是药品销售,试图销售药品或药物,假设有21封电子邮件是药品垃圾邮件。假设通过电子邮件路由信息,发现7个具有不寻常的电子邮件路由,18封电子邮件试图窃取密码或钓鱼电子邮件。垃圾邮件有时也不会在电子邮件正文中编写垃圾邮件,而是创建图像,然后将垃圾邮件写入电子邮件中的图像中。这使得学习算法更难弄清楚。也许其中一些电子邮件是嵌入图像的垃圾邮件。即使构建了非常复杂的算法来查找故意的拼写错误,也只能解决100个错误分类示例中的3个。例如,可能有一个具有不寻常路由的医药垃圾邮件,或者一个具有故意拼写错误的密码,并且也在试图进行网络钓鱼攻击。一封电子邮件可以算入多个类别。在这个例子中,算法错误分类了100个示例。如果有一个更大的交叉验证集,假设我们有5,000个交叉验证示例,如果算法错误分类了其中的1,000个,可能没有时间手动查看算法错误分类的1,000个示例。在这种情况下,通常会随机抽取一个子集,通常大约100个,因为这是可以在合理的时间内查看的数量。希望查看大约100个示例将为您提供足够的统计数据,了解最常见的错误类型。经过此分析,如果发现很多错误都是医药垃圾邮件,那么这可能会给您一些灵感,让您知道下一步该做什么。例如,您可能决定收集更多数据,但不是收集所有内容的数据,而只是找到更多有关医药垃圾邮件的数据,以便学习算法能够更好地识别这些医药垃圾邮件。或者,您可能决定提出一些与垃圾邮件发送者试图销售的药品的具体名称相关的新特征,以帮助学习算法更好地识别此类医药垃圾邮件。然后,这可能会启发检测网络钓鱼电子邮件相关的算法进行特定更改。例如,查看电子邮件中的URL并编写特殊代码以添加额外特征,以查看它是否链接到可疑的URL。或者,获取更多钓鱼电子邮件的数据,以帮助学习算法更好地识别它们。此误差分析的重点是手动检查算法错误分类或错误标记的一组示例。通常,这会为下一步尝试提供灵感,有时它还可以告诉您某些类型的错误非常罕见,因此不值得花费太多时间去修复。总的来说,偏差方差诊断以及误差分析对于筛选模型非常有帮助。误差分析的一个限制是,对于人类擅长的问题,它更容易做到。对于人类不擅长的任务,误差分析可能会更难一些。

如果误差分析发现制药垃圾邮件是一个问题,可以采取更有针对性的措施,而不是获取有关所有类型的更多数据,而是专注于获取更多有关制药垃圾邮件的示例。而且,以更适中的成本,来添加所需的电子邮件。如果您有大量未标记的电子邮件数据,比如闲置的电子邮件,但没有人费心将其标记为垃圾邮件或非垃圾邮件,可以让人工快速浏览未标记的数据并找到更多示例,特别是与制药相关的垃圾邮件。这可以大大提高学习算法性能,而不仅仅是尝试添加更多各种电子邮件的数据。但如果有一些方法可以添加更多数据。如果误差分析表明算法在某些数据子集上表现特别差。而想要提高性能,那么只需获取做得更好的类型的数据。无论是更多的制药垃圾邮件示例还是更多的网络钓鱼垃圾邮件示例或其他内容。这可能是一种更有效的方法,只需添加一点点数据,但可以大大提高算法性能。不仅仅是获得全新的训练示例。还有一种技术被广泛使用,特别是用于图像和音频数据,它可以显著增加训练集大小。这种技术称为数据增强。我们要做的是利用现有的训练示例来创建一个新的训练示例。例如,如果你试图识别从A~Z的字母,以解决OCR光学字符识别问题。给定这样的图像,通过稍微旋转图像来创建一个新的训练示例。或者通过稍微放大图像或缩小图像或通过改变图像的对比度。这些是图像扭曲的例子,但不会改变它仍然是字母A的事实。对于某些字母,可以获取字母的镜像,它仍然看起来像字母A。但这仅适用于某些字母,但这些将是获取训练示例的方法。并对输入应用扭曲或变换,以便得出另一个相同标签的示例。通过这样做,你告诉算法,字母A旋转了一点、放大了一点或缩小了一点,它仍然是字母A。创建这样的额外示例可以让学习算法更好地学习如何识别字母A。对于数据增强的更高级示例,还可以取字母A,并在其上方放置一个网格。通过引入此网格的随机扭曲,你可以取字母A。并引入A的扭曲,以创建一个更丰富的字母A示例库。然后,扭曲这些示例的过程将一个示例的图像变成了训练示例,你可以将其提供给学习算法,希望它能够更稳健地学习。数据增强的这个想法也适用于语音识别。假设对于语音搜索,有一个原始音频剪辑,可以将数据增强应用于语音数据的一种方法是获取嘈杂的背景音频。例如,这是人群的声音。事实证明,如果将这两个音频剪辑加在一起,听起来像有人在说今天的天气怎么样。但他们是在背景中吵闹的人群中说这句话的。如果您要获取不同的背景噪音,比如车里的人,这就是汽车的背景噪音。如果您想将原始音频剪辑添加到汽车噪音中,好像说话者是从车里说的。更高级的数据增强步骤是,让原始音频听起来像是在手机连接不良的情况下录制的。这实际上是一种非常关键的技术,可以人为地增加训练数据的大小,从而构建更准确的语音识别器。数据增强的一个技巧是,数据所做的更改或扭曲应该代表测试集中的噪音或扭曲类型。相反,在数据中增加纯随机无意义的噪声通常没有多大帮助。例如,你取字母A,如果只向每个像素添加噪声,它们最终会得到像这样的图像。但如果这不能代表你在测试集中看到的内容,因为你在测试集中通常不会得到这样的图像,那么这实际上就没那么有用了。因此,考虑数据增强的一种方法是,如何修改、扭曲数据,或在数据中制造更多噪声。现在,数据增强采用现有的训练示例并对其进行修改以创建另一个训练示例。其中一种技术是数据合成,你可以从头开始制作全新的示例。不是通过修改现有示例,而是通过创建全新的示例。以照片OCR为例。照片OCR或照片光学字符识别是指查看这样的图像并让计算机自动读取图像中出现的文本的问题。这张图片中有很多文本。如何训练OCR算法来读取图像中的文本?照片OCR任务的一个关键步骤是能够查看这样的小图像并识别中间的字母。因此,中间有T,中间有字母L,中间有字母C 等等。因此,为这项任务创建人工数据的一种方法是,进入计算机的文本编辑器,会发现它有很多不同的字体,使用这些字体并在文本编辑器中输入随机文本。并使用不同的颜色、不同的对比度和非常不同的字体进行截图,你会得到像右边这样的合成数据。左边的图像是从世界上拍摄的真实照片中获取的真实数据。右边的图像是使用计算机上的字体合成的,实际上看起来非常逼真。因此,使用这样的合成数据,可以为照片OCR任务生成大量图像或示例。编写代码为给定应用程序生成逼真的合成数据可能需要大量工作。但是它有时可以帮助你为应用程序生成大量数据,并极大地提升你的算法性能。合成数据生成最有可能用于计算机视觉任务,而较少用于其他应用。有时花更多时间采用以数据为中心的方法会更有成效,这种方法专注于设计算法使用的数据。如果这是误差分析告诉你需要更多这方面的数据。使用数据增强来生成更多图像和音频,或使用数据合成来创建更多训练示例。

对于没有那么多数据的应用,迁移学习是一种很棒的技术,它允许使用来自不同任务的数据来帮助您的应用。让我们来看看迁移学习是如何工作的。迁移学习的工作原理如下。假设您想要识别从0~9的手写数字,但是没有那么多手写数字的标记数据。假设找到一个非常大的数据集,其中包含一百万张猫、狗、汽车、人等图片,一千个类别。然后,在这个包含一百万张图像和一千个不同类别的大型数据集上训练神经网络,以图像作为输入,并学习识别这1,000个不同类别中的任何一个。在此过程中,学习神经网络第一层的参数,第二层的参数,依此类推,输出层的参数。要使用迁移学习,必须复制此神经网络,并在其中保留参数 。但对于最后一层,需要消除输出层并将其替换为一个只有10个输出单元(而不是1,000个)的输出层。这 10个输出单元将对应于神经网络识别的类别。请注意,参数无法复制,因为此层的维度已更改,需要计算新的参数 并从头开始训练,而不是直接从前一个神经网络中复制。在迁移学习中,可以使用前四层的参数(实际上是除最终输出层之外的所有层)作为参数的起点,然后执行优化算法(例如梯度下降或Adam优化算法),并使用来自顶层神经网络的值初始化参数。

具体来说,有两种方式可以训练这个神经网络参数。选项1是只训练输出层参数。可以将参数作为顶层的值,并将它们固定,并使用随机梯度下降Adam优化算法仅更新,以降低从的小训练集中学习识别这些数字时使用成本函数。选项2是训练神经网络中的所有参数,包括,但前四层参数将使用顶层训练过的值进行初始化。如果训练集非常小,那么选项1可能会更好一些,但是如果训练集稍大一些,那么选项2可能会更好一些。这种算法之所以被称为迁移学习,是因为通过学习识别猫、狗、牛、人等等。希望它已经学会了一些合理的参数集,用于处理图像输入的早期层。然后通过将这些参数转移到新的神经网络,新的神经网络会从更好的参数开始,这样我们就可以进行进一步的学习。希望它最终能得到一个相当不错的模型。这两个步骤,首先在大型数据集上进行训练,然后在较小的数据集上进一步调整参数,第一步被称为监督预训练。然后第二步称为微调,从监督预训练中获得的参数,然后进一步运行梯度下降微调权重。如果有一个小型数据集,即使只有几十、几百、几千或几万张手写数字图像,能够从这些与任务不太相关的数百万张图像中学习,实际上可以大大提高学习算法的性能。迁移学习的一个好处是不需要亲自进行监督式预训练。对于许多神经网络,已经有研究人员在大型图像上训练了一个神经网络,并将训练好的神经网络发布在互联网上,任何人都可以免费下载和使用。意味着你不必自己执行第一步,只需下载别人可能花了数周时间训练的神经网络,然后替换输出即可。将层与自己的输出层组合,并执行选项1或选项2来微调其他人已经进行过监督预训练神经网络,只需进行微调,就可以快速获得一个表现良好的神经网络。但为什么迁移学习会有效?如果正在训练神经网络来检测图像中的不同物体,那么神经网络的第一层可能会学习检测图像的边缘。我们认为这些是图像中用于检测边缘的低级特征。这些方块中的每一个都是单个神经元学会检测的可视化,学会将像素组合在一起以找到图像中的边缘。神经网络的下一层然后学习将边缘组合在一起以检测角点。这些方块中的每一个都是单个神经元可能学会检测的可视化,必须学会技术性的、简单的形状,如像这样的角点形状。神经网络的下一层可能已经学会检测一些更复杂但仍然是通用的形状,如基本曲线或像这样的较小形状。这就是为什么通过学习检测大量不同的图像,从而教授神经网络检测边缘、角点和基本形状。这对许多计算机视觉任务很有用,例如识别手写数字。不过预训练的一个限制是,预训练微调步骤中的图像类型必须相同。相反,构建语音识别系统来处理音频,那么在图像上预训练的神经网络可能不会在音频上发挥太大作用。需要一个在音频数据上预训练的神经网络,然后在音频数据集上进行微调

语音识别为例来说明机器学习项目的整个开发周期。机器学习项目的第一步是确定项目范围(你想做什么)。决定要做什么之后,接下来需要收集数据。决定需要什么数据来训练机器学习系统。在完成初始数据收集后,就可以开始训练模型了。在这里,训练语音识别系统并进行误差分析,然后迭代改进模型。在对训练模型进行误差分析偏差方差分析后,接下来可能需要回去收集更多数据,或者只收集更多特定类型的数据。训练出高性能机器学习模型(例如语音识别模型)后,部署模型的常见方法是将机器学习模型部署到服务器中,一般将这个服务器称为推理服务器,它的工作是调用机器学习模型(即训练好的模型)进行预测。机器学习中有一个不断发展的领域,称为MLOps。代表机器学习操作。这指的是如何系统地构建、部署和维护机器学习系统的实践。为了确保机器学习模型可靠、可扩展、具有良好的规律、受到监控,然后根据需要对模型进行更新以使其运行良好。

如果正例与负例的比例非常不平衡,远远偏离50%:50%,错误指标(如准确率)的效果就不太好。假设你正在训练一个二元分类器,根据实验室测试的数据来检测患者的罕见疾病。如果疾病存在,则,否则。假设测试集上出现了1%的错误率,正确率为99%。如果你有一个算法实现了99.5%的准确率,另一个算法实现了99.2%的准确率,另一个算法实现了99.6%的准确率。很难知道哪一个才是最好的算法。因为误差最小的可能不是特别有用的预测,在处理倾斜数据集的问题时,我们通常使用不同的误差度量,而不仅仅是分类误差,来确定学习算法的表现如何。具体来说,常见的误差度量精确度召回率。为了评估学习算法对一个罕见类的性能,构建一个所谓的混淆矩阵很有用,它是一个矩阵,如下所示。在顶部的轴上,我将写出实际的类,它可以是10。在纵轴上,我将写下预测类别,为了评估算法在交叉验证集上的表现,100个交叉验证示例,其中15个,学习算法预测为1。因为在交叉验证集的这100个示例中,总共有25个示例的实际类别为175个示例的实际类别为0,通过将这些数字垂直相加即可。当实际类别为1且预测类别为1时,我们将其称为真阳性,因为预测为​​阳性,并且结果为真,因此有一个阳性示例。在右下角的这个单元格中,实际类别为0,且预测类别为0,将其称为真阴性,右上角的这个单元格称为假阳性,因为算法预测为阳性,但结果为假。它实际上不是阳性,所以这被称为假阳性。这个单元格称为假阴性数量,因为算法预测为0,但结果为假。它实际上不是阴性。实际类别为1。将分类为这四个单元格,您可能要计算的两个常见指标是精确度召回率。它们的含义如下。学习算法的精确度计算的所有患者中真正患有罕见疾病占比。换句话说,精确度定义为真阳性数除以分类为阳性的人数。换句话说,预测为阳性的所有示例中,正确的比例是多少。该公式的另一种写法是真阳性除以真阳性加假阳性,最终会得到预测为阳性的总数。在这个例子中,分子,真阳性,将是。所以这个算法的精确度是75%,因为它预测为阳性的所有事物中,患有这种罕见疾病的所有患者中,它有75%的时间是正确的。第二个有用的计算指标是召回率召回率指的是:在所有确实患有罕见疾病的患者中,我们正确检测出患有该疾病的比例是多少?召回率定义为真阳性数除以实际阳性数。它实际上是真阳性数加上假阴性数,因为通过将这个左上单元格和这个左下单元格相加,可以得到实际阳性示例的数量。在这个例子中,召回率是。该学习算法的精确度0.75召回率0.60


召回率指标有助于您检测学习算法是否一直预测为零。因为如果您的学习算法只是打印,那么真正的阳性数量将为零,因为它从不预测阳性,因此召回率将等于零除以实际阳性的数量,即等于零。一般来说,精确度为零或召回率为零的学习算法不是有用的算法。精确度实际上变得不确定,因为它实际上是零除以零。但在实践中,如果算法甚至没有预测一个阳性,我们只能说精确度也等于零。但我们会发现,计算精确度召回率可以更容易地发现算法是否既准确又合理,也就是说,当它说一个病人患有疾病时,病人患病的可能性很大,比如在这个例子中是75%,同时还要确保在所有患病的病人中,比如这里发现了60%。当你有一个罕见的类别时,查看精确度召回率,并确保这两个数字都相当高。如果你有一组病人,那么召回率衡量的是在患有这种疾病的病人中,有多少人你能准确地诊断为患有这种疾病。所以当你有偏斜的类别,精确度召回率可以帮助你判断学习算法是否做出了好的预测