写在前面
MachineLearningYearing这本书是一本很好的工程化指导性书籍。本文在官方翻译版出来前为了加强理解,自行翻译了前30多章。
Machine Learning Yearing
机器学习是许多重要应用的基石,包括网页搜索、反垃圾邮件、产品推荐等等。我假设你或者你的团队正在跟进一个机器学习应用,你希望让项目的进度加快。本书将帮助你达到这个目标。
例子:创建一个提供猫图片的创业公司
假设你正建立一个提供无限猫图片流给爱猫人士的创业公司。
你使用神经网络建立了一个计算机视觉系统来检测图片中的猫,但是悲剧的是你的算法准确率并不够好。你当前面临巨大的压力来优化你的猫检测器。你该怎么办?
你的团队提出了许多方案,例如:
如果你选择得当,你将建成领先的猫图片平台,带领你的公司走向成功。如果你决策错误,你可能会浪费几个月时间。你会怎么处理?
本书将告诉你怎么办。大多数机器学习问题都留下了蛛丝马迹告诉你怎么尝试会有用,怎么做没用。学习如何读懂这些线索可以节约你几个月甚至几年的开发时间。
读完本书后,你将在如何为你的团队在机器学习项目中设定技术路线有较为深刻的理解。
但是你团队中的成员可能并不理解为什么你建议这样的技术路线。也许你希望你的团队定义一个单独的衡量指标,但是他们并不赞同这样的建议。你该怎么说服他们?
这也就是为什么我将每一张内容都写得很短的原因:这样你可以将它们打印出来,让你的团队成员读其中的1-2章他们需要了解的内容。
一点优先次序的变化,可能会对你的团队生产力产生巨大的影响。通过一点点优先级的改变帮助你的团队,我希望你能成为团队成功的超级英雄。
如果你上过想我在Coursera上的MOOC深度学习课程,或者你在有监督学习上有经验,你会看懂这些文字。
我假设你对有监督学习较为熟悉:使用表定好的训练数据如(x,y),学习一个将x映射到y的函数。有监督学习算法包括线性回归、逻辑回归与神经网络。除此之外还有其它形式的机器学习算法,但主流且实用的机器学习方法都是有监督学习的。
我将频繁的提到神经网络(也就是深度学习)。你仅需要通过本文得到一些基本的理解。
如果你对这里提到的基本概念不理解,请看Coursera上的机器学习课程前三周的视频:http://ml-class.org。
许多深度学习(神经网络)的概念已经存在了几十年,为什么这些概念如今迅速发展。
当前的进展有两大驱动:
当前人们花费更多的时间在数字设备上(笔记本电脑、移动设备)。他们数字端活动产生了大量我们可以用在学习算法上的数据。
我们仅在数年前才有利用现有大规模数据集,训练足够大的神经网络的能力。
从细节看即使你添加更多的数据,通常传统学习算法例如逻辑回归会陷入滞留期(Plateaus)。这意味着学习曲线变平,即使更多的数据也不能使算法继续优化:
就好像经典算法不知道如何处理这些我们现有的数据。
如果你训练一个小型的神经网络解决同一个有监督学习任务,你可能得到一个略微好些的结果:
这里,小型的神经网络的意思是指隐藏单元、层或者参数量比较少的情况。最后,如果你训练越来越大的神经网络结构,你得到的结果也会越来越好[1]:
因此,但你满足一下两个条件的时候,你会获得最好效果:1、训练一个非常大的神经网络,得到上图绿色的曲线;2、有数量巨大的训练数据。
有许多细节部分例如神经网络的架构等十分重要,此处会有很多创新。但如今更可靠的优化算法效果的方式是:1、训练更复杂的网络;2、新增更多的数据。
完成上文1、2两个步骤的过程却出奇的复杂。本书将详细的讨论细节。我们将从传统学习算法与神经网络的通用策略开始,逐步建立最先进的深度学习系统构建的策略。
让我们回到之前猫图片的例子:你运营一个手机app,用户上传各种不同东西的图片到你的app上,你希望自动找到猫的图片。
你的团队通过下载不同网站上的包含猫的图片作为正样本,不包含猫的作为负样本。他们将数据集三七分,70%作为训练集,30%作为测试集。用这些数据,他们训练了一个在训练集与测试集上都表现不错的猫检测模型。
但是当你将检测器部署到手机app上的时候,你发现效果相当的差。
为什么会这样?
你发现用户传上来的样本跟网站下载用于建立训练集的有很大的出入:用户上传的图片很多是手机拍摄的,分辨率低,图片模糊,光线不足。由于训练,测试集是由网络图片组成的,你的算法对手机图片的实际分布并没有足够的鲁棒性。
在大数据时代之前,随机按照三七分来建立训练集与测试集是通用的规则。这在实践中会起到一定作用,但在越来越多训练分布(上述网站数据例子)与你最终关心的分布(手机图片)不一致的情况下,表现并不好。
我们通常定义:
一旦定义好了验证集与测试集,你的团队可以尝试例如不同算法参数等许多思路,来确定怎样效果会更好。开发与测试让你的团队快速的了解你们算法的性能。
换句话说,验证与测试集的目的是引导你的团队为机器学习系统做最有效的改变。
因此,你应该做以下工作:
建立可以代表未来实际应用的验证与测试集。
换句话说,你的测试集不能仅仅是当前数据的30%,特别是当你实际应用的数据(手机图片)与你的训练集(网络图片)本质不一样的情况。
如果你的手机应用还没有上线,你可能还没有用户,因此也不可能得到真实反映你未来应用场景的数据。但是你还是可以近似的解决这个问题。例如,让你的朋友用手机拍猫的图片发给你。一旦你的应用上线了,你可以用实际数据来更新你的验证与测试数据集。
如果你实在没有任何方式得到将来实际应用的样本,也许你也可以先从网络图片开始。但是你必须了解这样会导致系统鲁棒性不好的风险。
决定投入多少资源建立验证与测试集是需要判断力的。但是不要假设你的训练集分布于测试集一致。尝试从最终应用场景的样本中挑取图片,而不是用从现有的训练数据中挑取。
你将你的猫app图像数据根据你最大的市场分为四个部分:1、美国;2、中国;3、印度;4、其它。为了建立验证集与测试集,假设我们将1和3作为开发集,2和4作为测试集。换句话说,随机分配两个子集作为验证集,另外两个作为测试集,这样对么?
一旦定义好的验证集与测试集,你的团队将专注于提升验证集上的算法效果。因此,验证集应当反映你最希望改进的任务:在四个地理位置都表现的好,而不是仅仅在两个地方。
验证集与测试集的分布不同还会带来第二个问题:有可能团队开发的算法在验证集表现很好,却在测试集表现很差。我将这个视为对大家努力很大的挫折与浪费。请避免让这样的事发生在你身上。
举个例子,假设团队开发了一个在验证集上表现很好但在测试集上表现不好的算法。如果你的验证集与测试集服从相同的分布,你可以很清晰的判断出问题出现在哪里:算法过拟合了验证集合。最有效的方法就是添加更多的数据到验证集中。
但是如果验证集与测试集服从不同的分布,你的决定就不那么清晰了。有好几个地方都有可能有问题:
做一个机器学习的应用已经很难了,验证集与测试集的不同分布会增加更多的不确定性在验证集上的优化是否在测试集上有效方面。验证集与测试集的不同分布使得搞清楚算法哪里出了问题这件事变得更难,因此也更难决定下一步工作的优先级。
如果你在进行第三方的评效(benchmark)问题,问题的创建者会指定来自不同分布的验证集与测试集。这种情况下对比测试数据集与训练集在服从同一分布,运气而不是技巧会决定在评效中的表现。开发在一种分布下训练却在另外一种分布也表现很好的学习算法是一个重要的研究课题。但是如果你的目标是在特征机器学习应用而不是研究上,我建议尝试选取符合相同分布的验证集与测试集。这样会让你的团队更加高效。
验证集应该大到可以区分出你要尝试的不同算法。例如,分类器A准确率在99.0%,分类器B的准确率为99.1%,如果验证集只有100张样本,那么它不能体现出0.1%的区别。从我见到的其他机器学习问题来看,100张样本太小了。验证集样本一般从1000张到10000张比较正常。10000张样本的验证集使得你有较大的机会检验处0.1%的准确率区别。[2]
对于成熟且重要的产品来说,例如广告推送,网络搜索,产品推荐等由于会直接影响公司的利润,我也见过团队竭力优化甚至0.01%。在这种情况下,验证集需要比10000张更多来检测更细微的改进。
那么测试集应该多大呢?测试集应该大到足够有效评估你系统的整体性能测程度。一种流行的方式是用30%的样本作为测试集。当我们的样本数不多,例如100-10000张的时候是有效的。但在大数据时代,我们面临着可能超过10亿数目的样本需要处理的机器学习问题时,分配验证与测试集的比例变小,尽管绝对的样本数变多了。没必要准备一个大到超出评价算法需求的验证与测试集。
分类准确率是一种典型的单评估指标:在验证集(测试集)上运行你的分类器,得到一个单独的分类准确率数字。通过这种评估,如果分类器A达到97%的准确率,分类器B达到90%,那么我们判断出分类器A的性能更好。
从另一个方面看,精度(Precision)与召回率(Recall)[3]不是一种唯一评价方式:它使用了两个数字来评估你的分类器。多个评估指标使得算法评估变得复杂。假设你的算法表现如下表:
上表中不能体现出那个分类器更好,所以也不能告诉你两个模型怎么选择。
在开发过程中,你的团队会尝试许多不同算法结构,模型参数,特征选择等。像准确率这样一个具有唯一性的评估指标可以让你将你的模型性能进行排序,快速决定那个模型更好。
如果你的确需要同时考量准确率与召回率,我建议找一种方法将他们合并成一个指标。例如,一个可以同时平均准确率与召回率的指标。或者你可以计算改进的平均方式“F1得分”,这个方式比直接均值更好。[4]
唯一的评估指标是你具备在大量分类器中迅速做出选择的能力。它提供了模型表现清晰的排名,也给项目的推进指明了方向。
就像最后一个例子,如果你分别根据猫分类器在关键市场1、美国;2、中国;3、印度;4、其他市场。这样就会有4个度量指标。通过将这四个数据进行平均或者加权平均就可以得到一个唯一的度量指标。进行平均或者加权平均是最常见的融合多度量指标的方式。
这里提供另外一种融合多个评估标准的度量方式。
假设你同事关系学习算法的准确率与运行时间。你需要从下列三个分类器中选择一个:
如果直接将准确率与运行时间放到一个公式里计算唯一度量方式会看起来有点奇怪:
Accuracy – 0.5 * RunningTime
这样做会比较合适:首先,定义一个可接受的运行时间。假设任何小于100ms的运行时间都是可以接受的。第二部,在保证运行时间限制的情况下,最大化准确率。这里,运行时间是一个满足指标(satisficing metric),对于你的分类器中满足这个指标就可以了,也就是最多不超过100ms的时耗。准确率是这里的优化指标(optimizing metric)。
如果你在N个不同约束项中权衡,例如模型二进制文件大小(这在移动端app中相当重要,没有用户愿意下载太大的apps),运行时间与准确率,你可以考虑设置N-1个约束项为满足即可的指标,例如你仅仅希望他们满足一个特定值就可以了。然后定义最后一个约束项作为优化指标。例如,给二进制文件的大小与运行时间设置一个可接受的阈值,在这些阈值的约束下优化准确率。
最后举一个例子,如果你要构建一个利用麦克风监听用户说特定激活语言激活的硬件设备。例如亚马逊的Echo听到“Alexa”,苹果的Siri听到“Hey Siri”,安卓听到“Okay Google”,百度听到“Hello Baidu”。你同时关注误识率(系统在没有唤醒词的时候激活的频率)与漏检率(有唤醒词但系统未激活的频率)。这个系统比较理想的性能指标是最小化漏检率(优化指标),满足24小时内的误检率不大于一次(满足即可指标)。
一旦你的团队在优化指标上达成一致,项目的进展会更快。
想提前知道哪种方法可以更好的解决新问题是一件很难的事。即使最有经验的机器学习工程师通常也需要大量尝试才能找到最满足应用的方法。在构建一个机器学习系统的时候,我通常这样做:
这是一个迭代的过程。迭代的速度越快,项目推进的速度越快。这也是为什么验证集、测试集与度量标准十分重要:每次你尝试新方法的时候,在验证集上的测试结果让你可以快速判断自己是否想正确的方向发展。
相反,假设你没有一个指定的验证集与度量方法。每次你的团队开发一个新的猫分类器,你都需要将它部署到app上,然后在app上经过几个小时真实应用测试验证算法效果是否有提升。这个过程相当漫长!而且,如果你的团队将准确率从95.0%提升到95.1%,在app上的测试可能根本体现不出来这0.1%的改进。然而很多个0.1%的提升会为你的系统带来很显著的提升。验证集与评价标准让你可以迅速确定那种方法可以给你小(或者大)的性能提升,也让你快速决定哪些方法需要保留,哪些需要抛弃。
当刚开始一个新项目的时候,我会快速建立验证与测试集,因为这样可以让团队有一个明确目标。
我通常要求我的团队在一周内提供一个初始版本的验证集/测试集,与处理评价指标。有些不完美的地方也没什么关系,总比过度思考等在那里要好。但这个一周的时间节点并不是用来评测应用的。例如,反垃圾邮件系统是一个成熟的深度学习应用。我见过有些团队在已经成熟的系统上花费数月的时间建立更好的验证集与测试集。
如果后续发现你的初始验证集与测试集或者评价标准有问题,务必快速修正它们。例如,如果你的验证集与评价标准得出分类器A好于分类器B的结论,但是你的团队任务认为分类器B才更适合你的应用,这可能就是一个你需要修改你的验证集、测试集与评价标准信号。
有三个主要原因可能到时验证集、测试集与评价标准错误的将分类器A评价为更好:
假设你的初始验证集与测试集主要有成年的猫图片组成,你运行你的app发现用户上传的更多的是幼年猫的图片。验证集与测试集的样本分布并不能代表实际样本分布。这种情况下,更新你的验证集与测试集使得他们更具有代表性。
重复在验证集验证算法的流程可能逐步让你的算法对验证集过拟合。在开发过程中,你需要在测试集上验证你的系统,当你发现验证集的效果远远好于你在测试集的表现的时候,这是在验证集过拟合的征兆。这种情况下,你需要一个新的验证集。
如果你需要跟踪团队的进度,你需要频繁的在测试集上评估你的系统(例如每周一次或者每月一次)。不要用测试集来决定算法的问题,包括是否回退到上个版本系统。如果你这么做,可就开始过拟合测试集了,这样也就不能依赖测试集来给系统一个完整无偏差的性能评估(这个评估无论是发论文还是做任何重要的商务决定时候都需要)。
对于之前提到的猫应用来说,你的评价指标是分类准确率。这个评价当前评价分类器A比分类器B好。但是当你尝试两种算法的时候发现,分类器A偶尔让一些黄色图片通过了分类。尽管分类器A准确率更高,但偶尔让一些黄色图片通过分类这件事完全不能接受,那个你该怎么做?
这个评价标准没有很好的分辨出分类器B比分类器A在产品中要好。因此你再也不能将这个评价标准作为算法选择的指标了。是时候换一个评价指标了。例如,你将评价指标中将让黄色图片通过的惩罚权重加的很重。我会强烈的推荐你选择一个新的评价指标,使用新评价指标给团队定一个明确的目标,而不是继续用一个不可信的评价指标,最后回到人工选择分类器的情况中去。
在项目开发过程中修改验证集、测试集与评价指标是很正常的情况。初始版本的验证集、测试集与评价指标让你快速开始项目迭代。如果你一旦发现验证集、测试集与评价指标没有将你的团队指向正确的方向,没关系!立即修改它们,并且让团队了解新的目标方向就可以了。
你希望建立一个新的反垃圾邮件系统。你的团队有许多想法:
尽管我曾经在反垃圾邮件领域工作过,但是还是很难从这些想法中挑一个方向。更别说如果你不是这个应用领域的专家。
所以不要指望一开始就设计建造一个完美的系统。一开始可能只花费几天时间[5]快速建立训练一个基础版本系统。也许基础版本系统离你可以假造最好的系统有很大的距离,但这还是对于验证基础系统功能有重要意义:你将快速找到可以投入你研发时间的最理想的研发方向。接下来的几张会像你展示如何解析上述细节。
当你把玩你猫应用的时候,你发现出现将狗误识成猫的样例。的确有些狗跟猫长得很像!
有些团队成员提取与三方应用结合会是自己的系统在狗图片识别上处理的更好。这些工作会需要花费数个月,团队成员对这件事都热情高涨。你应该说“去做吧“么?
在投入时间到这个数月的任务之前,我建议你首先评估下这样做到底会给你的系统提升多少准确率。这样你可以更理性的决定这个是否值得投入数月的研发时间,或者将这个时间投入到其他任务会更合理。
具体来说,你可以做下列的工作:
研究误分类样本的过程称为误差分析。此例中,如果你发现只有5%的误分样本是狗图片,也就是说无论你怎么提升你的算法对狗图片的处理效果,效果的提升都不会超过5%。换句话说,5%是这个方案对你项目效果提升的上限(表示最大可能的数目)。因此,如果你整个系统的准确率目前是90%,也就是说有10%的错误率,显得方案至多将准确率提升到90.5%(或者说错误率到9.5%,错误率比之前的10%降低了5%)。
相反,如果50%的错误都是狗图片,你可以更自信提出的方案会对项目的效果产生很大的效果。它可能将准确率从90%提到95%(对错误率有50%的减少,从10%降低到5%)。
简单的计数误差分析给你一个快速评估集成狗图像识别三方库可行性的估计。它给我们提供了一个是否投入时间的量化指标。
误差分析可以帮助你分析出优化方向是否可行。我见过许多工程师不愿意进行误差分析。他们通常更愿意扎到项目中并且实现这些想法,而不是反问自己这些想法是否值得投入时间。这是一个常见的错误:它可能导致你的团队花费数月的时间但仅仅收获一点点进步。
手动验证100张样本不是个长久的方法。即使你每张图片只花费1分钟,你需要花费2个钟。这两个小时可能会节省你数月的工作。
误差分析是指类似检查验证集中你的算法误分类样本的过程,这样你可以了解导致这些误差的潜在原因。这可以帮助你就像这个样例中給项目排优先级,也可以启发接下来要讨论的新研发方向。接下来几张也会展示出进行误差分析的最好方式。
你的团队提出了数个改进猫检测器的思路:
你可以高效的平行评估这些方案。我通常在研究100个误分类的验证集的时候建一个电子表格。我也会写下大致的描述来帮助我记住一些特定样本。为了更好的介绍这个过程,下表展示了一个分四类的小样本集数字表格:
上图3检验了猫科类与模糊样本。此外,由于一个样本可能与多类问题相关,所以,最后的百分比加起来可能不是100%。
你可能首先构想类别(狗,猫科,模糊),然后手工分类,实际上一旦你过一遍样本,你会有新错误类别的想法。例如Instagram类别在你利用Intagram滤波器复原并复原原图上会十分有用。但是你也没必要将自己限制在你知道如何解决的错误类别范围内。这个过程的目标是建立你自己需要专注领域的直觉。
误差分析是一个迭代的问题。不用担心刚开始的时候没有类别的概念。看过一些图片之后,你可能就会有一些类别的想法。在手工分类过一些样本后,你可能会有一些新类别的想法,再回去检查之前看过的样本。
假设你完成了100张误分类验证集样本的误差分析,得到下表:
你现在知道了进行一个处理狗误分类项目可以最多降低8%错误率。处理猫科类或者模糊样本可以降低更多。因此,你可以挑一到两个类别来关注。如果你的团队有足够的人手来多个方向并行工作,你可以让一些工程师解决猫科动物误检问题,其他的解决模糊图片问题。
误差分析不会产生一个严格的公式告诉你那个任务的优先级更高。你还需要考虑每个误差类别上你希望进展的程度以及需要花费的工作量。
在误差分析过程中,你可能注意到你的验证集中有些样本标错了。这里说的误标注指的是样本在分类器分类之前已经被人工错误的标注了,就像样本(x,y)中y的类别标签不对。例如,可能有些没有猫的图片误标记成包含猫的,反之亦然。如果你怀疑误标记样本的比例很大,在表格中新增一类来跟踪被误标的样本。
你是否需要校验你的验证集标签?记住验证集是为了帮助你快速评估算法性能,让你更好的分辨算法A还是B更好。如果验证集的错误率大到影响你的判断,那么是值得花时间去纠正那些误标的样本。
例如,假设你的分类器表现如下:
这里,相对于94%的你可以改进的错误率,0.6%的由于误标记产生的错误并不足够严重。人工纠正验证集中误标定的图像并没有什么坏处,但是这个需求并不紧急:是否区分10%或者9.4%的系统整体错误率并不会有什么影响。
假设你持续优化猫分类器,达到了以下表现:
30%的错误是由于验证集误标记导致的,给你准确率评估新增了重大的影响。这时候优化验证集标注的质量就很有意义了。解决样本误标注的问题会帮助你搞清楚分类器的误差率是1.4%还是2%,这是个很大的相对偏差。
刚开始的时候在验证集或者测试集中有误标记样本是可以接受的,当你的系统优化到误标记样本影响整体错误率的时候再去优化验证集与测试集。
最后一章解释了你该如何通过算法改进优化像狗、猫科与模糊图片这样的错误类别。你在本章也学会了如何通过改进数据标注来优化误标记类别。
无论你使用什么方式来优化验证集标签,记住同样应用到测试集标签上,这样你的验证集与测试集会继续服从同一分布。同时优化验证集与测试集可以防止第六章中提到的问题,防止你的团队优化验证集的准确率最后发现测试集的标准不一致。
如果你决定优化标注质量,可以考虑反复检查系统误分类的样本与正确分类的样本。无论是原本标签或者是你的算法都有可能出现错误。如果你有1000张验证集样本,如果你的分类器有98%的准确率,检查20张误分类的样本会比检查980张正确分类的样本简单的多。由于实际上检查误分类样本会容易的多,偏差会分不到一些验证集中。这些偏差如果你是要开发一个产品或者应用是可以接受的,但是如果你要发表一篇学术研究论文或者需要测试集完整无偏差的准确率评估,这些偏差是无法接受的。
假设你有5000张验证集样本,20%的错误率。因此,你的算法误分了1000张验证集图片。人工检查1000张图片需要很长时间,所以我们决定在误差分析的时候不全部使用它们。
本例中,我们明确将验证集分为两个子集,一个我们进行分析,另外一个不进行分析。你将迅速的过拟合你人工分析的那个子集。你可以用不人工分析的那个子集来微调参数。
我们继续上述的例子,算法从5000张验证集样本中误分类了1000张。假设你希望人工分析其中的100张进行误差分析(10%误分样本)。你需要随机从验证集中选择10%,放到一个我们叫做“EyeBall”验证集的文件夹中提醒我们需要人工审核(对于语音识别项目来说,我们需要听音频片段,我们可以叫做“Ear”验证集)。“Eyeball”验证集因此有500张样本,我们期望算法分错100张。
验证集的第二个子集我们称作“Blackbox”验证集,会有4500张样本。你可以用黑盒验证集通过计算错误率来自动评估分类器效果。你也可以用来选择算法或者超参数。然而你需要避免人工查看样本集。我们使用黑盒子这个词是因为我们只会用这个子集对分类前保持黑盒子评估。
为什么我们将验证集明确的分为白盒子与黑盒子两个子集?由于我们会从白盒子验证集中得到分析结果,然后快速过拟合它。如果你发现白盒子验证集优化的速度远远高于黑盒子验证集,你可能已经过拟合了白盒子验证集。本例中,你可能需要放弃这个验证集并且通过将黑盒子验证集中的数据新增到白盒子子集中的方式或者新标注数据的方式新建白盒子验证集。
明确的将验证集分为白盒子与黑盒子验证集使得你可以发现你的人工误差分析过程过拟合了你的白盒子部分数据。
你的白盒子验证集需要足够大到你的算法可以让你了解误差类型。如果你在研发一个人工可以很好识别的项目(从图片中识别猫),下面有些简单的引导:
建设你的分类器有5%的错误率。为了保证你的白盒子验证集中有100误标样本,你的白盒子验证集需要有至少2000张样本(0.05*2000=100)。你的白盒子验证集错误率越低,你的白盒子验证集需要越大以保证得到足够的样本来进行错误分析。
如果你在进行一个人工都很难处理好的项目,那么白盒子验证集的检查由于根本无法判断算法为什么没有分类成功而没什么用。这种情况下,你可以省略白盒子验证集。我们在下一章会讨论这类问题的解决方法。
黑盒子验证集怎么样?我们之前说过通常验证集大小在1000-10000样本。为了完善上述表达,一个1000-10000张样本的黑盒子验证集通常会给你提供足够的数据还微调超参数并选择魔心。尽管更多的样本也没有什么坏处。一个100大小的黑盒子验证集尽管小但也是有用的。
在白盒子与黑盒子验证集中,我认为白盒子验证集更重要(假设你在进行一个人工可以很好解决并从误差分析中获取思路的任务)。如果你只有白盒子验证集,你可以进行误差分析,模型选择,超参数调整。白盒子验证集不好的一面是你可能有更大的风险过拟合这个验证集。
如果你有大量的数据资源,白盒子验证集的大小取决与你有多少时间可以投入到样本分析中。例如,我很少见过有人人工分析超过1000样本。
假设你的训练集,验证集与测试集都服从同一分部。那么你需要持续新增训练数据,这样可以改进算法效果。
尽管更多训练数据不会有什么坏处,但是新增数据也不是总与你想的那样那么有用。不断新增数据也有可能是浪费时间。那么怎么决定何时新增数据,何时不必新增数据。
机器学习中有两类主要的误差来源:偏差与方差。了解偏差与方差,有助于你决定什么时候新增数据或者使用其他策略,有利于提升效率。
假设你希望构建一个错误率为5%的猫分类器。当前我们训练集的错误率为15%,你的验证集错误率为16%。这种情况下,新增更多的数据应该没有用。你需要关注其它方面。实际上,新增更多样本到训练集中使得算法对训练集的优化变得更复杂。(我们将在下一章解释这个问题)。
如果你在训练集上的错误率是15%(或者85%的准确率),但目标错误率是5%(95%的正确率),那么首当其冲的问题是优化你的算法在训练集上的表现。如果你在你算法训练的样本上只有85%的准确率,那么没可能在其他样本集上得到95%的准确率。
就像上面的例子那样,假设你算法在验证集上的错误率为16%(84%的准确率)。我们将16%的错误样本分为两个组成部分:
有些方法可以优化学习算法在第一类误差上的表现,改进在训练集上的准确率。有些方法可以解决第二类问题,改进在验证集或者测试集上的表现。[7]为了选择最合适的方式,明白两类问题中哪个更急迫的需要解决十分重要。
培养好的偏差与方差的直觉对于算法优化来说十分重要。
假设你还在进行猫分类任务。理想的分类器(例如人眼)可能在这个任务上达到近乎完美的表现。
假设你的算法表现如下:
这个模型问题在哪里?应用上一章的定义,我们估计偏差为1%,方差为10%(=11%-1%)。因此属于高方差率(high variance)。分类器的训练误差很小,但在验证集上的鲁棒性不强。这也被称为过拟合(overfitting)。
现在假设:
我们估计偏差为15%,方差为1%。这个分类器对训练集拟合的不好,有15%的错误率,但是在验证集上的错误率仅仅比测试集上高了一点点。这个分类器情况被称为高偏差(high bias),但低方差。我们称算法欠拟合(underfitting)。
现在假设:
我们估计偏差为15%,方差为15%。这个分类器输入高偏差且高方差:由于在训练集上表现不好所以高偏差;在测试集上表现更差,所以搞方差。过拟合与欠拟合这样的术语在这种情况下很难用于描述这个既过拟合又欠拟合的分类器。
最后假设:
这个分类器的表现很好,具有低偏差,低方差。恭喜你得到了理想的模型。
在猫识别例子中,理想的错误率是指最优的分类器达到近乎0%错误率的水平。人类在看到包含猫的图片每次都可以识别对,因此我们希望机器也可以达到这样的水平。
有些问题更复杂。例如,你建立一个语音识别系统,14%的语音片段都掺杂着大量噪声,或者即使人类人无法听明白其中的内容。本例中,即使最优的语音识别系统也会有14%的错误率。
在这个语音识别问题中,假设你的算法达到了:
训练集上基本达到了最优错误率14%。因此,没有多少空间来优化偏差或者优化训练集上的表现了。然而,算法在验证集上不够鲁棒,因此有足够的空间可以来优化方差导致的误差曲线。
本例与上一章的第三个例子有相似之处,也是有15%的训练错误率与30%的验证错误率。如果最优的错误率是0%,训练错误率达到15%的时候就有很大的优化空间。这种情况下减少偏差率是非常有效的。但是如果理想误差率是14%,那么同样的训练集误差率告诉我们已经没有多少空间来改善分类器的偏差率了。
对于最优误差率远大于0的情形,这里进行一个算法误差的详细分解。继续上述的语音识别的例子,整体30%的验证集误差可以分解成以下几个部分(同样的思路也可以应用到测试集误差上):
为了关联我们之前的定义,偏差与可避免偏差通过以下公式关联:[9]
Bias = Optimal error rate(“unavoidable bias”) + Avoidabel bias
可避免偏差率反映了你的算法在训练集上表现比理想分类器错误率差了多少。
方差的概念与之前一致。理论上说,我们总是可以通过在一个大量集训练集上训练达到几乎方差为零的模型。因此,所有的方差在足够大的数据集上都是可以避免的,所以不会有无法避免的方差这种概念。
举多一个例子,假设理想错误率为14%:
上一章里我们称这种情况为高偏差率,现在我们将这种情况称作可避免的偏差导致的错误率为1%,方差是1%。因此,算法已经表现的很好了,只有很小的优化空间。比起理想错误率只有2%的优化空间。
我们从这些例子中可以看出来理想错误率对引导下一步的优化方向十分重要。统计学中,理想错误率也被称作贝叶斯错误率(Bayes error rate)或者贝叶斯率。
那么我们怎样才能知道最优错误率呢?对于人类可以分别的,例如图片识别或者语音片段转译,你可以用训练集的人工标注精度来衡量。这可以提供理想错误率的估计。如果你在处理即使是人也很难解决的问题(例如预测推荐哪部电影或者给用户展示哪些广告),估计理想错误率比较困难。
在章节“Comparing to Human-Level Performance(33到35章)”,我会更详细的讨论如何将学习算法的表现与人类的表现对比。
在最后几个章节里,你会学习如何通过观察训练与验证集错误率来估计可避免/不可避免偏差与方差。下一章会讨论如何应用这些分析的结果来区分优化偏差与方差技术的优先级。对于你项目中高可避免偏差或者高方差会有不同的技术来处理。请继续阅读!
这里展示解决偏差问题与方差问题最简单的公式:
如果你可以无限新增网络模型的大小并且新增数据到训练集,许多学习问题会迎刃而解。
实际上,增加模型的尺寸会最终导致你陷入计算量问题中,因为训练大模型是非常慢的。获得更多的训练数据也会让你筋疲力尽。(即使是网络上也只有有限的猫样本)。
不同的模型架构,例如,不同的神经网络结构会在解决你的问题时产生不同的偏差/方差。当前许多深度学习的研究研发出了许多先进的模型结构。所以如果你使用神经网络,学术论文是很好的灵感来源。在github上有许多伟大的开源实现。但是尝试新结构的结果比起新增网络尺寸与训练集大小的简单公式来说会有更多的不确定性。
增加模型的尺寸会最终解决偏差问题,但它也可能增加方差,导致过拟合问题。然而,这些过拟合风险只会在你没有使用正则化的时候增加。如果你的方法中包含了精心设计的正则化方法,那么你就可以无需考虑过拟合风险安全的增加模型的尺寸了。
假设你使用深度学习的方法,使用L2正则化或者dropout的方式,这些正则化参数在验证集上表现的最好。如果你增加模型尺寸,通常模型的效果会保持不变或者变好,基本不可能会明显变差。不使用大尺寸模型的唯一原因是增加的计算量花销。
你可能听说过偏差与方差权衡的说法。大多数学习算法中的改变有些会降低偏差率,但是增加方差,反之亦然。这就产生了偏差与方差权衡的问题。
例如,增加模型尺寸,给神经网络增加神经元或者层,或者增加输入特征,通常可以降低偏差但导致方差。或者增加正则项通常会增加偏差但却降低方差。
在如今,我们通常使用大量的数据并且使用非常大的神经网络(深度学习)。因此,权衡变得更少了,我们有更多降低偏差并且不影响方差的选项,反之亦然。
例如,通常你可以增加神经网络的尺寸,调整正则化方法来在不显著增加方差的情况下降低偏差。通过增加训练数据,你也可以在不影响偏差的情况下降低方差。
如果你为你的任务选择了合适的模型结构,你也可能可以同时降低偏差与方差。算法合适的模型结构可能会比较有难度。
在接下来的几个章节中,我们会讨论更多的解决偏差与方差的技术。
如果你的学习算法深受高可避免偏差的影响,你可以尝试以下技术:
一个可能不那么有效的方法:
你的算法在你期望它可以在验证集或者测试集上表现良好之前必须在训练集上表现良好。
除了之前解决高偏差问题方法之外,我有时也会对训练数据进行误差分析,遵循与白盒子验证集上误差分析相似的规则。这种方式在你算法有高偏差率的时候非常有效,例如模型对训练数据拟合的不好。
例如,假设你为你的app建立一个语音识别系统,已经收集了许多志愿者的语音片段。如果你的系统在训练集上表现的不好,你可以考虑听100个算法表现不好的训练集片段来了解训练集错误主要是那些类别的问题。与验证集误差分析一致,你可以将错误统计为不同类别:
本例中,你可能发现当训练样本中包含较多背景声音的时候算法处理效果不好。因此,你可以更管制那些可以让模型更好拟合包含背景噪声训练样本的技术。
你再次确认人是否可以正确理解这些输入到算法中的音频片段。如果背景噪声达到没人可以听出音频里在说什么,那么也就没有道理要求算法正确的识别这样的说话方式。我们会在接下来的章节中讨论将算法与人工表现比较的好处。
如果你的算法存在高方差问题,你可以尝试一下技术:
这里还列出了其他两种与前一章解决偏差问题重复的策略:
我们展示了一些方式来评估多少误差可以归咎于可避免偏差或者方差。我们通过估计理想错误率并计算算法在训练集与验证集上的错误率来评估。我们来讨论一个信息量更大的技术:画学习曲线。
学习曲线画出了验证集误差对比训练集样本个数。画误差曲线需要你的算法跑在不同大小的训练集上。例如,如果你有1000个样本,你在分别在100,200,300,…,1000样本量的样本集上训练算法。之后画出不同训练集大小下验证集错的误差。如下图所示:
随着训练集大小的增长,验证集的错误率应该下降。
我们通常希望算法最终能达到期望错误率。例如:
将期望的效果加到学习曲线中:
你可以直观的通过红色的验证集误差曲线推断出通过添加数据你的效果离理想值差多少。上述例子中看起来加倍训练集的大小可能可以达到理想效果。
但是如果验证集误差曲线出现了平稳的趋势,那么你可以立马判断出新增更多的数据可能达不到你想要的效果:
通过研究学习曲线可以帮补你避免花费几个月的时间收集两倍的数据到头来却发现没啥作用。
这个方法的缺点是如果你仅仅关注验证集误差曲线,你很难推断或者预测如果你有更多的数据红色的曲线的走势会是什么样的。还又另外一个曲线可以帮助你评估新增更多数据的影响:训练错误率。
验证集(与测试集误差)会随着训练集大小增长下降。但是训练集误差通常会随之增长。
我们用一个例子来说明上面的现象。假设训练集只有两个样本,一个是猫图片,一个是非猫图片。对于学习算法来说,很容易记住训练集中的这两个样本,达到0%训练集误差率。及时其中一个甚至两个训练样本被误标记了,对于算法来说还是很容易记住两个的标签。
现在假设你的训练集有100个样本。也有有些样本被误标记了或者模糊(有些样本模糊到人眼都无法分辨是不是有一只猫)。或许学习算法还是可以记住大多数或者全部的训练样本,但是想保持100%的准确率变难了。通过将训练集从2张增加到100张,你会发现训练集准确率会有些许下降。
最后,假设你有10000张样本的训练集。本例中,算法想要完美的过拟合10000张样本变得更难了,特别是如果有些样本是误标的或者模糊的。因此,学习算法会在训练集上表现更差。
我们将训练误差画到之前的图表上:
可以发现,蓝色的训练误差曲线随着训练集大小的增加而增加。此外,算法通常在训练集上的效果比验证集好;因此红色的曲线通常在蓝色训练误差曲线上方。
我们接下来讨论如何解析这些曲线。
假设验证集误差曲线如下:
我们之前说过,如果你的验证集误差曲线变得平坦,通过新增数据可能难以达到期望的效果。
但是很难推断出红色的验证集误差曲线会怎样变化。如果验证集很小,结果会由于曲线的噪声变得更不确定。
假设我们将训练误差虚线添加到图表中,得到以下曲线:
这样,你可以百分之百确定仅仅新增数据是没用的。为什么这么说?请记住如下我们的两点观察:
在同一个图表中同时分析验证集误差曲线与训练集误差曲线使我们对验证集曲线的发展确实的分析更有依据。
假设,期望的表现就是我们对理想误差率的估计。上述的图表示典型的包含高可避免偏差的学习曲线:在训练集最大的时候(假设对于我们所有的训练数据来说)在训练误差与期望表现中有巨大的空隙,这预示着算法有大量的可避免偏差。此外,训练与验证集误差曲线间的间隙很小,预示着方差很小。
之前我们通过对应所有训练样本的图中最右边的点来评估训练与验证集误差。画完整的学习曲线让我们对算法在不同大小训练集的表现有一个更综合的了解。
假设学习曲线如下:
上述的图表预示着什么,高偏差,高方差还是两者都有?
蓝色的训练误差曲线相对较低,红色的验证集曲线比蓝色的训练集误差要高的多。因此,偏差很小,但是方差很大。新增更多的训练数据可能会使得验证集误差与训练集误差间的间隙变小。
现在考虑这种情况:
这次,训练误差很大,比期望的表现高的多。验证集的误差比训练集误差高得多。因此,你的偏差与方差都很高。你需要找到一种可以同时降低算法偏差与方差的方式。
假设你有一个只有100个样本的很小的训练集。你分别用随机的子集以10为跨度,10张样本的,20张样本,30张样本,到100张来训练算法。之后利用10点数据来画学习曲线。你可能发现在训练集较小的时候曲线看起来有些噪声(意思是值比期望高或低)。
当使用10张随机选择的样本的时候,可能不幸的训练集不太好,例如许多模糊或者误标注的样本。或者你可能相当幸运的有一个相当好的训练集。小数据集意味着验证集与训练集误差可能会随机波动。
如果你的机器学习应用严重的向一类偏斜(例如猫分类器中负样本数远远大于正样本数)或者有很多类别(例如识别100种动物物种),那么选择出不具有代表性或者不好的训练集的概率会变得更高。例如,如果你的样本中80%是负样本(y=0),20%是正样本(y=1),那么很有可能10张样本的样本集只有负样本,这样使得算法很难学到有效的信息。
如果噪声使得训练曲线很难看出真实的趋势,这里有两个解决方案:
如果不是样本噪声过大你尝试了无法看出学习曲线的趋势的话,我不会使用上述两种方法。如果你的训练集很大(假设多于10000张样本),你的类别分布并没与那么偏向性,你应该也不需要这些技术。
最后,绘制学习曲线可能会耗费大量算力:例如,你可能需要用1000到2000张训练十个模型,总共用了10000张样本。利用小数据集训练模型比利用大数据训练模型快的多。因此,比起直接将样本集线性的划分上述大小,不如用1000、2000、4000、6000这样的大小的数据集训练模型。当然,这个技术只有在花费大量算力训练这些多出的模型是有用的情况下才会用到。
学习机器学习系统旨在将人类可以处理的很好的事情自动化。典型的例子包括图像识别,语音识别,垃圾邮件分类等。学习算法发展的越来越好,在越来越多的任务中超越了人类的表现。
此外,还有一些构建人类处理很好的机器学习系统会相对容易的原因:
尽管第三点看起来没那么重要,我发现一个合理并且可以达到的目标误差率可以帮助团队加快进度。知道你的算法有高的可避免误差率相当的重要,就像打开了一个写满可以尝试方法的列表。
还有些任务就算人类也不擅长。例如, 调一本书推荐给你;或者挑一个网页广告展现给用户;或者预计股市走向。电脑在这些任务上已经超过了大多数人表现。这些应用中我们遇到了下列的问题:
假设你正在进行X线图片的自动诊断引用系统的开发工作。一般没有医学背景但是经过基本训练的人的误差率可以达到15%。初级医生可以达到10%的误差率。资深医生可以到5%。一组医生团队经过讨论后误差率可以达到2%。以上的这些误差率那个可以定义成人类级别的表现?
本例中,我会用2%作为最佳误差率的值。根据上一章提到的所有三个与人类级别表现比较的理由,你可以将2%设置成期望表现的水准:
在进行数据标注的时候,你不可能每张图片都跟医生团队讨论,因为他们时间宝贵。你可能可以雇佣一个初级医生来标注绝大多数样本,再将少数疑难样本交个资深医生或者医生团队来标注。
如果你的系统当前的误差率是40&,无论你用初级医生(10%误差率)或者资深医生(5%误差率)来标注数据并提供指导都没有什么影响。但是如果你的系统以及达到了10%的误差率,那么将人类界别的参考值设置为2%会让你更好的优化你的系统。
你在进行语音识别系统的开发,有一个语音片段的数据集。假设你的数据集噪声很大,以至人类也只能达到10%的误差率。假设你的系统误差率已经是8%了,你是否还可以利用33章描述的技术取得快速的进步呢?
如果你还是可以找到一个子集,在这个子集上人类的表现显著的超过了你的系统,那么你还是可以利用那些技术来驱动快速进步。例如,如果你的系统比人类在高噪声的样本中表现要好得多,但是人类在语速较快的片段中表现更好。
对于高语速的样本子集来说:
总而言之,只要你的验证集中还有人类可以正确识别但算法识别失败的样本,那么很多之前描述过的技术还是可以使用的。这个说法即便在整个验证集或者测试集的评价误差率已经低过人类级别的表现时也是成立的。
有许多机器学习的应用都超过了人类级别的表现。例如,机器可以更好的预测电影评级,预测驾驶车辆到一个地方需要花费多少时间,或者判断是否允许借出贷款。在人类难以识别算法明显识别失败的样本的时候才会使用小部分技术。因此,当机器已经达到人类级别的表现时进展会变慢,当机器还在努力追上人类级别的表现时进展会比较快。
你的猫图片应用长传了10000张图片,你手工的标注了是否包含猫。你还有一个200000张图片大小的从网络下载下来的大数据集。你该如何定义训练集、验证集与测试集?
由于10000张用户上传的样本实际反映了你希望处理好情形的样本分布,你可能希望用它们来进行验证与测试。如果你在训练一个数据驱动型的深度学习算法,你可能用200000网络图片来训练。因此,你的训练集与验证集、测试集的样本分布不同。这会如何影响你的工作?
我们可以将210000张样本都用上,随机从其中分成训练集、验证集与测试集,而不是直接分为训练集、验证集与测试集。这样所有的数据就会来自同一分布。然而我不推荐使用这样的方式,因为这样的话205000/210000≈97.6%的验证与测试数据会来自网络,并没有体现出实际的分布。请记住我们对验证集与测试集的选择建议:
选择的验证集与测试集要可以反映未来实际应用中的场景。
机器学习的大多数学术论文都假设训练集、验证集与测试集服从同一分布。[10]机器学习的早期数据量很少。我们通常只有一个来自可能分布的数据集。所以随机将它们分为训练集、验证集与测试集,并且假设所有的数据会通常来自同一个分布。
但是在大数据时代,我们如今又大量的训练数据,例如猫的网络图片。即使训练数据来自与验证测试集不同的分布,我们还是想利用他们来进行学习,因为它们可以提供很多信息。
对于猫检测的例子来说,我们会将10000张用户上传样本中的5000张而不是所有样本放入验证与测试集中。我们可以将剩下的5000张样本放到训练集中。这样,你的205000张样本的训练集包含了一部分来自你验证测试集分布的样本与200000张网络样本。我们会在后面章节中讨论为什么这样有用。
让我们讨论第二个例子。假设你在建立一个语音识别系统来给语音控制应用或者导航应用提供门牌号的转译。你有20000个用户说门牌号的样本。但是你还有500000个用户谈论其他内容的语音片段。你可以将10000个门牌号样本放到验证与测试集中,剩下的10000个样本加到500000样本中作为训练集。
我们继续假设你验证集与测试集来自同一分布。但是要理解不同的训练集与验证测试集分布会带来一些特别的挑战。
假设你的猫检测器训练集包含10000张用户上传的图片。这些数据与独立的验证测试集服从同一分布,代表了你关注并且需要性能好的分布。你还有其他的20000张网络样本。你是否需要将20000+10000=30000张所有的样本作为学习算法的训练集,或者放弃20000张网络样本因为担心他们会影响你的学习算法?
当使用早期的学习算法(例如手工设计计算机视觉特征与简单的线性分类器)将两个类型的数据合并在一起的确会有效果很差的风险。因此,有些工程师会警告你不要使用20000张网络样本。
但是对当前功能强大且灵活的学习算法来说,例如大规模神经网络,这种风险很大程度上被削减了。如果你可以建立一个包含足够多隐藏单元或者层的神经网络,你可以安心的将20000张网络图片加到你的训练集中去。增加这些数据更有可能会优化你的效果。
这种观察依据有一些x->y的映射会对两种数据类型都表现很好的现实。换句话说,存在一种系统可以在不知道图片数据源的情形下,无论输入网络图片或者移动端图片都可以可靠的预测标签。
增加额外的20000张样本会有以下影响:
为了用另外一种方式描述第二种情形,我们引用夏洛克福尔摩斯小说中的章节,里面说到你的大脑就像一个容量有限的情报中心。他说,每次获得额外的知识,你会忘记一些你之前知道的知识。因此不要将无用的知识替代有用的知识就相当的重要了。[11]
幸运的是,如果你拥有足够的计算能力来构建一个足够大的神经网络,就像一个足够大的情报中心,那么这就没什么可担心的了。你有足够的能力来同时从网络样本与移动端样本进行学习,而且两种不同类型的数据不回去竞争网络容量。你的算法大脑容量足够的大,使得你不必去为空间不够而担心。
但是如果你没有一个足够大的神经网络(或者其它高灵活性的学习算法),那么你需要话更多的精力在你的训练数据需要匹配你的验证与测试集分布上。
如果你认为你有没有用的数据,你最好出于算力的原因抛弃这些数据。例如,假设你的验证测试集中包含主要是随机的人、宫殿、地标、动物的样本。假设你还有一大批历史文档的扫描件:
这些文档不包含任何与猫相关的信息。他们也看起来根本没有任何与你验证测试集分布。没有任何将这些数据作为负样本的意义,因为从这些数据中获得的第一条受益是微不足道的,你的神经网络基本上学不到任何可以应用到你的验证测试集分布上的东西。并且他们会浪费计算资源与神经网络的表达能力。
[1] 此图展示了神经网络在小数据集的情形下表现更好。这种现象与神经网络在大数据情形下的表现不连续。在小数据集场景,传统算法的效果依赖手工特征的设计,可能表现好或不好。例如,如果你有你只有20张样本,可能无论用逻辑回归或者神经网络都没什么影响;手工特征的影响大于不同算法选择的影响。但是,如果你有100万样本,我会选择神经网络。
[2] 理论上说,在算法有一个显著的统计学改变的时候也可以进行验证集上的测试。实际上,大多数团队并不会纠结这个(除非他们准备发布学术研究论文)。我没有发现测试显著的统计学改变的算法中间过程测试有什么用处。
[3] 猫分类器的准确率定义成验证集(测试集)上分成猫的是标记成猫的样本百分比。召回率是指整个验证集(测试集)中所有猫样本别识别成猫的比例。在高准确率与高召回率间通常需要权衡。
[4] 如果你希望了解更多F1得分,可访问https://en.wikipedia.org/wiki/F1_score。F1得分是准确率与召回率的调和平均(harmonic mean),可由2/((1/Precision)+(1/Recall))计算出来。
[5] 这个建议是给那些希望建立AI应用的读者的,而不是那些希望发表学术论文的读者。我后续会回到学术研究主题上。
[6] 在统计学上对偏差与方差有更正式的定义,但是我们不必关注。简单的来说偏差是指当你有一个相当大的训练集时,你的算法在这个训练集上的错误率。偏差是指同样的参数下,你算法在验证集上的准确率比训练集上差多少。当你误差丈量标准是均方误差的时候,你可以用一个公式表示这两种指标,Total Error=Bias+Variance。但是当我们的目标是寻找解决ML问题的方向的时候,一个不那么严谨的偏差与方差的定义就足够了。
[7] 也有些方法可以同时改进偏差与方差问题,比如通过修改系统构架。但这些很难被定义与实现。
[8] 如果这个值是负的,也就是说你在训练集上的错误率低于理想错误率。这表示你在训练集上过拟合了,算法过度理解了训练集。比起减少偏差方法,你需要更关注方差的问题。
[9] 这个定义选来用于表达如何优化你的学习算法的方式。这个定义不同于偏差与方差的统计学定义。技术上说,此处定义的偏差是指由于偏差导致的误差,可避免偏差指的是学习算法导致的高于理想错误率的部分。
[10] 也有一些学术论文研究训练与测试在不同分布的情形。例子包括“domain adaptation”、“transfer learning”与“multitask learning”。但是理论与实践中还是有很大的差距。如果你在数据集A上训练,然后在一个差异很大的数据集B上测试,你算法的表现会很大程度上由运气决定。(这里的运气包括研究着为特定任务手动设计的特征与其它你暂时难以理解的事实。)这使得关于在不同数据集上训练与测试的学术研究很难成体系。
[11] 阿瑟·柯南·道尔的《血色研究》