Andrew Ng
目录
- 为什么需要机器学习策略
- 如何使用这本书来帮助你的团队
- 预备知识和符号约定
- 规模促进了机器学习的发展
- 你的开发集和测试集
- 你的开发集和测试机应该来自同一分布
- 开发集和测试集多大合适
- 为你的团队进行算法优化建立一个单一数字的评估指标
- 优化指标和满足指标
- 有一个开发集和评估指标来加速迭代
- When to change dev/test sets and metrics 何时更改开发/测试集和评估指标
- Takeaways: Setting up development and test sets 小结:建立开发集和测试集
- Build your first system quickly, then iterate
- Error analysis: Look at dev set examples to evaluate ideas 错误分析:查看开发集样本来评估idea
- Evaluate multiple ideas in parallel during error analysis 错误分析时并行评估多个想法
- If you have a large dev set, split it into two subsets, only one of which you look at
- How big should the Eyeball and Blackbox dev sets be?
- Takeaways: Basic error analysis
- Bias and Variance: The two big sources of error
- Examples of Bias and Variance
- Comparing to the optimal error rate
- Addressing Bias and Variance
- Bias vs. Variance tradeoff
- Techniques for reducing avoidable bias
- Techniques for reducing Variance
- Error analysis on the training set
- Diagnosing bias and variance: Learning curves
- Plotting training error
- Interpreting learning curves: High bias
- Interpreting learning curves: Other cases
- Plotting learning curves
- Why we compare to human-level performance
- How to define human-level performance
- Surpassing human-level performance
- Why train and test on different distributions
- Whether to use all your data
- Whether to include inconsistent data
- Weighting data
- Generalizing from the training set to the dev set
- Addressing Bias and Variance
- Addressing data mismatch
- Artificial data synthesis
- The Optimization Verification test
- General form of Optimization Verification test
- Reinforcement learning example
- The rise of end-to-end learning
- More end-to-end learning examples
- Pros and cons of end-to-end learning
- Learned sub-components
- Directly learning rich outputs
- Error Analysis by Parts
- Beyond supervised learning: What’s next?
- Building a superhero team - Get your teammates to read this
- Big picture
- Credits
- 为什么需要机器学习策略
机器学习是很多重要应用的基础,例如网页搜索,反垃圾邮件,语音识别等。如果你或你的团队正在开发一个有关机器学习的应用,并且你想要获得快速地进步。这本书将会帮助到你。示例:建立一个识别含有猫的图片的创业公司,也就是说你建立了一个创业公司,为猫爱好者提供无尽的猫的图片。你打算使用一个神经网络建立一个计算机视觉系统来检测图片中的猫。
但悲催的是,你的学习算法的准确率目前并不够好。所以你面临巨大的压力来改善你的算法。你该做些什么呢?你的团队有很多idea,比如:
- 获取更多数据:收集更多关于猫的图片
- 收集更多样化的训练集。例如:猫在不同位置的图片;不同着色的猫;不同相机(设置)拍摄的图片
- 通过运行更多的梯度下降迭代次数,来增长训练算法的时间
- 尝试更大的网络,具有更多的层,更多的隐藏单元及参数
- 尝试更小的网络
- 尝试添加正则化(例如L2正则化)
- 改变神经网络的架构(激活函数,隐藏单元的数量等)
……
在这些可能的方案中,如果你选择的好,那么你将建立一个领先的关于猫的图片的平台,并带领你的公司走向成功;如果你的选择很糟糕,那么你可能白白浪费几个月的时间。你会选择怎么进行?这本书将会告诉你怎么去做。大部分机器学习问题都会留下一些线索,这些线索会告诉你什么是有用的尝试,什么是没用的。学会阅读理解这些线索能够节省你数月或上年的开发时间
2. 如何使用这本书来帮助你的团队
在读完这本书后,你将对如何制定机器学习项目中的技术方向有一个深入的了解。
但是你的队友可能并不理解你为什么建议某一个特定的方向。或许你希望你的团队定义一个单一数字的评估指标,但他们却并不信服。你如何说服他们?
这就是为什么我把章节设置的这么短:这样你可以打印出来并给你的队友看仅仅你想要让他们知道的那1~2页。面对几个不同的选择,在优先次序上的一些改变可能会对你团队生产力产生巨大的影响。通过帮助您的团队做出这样一些改变,我希望你能够变成你们团队的超级英雄!
5.你的开发集和测试集
让我们回到之前关于猫的图片的例子:你制作了一个移动APP,用户可以上传很多不同事物的图片到你的app上,你想要自动发现关于猫的图片。你的团队从不同的网站下载大量猫(正样本,positive examples)和非猫(负样本,negative example)的图片,从而获得了一个很大的数据集。他们将这些数据按 70%:30%分为训练集和测试集。利用这些数据,他们构建了一个猫的检测算法,它在训练集和测试集上表现都很好。但是当你把这个分类器部署倒移动APP上时,你发现它的表现非常糟糕!
发生了什么?
你发现用户上传的图片和你从网站下载的作为训练集的图片有些不同:用户使用手机拍摄的图片分辨率更低,模糊,且照明效果较差。由于你的训练集和测试机数据都来自于网站图片,你的算法没有在你所关心的智能手机图片的实际分布上一般化得很好。大数据时代之前,在机器学习中人们常使用随机的70%:30%分割训练集和测试集。这种做法能够work,但是在越来越多的应用(在这些应用中,训练集的分布(在我们的例子中的网站图像)不同于你最终关心的分布(手机拍摄的图像))中是个坏主意。
我们通常定义:
- 训练集(Training set)——你运行你的算法在这上面。
- 开发集(Dev/development set)——这部分数据用来调参,选择特征,以及对学习算法做出其他决定。有时也被称为留出交叉验证机(hold-out cross validation set)
- 测试集(Test set)——这部分数据用来评估算法的性能,但不要依靠这部分数据对使用的学习和参数做出任何决定。
一旦你定义一个开发集(Dev/development set)和测试集(Test set),你的团队将尝试各种idea(例如不同的学习算法参数),看哪一种最好。开发集和测试集能够使你的团队快速看到你的算法做得有多好。换句话说,开发集和测试集的目的是指导你的团队对机器学习系统做出最重要的改变。
所以你应该做到:
选择开发集和测试集,以反映你期望在未来获得的数据,并希望在上面做得很好。换句话说,你的测试集不应该只是可用数据的30%这么简单,特别是当你期望得到的数据(移动app的图像)和你的训练数据(网页图像)在性质上不太一样时。如果你尚未发布你的app,也就意味着还没有任何用户,因此可能无法获得你未来想要做得很好的数据。但是你仍然可以尝试去接近这一点。例如,请你的朋友拍一些手机照片并发给你。一旦你的app启动后,你可以使用用户的实际数据更新你的开发/测试集。如果你真的没有任何方法获取接近你期望的数据,也许你可以使用网站图片作为开始。但是你应该清醒地意识到这种做法可能导致你的系统不能泛化的很好。有时可能我们需要决定投资多少去获取好的开发集和测试集。切记不要假定你的训练集分布和测试集分布必须是一样的。尝试去挑选能反映你最终想要表现很好的数据作为测试样本,而不是你遇到的任何数据。
6.你的开发集和测试机应该来自同一分布
根据你的市场,您将你的猫app的图片数据分为四个区域:美国、中国、印度和其他地区。要生成一个开发集和一个测试集,我们随机地分配两个地区的数据到开发集,另外两个到测试集,对吗?比如来自美国和印度的数据在开发集,中国和其他地区的在测试集。一旦你这样定义了开发集和测试集,你的团队将专注于提高开发集的表现性能。因此,开发集应该反映你真正想要提高性能的任务:在四个地区做得都好,而不只是两个。
开发集和测试集数据的分布不同导致的第二个问题是:你的团队可能会做出一些工作,在开发集上表现很好,在测试集却表现很差。我曾经在很多挫折和白费的努力中看到过这一结果。要避免这种情况发生在你身上。例如,假设你的团队开发的系统在开发集上表现很好,在测试集上却很糟糕。如果你的开发集和测试集来自同一分布,那么你会有一个非常明确的诊断:你的算法在开发集上过拟合了。显而易见的方法是去获得更多的开发集数据。
但如果你的开发集和测试集来自不同的分布,那么你的选择就不太清楚了。可能会出现以下几种错误:
- 你的算法在开发集上过拟合了。
- 测试集比开发集更难以识别。所以你的算法可能做的和预期的效果一样好了,因此也就没有可能做出进一步的显著改进了。
- 测试集不一定是比开发集更难,只是它们来自不同的分布。所以在开发集上表现很好的算法并不能在测试集上表现良好。这种情况下,你之前做的很多提高开发集表现性能的努力都白费了。
机器学习应用方面的工作已经很困难了。具有不匹配的开发集和测试集引入了额外的关于是否改进开发集分布或提高测试集表现性能的不确定性。这使得更难找出什么work和什么不work,因此更难以确定不错选择之间的优先级。如果你面对的是第三方基准测试(benchmark)的问题,它们的创造者可能已经指定了开发集和测试集来自不同的分布。这种情况下,运气,而非技能,将会对你的性能产生更大的影响。当然,开发那些能够在一个分布上训练并能很好地推广(generalize)到另一个分布的学习算法是一个很重要的研究方向。但如果你的目标是开发能够在特定机器学习应用中得到不错效果的系统的话,我建议你选择开发集和测试集服从同一分布。这将使您的团队更有效率。
7. 开发集和测试集多大合适?
开发集应该足够大,大到能检测出你尝试的不同算法之间的差异。例如,如果一个分类器A具有90.0%的准去率而分类器B具有90.1%的准确率,则只具有100个示例的开发集不能够检测出这0.1%的差异。与我看到的其他机器学习问题相比,100个样本的开发集很小。常见的开发集样本规模一般在1000到10000之间。在10000个样本的情况下,你将有更大的可能性检测到0.1%的性能提升。对于一些成熟和重要的应用程序(例如广告,网页搜索和产品推荐等),我也会看到一些团队在为甚至0.01%的性能提升而努力奋斗,因为它对公司的利润有直接影响。在这种情况下,开发集的数据量可以远大于10000,以便检测更小的改进。
那关于测试集的数据规模呢?它应该足够大,大到能对你的系统整体性能评估拥有一个很高的自信度。一个流行的启发式方法(heuristic)是将30%的数据用于测试。在你拥有一个中等数据量(100到10000个样本)的情况下,它work的很好。但是在大数据时代(现在我们面对的机器学习问题可能会有超过数10亿的样本),分配给开发/测试集的数据比例一直在减小,但是开发/测试集样本的绝对数量是在增长。在给开发/测试集分配数据时,没必要过多地超出其评估算法性能所需要的数据量。
8. 为你的团队进行算法优化建立一个单一数字的评估指标
分类准确率是单一数字评估指标的示例:你在开发集(或测试集)上运行运行一个分类器,然后得到一个正确分类的样本比例这样一个数字。根据给指标,如果分类器A获得97%的准确率,分类器B获得90%的准确率,则我们认为分类器A更好。相比之下,查准率(Precision)和查全率(Recall)就不是一个单一数字的评估指标:它给出了两个数字来评估你的分类器性能。具有多个数字 的评估指标使得比较算法更为困难。假设你的算法表现如下:
这里,两个分类器都没有显而易见地比另一个更优越,所以它不能马上引导你选择其中一个。
在开发期间,你的团队会尝试各种关于算法体系结构,模型参数,特征选择等方面的许多idea。使用单一数字的评估指标(single-number evaluation metric)(如精度),你可以根据其在这个指标上的效果快速对所有模型进行排序,从而快速决定哪一个work的最好。如果你真的同时关心查准率(Precision)和查全率(Recall),我建议你使用一种方法将它们组合为单一的数字。例如,可以取Precision和Recall的平均值,最终得到单个数字。或者,你可以计算“F1度量(F1 score)”,它是一种基于其平均值的改善的方法,比简单地取平均值效果要好。
当你面临在一大堆分类器中做出选择时,使用单一数字的评估指标可以加快你做出决策。它可以给出所有尝试的idea的明确的优先排名,从而给出一个清晰的前进方向。作为最后一个例子,假如你分别得到了你的猫分类器在四个主要市场(美国,中国,印度和其他地区)的准确率。这里提供了四个指标。通过对这四个数据进行平均或加权平均,你将得到单个数字度量。取平均值或加权平均值是将多个指标合并为一个的最常见的方法之一。
9. 优化指标和满足指标
这是组合多个评估指标的另一种方法。
假设你同时关心算法的准确率和运行时间。你需要在下面三个分类器中进行选择:
这里如果将准确率和运行时间组合为单个评估指标会看起来不太自然(例如:Accuracy−0.5∗RunningTime)。
这里你可以这样处理:首先,定义一个“可接受”的运行时间。例如我们说任何运行时间在100ms以内的算法都是可接受的。这里,运行时间就是一个“满足的度量(satisficing metric)”——你的算法只需要在这个指标上表现地“足够好(good enough)”就行,在这个意义上它应该满足最多100ms。准确率是一个“优化度量(optimizing metric)”。
如果你正在权衡N个不同的标准,例如模型的二进制文件大小(这对于移动app很重要,因为用户不想要下载很大的程序),运行时间和准确率等。你可以考虑设置其中N-1个标准为“满意(satisficing)”指标,也就是说你只需要他们满足特定的值即可。然后将最后一个定义为“优化(optimizing)”指标。例如,为二进制文件大小和运行时间设定可接受的阈值,并尝试在这些约束条件下不断优化准确率。
作为最后一个例子,假定你正在构建一个硬件设备,该设备使用麦克风监听用户说出的某个特定的“唤醒语(wakeword)”,从而唤醒系统。例如:Amazon Echo监听“Alexa”;苹果Siri监听“Hey Siri”;Android监听“Okay Google”;或百度app监听“你好百度”。你同时关心假正例的比率(the false positive rate, 即当没有人说唤醒语时系统唤醒的频率)和假反例的比率(the false negative rate, 即当有人说出唤醒语时系统没有唤醒的频率)。对这个系统表现性能的一个合理的目标是最小化假反例的比率(优化指标,optimizing metric),同时满足每24小时操作出现不超过一个假正例即可(满足指标,satisficing metric)。一旦你的团队对评估指标进行优化,他们将能够更快地取得进步。
10. 有一个开发集和评估指标来加速迭代
对于一个新问题,很难事先知道什么方法是最合适的。即使经验丰富的机器学习研究者在发现满意的方法之前也会尝试各种各样的idea。在构建机器学习系统时,我经常会:
- 首先想出一些构建系统的想法(idea)
- 在代码(code)中实现这些idea
- 进行实验(experiment),通过实验判断我的想法 work的怎么样。(通常我的前几个想法都不是很work!)基于这些知识,再生成更多的idea,并不断迭代。
这是一个不断迭代的过程。你循环得越快,你的进展也就越快。这就是 开发/测试集 和评估指标非常重要的原因:每次你尝试一个新的想法时,在开发集上测试其表现性能,这将使你快速判断你是否在朝着正确的方向前进。相反,如果你没有特定的开发集和评估指标。那么每次你的团队开发出一个新的猫分类器时,你必须把它移植到你的应用程序,并亲身体验几个小时来感受一下这个新的分类器性能是否有提升。这将是极其极其慢的!并且,如果你的团队将分类器的准确率从95.0%提升到95.1%,你可能无法通过亲身体验来感受到这0.1%的改进。而通过这些0.1%的不断改进,你的系统将取得很大的进步。有一个开发集和评估指标,你可以很快地检测出哪些想法给你的系统带来了小(或大)的改进,然后你就清楚地知道了哪些想法可以进一步改善,而哪些需要被舍弃。
11. 何时更改开发/测试集和评估指标
当开始一个新项目时,我一般会试图快速选择一个开发/测试集 ,因为这可以给团队制定一个明确的目标。我通常会要求我的团队在不到一周之内想出一个初始的开发/测试集和评估指标。提出一个不太完美的方案并迅速行动起来往往比过分考虑这些会更好。但是“一周”这个时间表并不适用于成熟的应用。例如,反垃圾邮件是一个成熟的深度学习应用。我曾经见过那些开发已经成熟的系统的团队可能会花费数月时间来获得更好的开发/测试集。
如果你后来发现你初始的开发/测试集或评估指标与你的目标并不完全一致,那么通过一切手段快速更改它们。例如,如果在你的开发集和评估指标上分类器A比分离器B表现好,但你的团队认为实际应用中分类器B更适合您的产品,这可能是一个你需要更改开发/测试集或评估指标的迹象。有三个主要原因可能会造成开发集/评估指标不正确地把分类器A排得更高:
你需要做得好的实际数据分布和开发/测试集是不同的。
假设你的初始开发/测试集主要是一些成年猫的照片。你查看猫app的后台,发现用户上传了比预期多很多的幼猫的照片。所以,开发/测试集的数据分布并不能代表你需要做好的实际的数据分布。这种情况下,更新你的开发/测试集,使其更具代表性。你已经过拟合了开发集。
在开发集上重复地评估不同方法的过程可能导致你的算法逐渐对开发集“过拟合(overfit)”。当你做完开发后,你将在测试集上评估你的算法。如果你发现算法在开发集上的表现远好于在测试集上的表现,这可能是你已经过拟合开发集的迹象。这种情况下,你需要更新你的开发集了。
如果你需要跟踪团队的进度,你也可以用测试集定期评估你的系统——每月或每周一次。但不要使用测试集来做出关于改进算法的任何决定,包括是否回退到上一周的系统。如果这样做了,你将开始过度拟合测试集,并且不可能再依靠它来给出系统性能的完全无偏估计(unbiased estimate)(你可能会在发表论文或做出重要商业决策是使用这个估计)。评估指标正在衡量的并不是项目所需要优化的东西。
假设对于你的猫app,你的评估指标是分类准确率。该指标现在把分类器A排在分类器B前面。但是假如你尝试了这两种算法,发现分类器A会偶尔允许色情图片通过。那么即使分类器A准确率更高,色情图片所带来的坏影响也意味着其表现是不被接受的。你需要做什么呢?
这里,评估指标不能辨别出对产品而言算法B比算法A更好这一事实。所以,你不能再相信该指标能挑选出最佳算法。现在时改变评估指标的时候了。例如,你可以改变评估指标,严重惩罚色情图片分类错误。我强烈建议你选择一个新的评估指标,以此来为你的团队明确定义一个新的目标,而非在不信任的评估指标下一直前行,并恢复到手工选择分类器。
在项目中改变开发/测试集和评估指标是很常见的。拥有一个初始的开发/测试集和评估指标能帮助你快速迭代。如果你发现 开发/测试集和评估指标 不再使你的团队在正确方向上前进,这不是什么大问题!只需要改变它们,并确保你的团队知道新的方向。
12. 小结:建立开发集和测试集
- 从分布中选择开发集和测试集,以反映你期望在未来获得的数据,并希望在上面做得很好。这可能和你的训练数据分布不同。
- 如果可能的话,选择来自同一分布的开发集和测试集。
- 为你的团队选择单一数字的评估指标进行优化。如果你关心多个目标,请考虑把它们合并到一个公式中(例如平均多个错误指标),或设定满足指标和优化指标。
- 机器学习是一个高度迭代的过程:在发现你满意的方法之前你可能需要尝试很多的idea。
- 具有开发/测试集和单一数字评估指标可以帮助你快速评估算法,因此迭代地更快。
- 当开始一个全新的应用时,尝试快速建立开发/测试集和评估指标,最好在一周之内。当然,在成熟的应用程序上花费更长的时间也是ok的。
- 依据70%:30%的比例划分训练/测试集这一经验性的方法不太适用于你拥有大量数据的情况;开发/测试集可以占有远小于30%的数据量。
- 你的开发集数据量应足够大,大到能检测出你的算法准确性上的有意义的改变,但没必要更大。你的测试集应该足够大,大到能对你的系统整体性能评估拥有一个很高的自信度。
- 如果你的开发集和评估指标不再使你的团队在正确方向上前进,快速改变它:(i)如果你过拟合了开发集,去获得更多的开发集数据。(ii)如果你所关心的实际分布和 开发/测试集 的分布不同,那么得到新的开发/测试集 数据。(iii)如果你的评估指标不再能衡量对你来说最重要的东西,请改变评估指标。