吴恩达《Machine Learning Yearning》学习笔记

本文链接

https://blog.csdn.net/fengtaoO08/article/details/84336400

开始

  1. 推动深度学习(神经网络)近期发展的主要因素:
     a)  数据可用性(data availability),如今广泛数字化行为产生海量数据可供训练。
     b)  计算规模(computational scale),如今有能力训练出足够大的神经网络。
  2. 在小数据集情况下,算法的表现更多取决于人工特征选择工程,此时选择神经网络还是传统算法并非决定因素。在大数据集情况下,传统算法较难从数据量中获得更多提升,神经网络会有更好效果。
  3. 提升性能表现方法:
     a) 训练大型神经网络。
     b) 利用更海量数据。
     c) 优化神经网络架构及其他细节。

建立开发集和测试集

  1. 机器学习中通常定义:
     a) 训练集(Training set)用于运行学习算法。
     b) 开发集(Dev set)用于调整参数,选择特征,对学习算法作出其它决定。有时也称为留出交叉验证集(hold-out cross validation set)。
     c) 测试集(Test set)用于评估算法的性能,但不会据此改变学习算法或参数。
  2. 开发集和测试集的使命就是引导你的团队对机器学习系统做出最重要的改变。不要无脑粗暴地将数据集7/3划分为训练集和测试集,而是合理地选择开发集和测试集,使之能够代表将来实际数据的情况(分布),并期望算法能够运行良好。
  3. 开发集和测试集应该服从同一分布,否则很难在 开发集过拟合/测试集预测困难/性质不同 这几种情况中,什么导致算法表现不佳。
  4. 开发集规模应当尽可能大,通常在1000到10000个样本数据之间,以尽可能区分出你所尝试的不同算法之间的性能差异。
  5. 测试集规模应当大到使你能够对整体系统的性能进行一个高度可信的评估,但数据量巨大时,不需要将开发集和测试集的规模提升到远远超过评估算法性能所需的程度。一种常见的启发式策略是将整体 30% 的数据用作测试集,这适用于总体数据量规模一般的情况(比如 100 至 10,000 个样本);大规模数据集时比例实际将远低于30%。
  6. 尽量使用单值评估指标(single-number evaluation metric)进行优化,因为多值评估指标提高了在算法之间进行优劣比较的难度。
  7. 整合到一个表达式里(比如对多个误差指标取平均值或者加权平均值)是将多个指标合并为一个指标的最常用方法之一,例如将查准率(Precision,又译作精度)和查全率(Recall,又译作召回率)的调和平均数F1 score作为单值评估指标。
    F 1 = ( r e c a l l − 1 + p r e c i s i o n − 1 2 ) − 1 F_1 = \left(\frac{\mathrm{recall}^{-1} + \mathrm{precision}^{-1}}{2}\right)^{-1} F1=(2recall1+precision1)1
    另一种方法是将某一种指标作为优化指标,其余指标作为“满意度指标”,要求算法在满意度指标满足一定的值或范围的情况下再去比较优化指标。
  8. 当开发集和评估指标对于团队已经不能提供一个正确的导向时,尽快修改它们:
     a)  如果算法在开发集上过拟合,则需要获取更多的开发集数据。
     b)  如果开发集与测试集的数据分布和实际数据分布不同,则需要获取新的开发集和测试集。
     c)  如果评估指标无法对最重要的任务目标进行度量,则需要修改评估指标。

基础误差分析

  1. 当你开始一个新项目,尤其是在一个你不擅长的领域开展项目时,很难正确预判出最有前景的方向。所以,不要在一开始就试图设计和构建一个完美的系统。相反,应尽可能快(例如在短短几天内)地构建和训练一个系统雏形。然后使用误差分析法去帮助你识别出最有前景的方向,并据此不断迭代改进你的算法。
  2. 误差分析(Error Analysis):检查被算法误分类的开发集样本的过程,以找到造成这些误差的原因。这将协助确定当下一步工作的优先级,并且获得探索新方向的灵感。例如,可以收集开发集中100 个被误分类的样本,即造成系统误差的样本,然后计算分析各种原因造成误分类的比例,这样就可以权衡消除这些原因所需工作量及其带来的性能提升收益之间的关系。
  3. 误差分析一种最佳实践是,在查看误分类样本同时完善一个电子表格,表格中记录这些样本的信息。例如
图像大猫模糊误标注备注
1不常见的美国比特犬
2
3狮子;雨天在动物园拍摄的图片
4树木后的美洲豹
89标注者忽略了背景中的猫
99
100猫的画像;非真猫
占全体比例8%43%61%6%
  1. 若要对开发集误标注标签进行修正,必须也对测试集进行同样的操作,以保证同分布。尽量修正整个系统内所有样本的标签(包括算法分类正确的),否则会引入偏差。
  2. 如果你正在处理一项实际情况中人类表现良好的任务,并且开发集足够大,考虑将其分为两个子集,即人为检查的 Eyeball 开发集和非人为检查的 Blackbox 开发集。如果在 Eyeball 开发集上的性能比在 Blackbox 开发集上好很多,说明你已过拟合 Eyeball 开发集,下一步应该考虑为其获取更多数据。
  3. 如果你正在处理一项,实际情况中人类也无法很好完成的任务,那么检查 Eyeball 开发集将不会有大的帮助,因为很难找出算法不能正确分类一个样本的原因。此时你可能也不需要建立 Eyeball 开发集。
  4. Eyeball 开发集应该足够大,以便于算法有足够多的错误分类样本供你分析。对大多数应用来说,含有1000-10000个样本的 Blackbox 开发集已足够。如果你的开发集不够大,无法按照这种方式进行拆分,那么就使用 Eyeball 开发集来执行人工误差分析、模型选择和调超参。

偏差和方差

  1. 机器学习中有两个主要的误差来源:偏差(bias)和方差(variance)。建立对偏差和方差的良好直觉将帮助你为算法选择出有效的改进策略。
  2. 粗略地说,偏差指的是算法在大型训练集上的错误率;方差指的是算法在测试集上的表现低于训练集的程度。当你使用均方误差(MSE)作为误差度量指标时,总误差=偏差+方差。例如,对于简单的任务,训练集上的错误率是 15%,开发集错误率为 16%,则偏差为15%,方差为1%,此时首要问题是如何提高算法在训练集上的性能。
  3. 减少偏差可以提高算法在训练集上的性能,减少方差可以帮助算法从训练集到开发/测试集上更好地泛化。
  4. 上述分解方法在考虑任务难度时有一个更好的版本,即开发集总误差=最优错误率+可避免偏差+方差。其中最优错误率(不可避免的偏差/噪声/贝叶斯错误率/贝叶斯率)是指即使理想的最优分类器也会存在的误差,可避免偏差指训练集错误率与最优错误率之间的差值,方差指开发集错误率与训练集错误率之间的差值。
  5. 如果可避免偏差值是负的,即算法在训练集上的表现比最优错误率要好。这意味着你正在过拟合训练集,并且算法已经过度记忆(over-memorized)训练集。你应该专注于有效降低方差的方法,而不是选择进一步减少偏差的方法。
  6. 偏差方差分析举例
算法编号训练集错误率开发集错误率最优错误率可避免偏差方差备注
11%11%0%1%10%高方差低偏差:过拟合
215%16%0%15%1%高偏差低方差:欠拟合
315%30%0%15%15%高偏差高方差
40.5%1%0%0.5%0.5%低偏差低方差:优
515%30%14%1%15%高方差低偏差:过拟合
613%15%14%-1%2%负可避免偏差:过拟合
714.5%15%14%0.5%0.5%低偏差低方差:优
  1. 简单处理方法:
     a) 高可避免偏差,加大模型的规模(例如通过添加层/神经元数量来增加神经网络的大小),风险是可能增加方差甚至过拟合。但若使用了 L2 正则化和 dropout 等正则化技术,并且设置了在开发集上表现最好的正则化参数,这种风险会降低,此时算力问题将会更凸显。
     b) 高方差,增加训练集数据量,这种方法对于偏差没有明显影响,缺点是可能会遇到算力和数据获取问题。
     c) 尝试新的模型架构,缺点是结果难以预测。
  2. 偏差和方差间的权衡:一般情况下,你可以通过增加神经网络的规模大小,并调整正则化方法去减少偏差,而不会明显的增加方差。通过增加训练数据,你也可以在不影响偏差的情况下减少方差。如果你选择了一个非常契合任务的模型架构,那么你也可以同时减少偏差和方差。只是选择这样的架构可能有点难度。
  3. 减少可避免偏差的技术:
     a) 加大模型规模(例如神经元/层的数量):这项技术能够使算法更好地拟合训练集,从而减少偏差。当你发现这样做会增大方差时,通过加入正则化可以抵消方差的增加。
     b) 根据误差分析结果修改输入特征:假设误差分析结果鼓励你增加额外的特征,从而帮助算法消除某个特定类别的误差。这些新的特征对处理偏差和方差都有所帮助。理论上,添加更多的特征将增大方差;当这种情况发生时,你可以加入正则化来抵消方差的增加。
     c) 减少或者去除正则化(L2 正则化,L1 正则化,dropout):这将减少可避免偏差,但会增大方差。
     d) 修改模型架构(比如神经网络架构)使之更适用于你的问题:这将同时影响偏差和方差。
  4. 减少方差的技术:
     a) 添加更多的训练数据:这是最简单最可靠的一种处理方差的策略,只要你有大量的数据和对应的计算能力来处理他们。
     b) 加入正则化(L2正则化,L1正则化,dropout):这项技术可以降低方差,但却增大了偏差。
     c) 加入提前终止(例如根据开发集误差提前终止梯度下降):这项技术可以降低方差但却增大了偏差。提前终止(Early stopping)有点像正则化理论,一些学者认为它是正则化技术之一。
     d) 通过特征选择减少输入特征的数量和种类:这种技术或许有助于解决方差问题,但也可能增加偏差。稍微减少特征的数量(比如从 1000 个特征减少到900个)也许不会对偏差产生很大的影响,但显著地减少它们(比如从1000个特征减少到100个,10倍地降低)则很有可能产生很大的影响,你也许排除了太多有用的特征。在现代深度学习研究过程中,当数据充足时,特征选择的比重需要做些调整,现在我们更可能将拥有的所有特征提供给算法,并让算法根据数据来确定哪些特征可以使用。而当你的训练集很小的时候,特征选择是非常有用的。
     e) 减小模型规模(比如神经元/层的数量):谨慎使用。这种技术可以减少方差,同时可能增加偏差。然而我不推荐这种处理方差的方法,添加正则化通常能更好的提升分类性能。
     f) 减少模型规模的好处是降低了计算成本,从而加快了你训练模型的速度。如果加速模型训练是有用的,那么无论如何都要考虑减少模型的规模。但如果你的目标是减少方差,且不关心计算成本,那么考虑添加正则化会更好。
     g) 根据误差分析结果修改输入特征:假设误差分析的结果鼓励你创建额外的特征,从而帮助算法消除某个特定类别的误差。这些新的特征对处理偏差和方差都有所帮助。理论上,添加更多的特征将增大方差;当这种情况发生时,加入正则化,这可以消除方差的增加。
     h) 修改模型架构(比如神经网络架构)使之更适用于你的问题:这项策略将同时影响偏差和方差。

学习曲线

  1. 开发误差曲线即开发集误差随训练集大小变化的曲线,可以将开发集的误差与训练集样本的数量进行关联比较。例如,可以根据红色的开发误差曲线的走势推测添加一定量数据后算法距离期望性能接近了多少。在数据集足够大的情况下,如果走势逐渐平缓,那么可以立刻得知,再增加数据不太可能得到预期的性能提升;否则继续添加数据量是合理的。
    学习曲线1
    学习曲线2
  2. 但是对于数据集较小的情况,开发误差曲线可能会非常不稳定,因为可能含有噪声,因此不足以预测曲线走向。此时引入训练误差曲线,即训练集误差随训练集大小变化的曲线,来协助评估添加数据带来的影响。
    学习曲线3
  3. 随着训练集大小的增加,开发集(和测试集)误差应该会降低,但你的训练集误差往往会随之增加。算法在训练集上通常比在开发集上表现得更好;因此,红色的开发误差曲线通常严格位于蓝色训练错误曲线之上。有这些关系,就能通过训练误差曲线的走势“上限”来判断红色的开发误差曲线的走势“下限”。
  4. 分析方法:一般,期望性能是我们对最优错误率的估计。在训练集大小的最大处(大致对应使用我们所有的训练数据),训练误差和期望性能之间的间隙大小,代表可避免偏差的大小。训练曲线和开发曲线之间的间隙,代表方差的大小。
  5. 三种典型情况:高偏差低方差(欠拟合),高方差低偏差(过拟合),高方差高偏差。
    学习曲线4
    学习曲线5
    学习曲线6
  6. 绘制学习曲线时,通常是从整个数据集中无放回随机抽取一定大小的子数据集序列来进行训练。但对于小数据集,为了减少噪声扰动,可以多次训练有放回抽样的子数据集,再取平均的方法来得到某个大小的数据集的误差点,从而绘制学习曲线。对于样本类别不均的数据集,为避免倾向某一个类,应该确保每个类的样本比例尽可能地接近原始训练集的总体比例。

与人类表现水平比较

  1. 构建处理人类擅长任务的机器学习系统,相比构建处理人类不擅长任务的机器学习系统要简单。
     a) 前者很容易从人为标签中获取数据,后者很难。
     b) 前者可以基于人类直觉进行误差分析,后者不能依靠人类直觉。
     c) 前者可以使用人类表现水平来估计最优错误率,并设置可达到的“期望错误率”,后者难以确定这些参数。
  2. 人类表现水平应当根据实际应用场景,尽量选择较低的错误率作为定义。即使你的算法在整个开发集或是测试集上的表现已经超过了人类,只要在开发集上存在着一些人类能正确处理而算法不能的样本,前面提到的技术就能够被应用以继续获取进展。

在不同的分布上训练和测试

  1. 关于选择开发/测试集的建议:选择开发集和测试集以反映你在将来想要正确处理的数据。
  2. 假设你有两组不同分布的数据集,应只从与将来想要正确处理的数据分布一致的数据集中选择数据来作为开发集和测试集,并保留部分数据作为训练集。不全部作为开发/测试集的原因是,这样允许你在误差分析中对比这种分布的数据在训练集和开发/测试集之间的性能表现。另外一组数据是否可添加为训练数据,考虑以下内容来决定。
     a)数据一致性。考虑算法在不知道数据来源(即来自哪个分布)的情况下,能否可靠地完成算法目标。如果不能,则称数据是不一致的,此时最好忽略这些不一致的数据。
     b)如果数据是一致的,则考虑这些数据是否存在对你的神经网络学习目标有帮助的信息。如果没有任何帮助,即神经网络从这些数据中几乎没有可学习到的东西,只会浪费计算资源和网络表征能力,那么应该排除这些数据。
     c)如果数据一致,且存在有用信息,则考虑神经网络是否拥有足够的表征能力(足够大,足够灵活)来容纳这批数据。因为不同分布的数据会迫使你的算法花费部分容量学习一些额外的属性或特征,这会“消耗”一些表征能力,损害算法性能,这就是早期的学习算法不推荐这样做的原因。但当你的神经网络足够大或足够灵活的时候,这种风险大大降低了,此时添加这些数据更有可能提升算法性能;否则你应当更关注训练数据与开发集/测试集匹配的问题,而舍弃这些数据。
  3. 例子:10000张用户上传的移动数据端猫咪图片和200000张互联网下载猫咪图片,目标是移动端猫咪分类。可从10000张移动端数据中抽取5000张图片作为开发/测试集,剩下5000张图片用作训练集。考虑200000张互联网数据与移动端数据一致,且存在对学习目标有用的信息,并且当前网络足够容纳所带来的额外信息,可将互联网数据添加到训练集。即最后有205000张图片作为训练集,5000张图片作为开发/测试集。
  4. 如果你觉得额外数据的分布,与开发/测试集同分布数据的分布之间区别太大,或者额外数据的规模远远大于开发/测试集同分布数据的规模时,则有必要对数据加权重,以确保在有限计算资源下,算法在两种数据上都训练得很好(理论上在足够大的网络上训练足够久的情况下,并不需要这种处理)。在上面的例子中,如果优化目标是 min ⁡ θ ∑ ( x , y ) ∈ M o b i l e I m g ( h θ ( x ) − y ) 2 + ∑ ( x , y ) ∈ I n t e r n e t I m g ( h θ ( x ) − y ) 2 \min_{\theta}\sum_{(x,y)\in MobileImg}(h_{\theta}(x)-y)^2 +\sum_{(x,y)\in InternetImg}(h_{\theta}(x)-y)^2 θmin(x,y)MobileImg(hθ(x)y)2+(x,y)InternetImg(hθ(x)y)2可使用一个额外的权重参数 β \beta β改为 min ⁡ θ ∑ ( x , y ) ∈ M o b i l e I m g ( h θ ( x ) − y ) 2 + β ∑ ( x , y ) ∈ I n t e r n e t I m g ( h θ ( x ) − y ) 2 \min_{\theta}\sum_{(x,y)\in MobileImg}(h_{\theta}(x)-y)^2 +\beta\sum_{(x,y)\in InternetImg}(h_{\theta}(x)-y)^2 θmin(x,y)MobileImg(hθ(x)y)2+β(x,y)InternetImg(hθ(x)y)2这个权重参数如设置为 β = 1 40 \beta=\frac{1}{40} β=401则这个算法会对 5000 个移动图像和 20 万个互联网图像给予同等的权重,也可以设置为其他值类似地对开发集进行调优。
  5. 上述方法可能会导致数据不匹配(Data Mismatch)问题:算法能够很好地泛化到与训练集相同分布的未知数据,但不能很好地泛化到与开发/测试集相同分布的未知数据。
  6. 在上述这种训练集含有与开发/测试集不同分布的数据的情况下,需要建立一个训练开发集(Training dev set),来帮助我们分辨高偏差问题及数据不匹配问题分别对算法造成的影响。具体来说,需要把原来的训练集抽取拆分出一个小子集不做实际训练,而作为训练开发集。它的数据自然来自与训练集相同的分布;它通常比训练集要小,只需要足够大到来评估和跟踪我们的学习算法的进展。如果开发集误差比训练开发集的误差相对大很多,则非常可能是出现了数据不匹配问题。
  7. 分析举例
算法编号训练集错误率开发集错误率训练开发集错误率最优错误率可避免偏差开发集方差训练开发集方差备注
11%5%5%0%1%4%4%高方差低偏差:过拟合
210%12%11%0%10%2%1%高偏差低方差:欠拟合
310%20%11%0%10%10%1%高偏差数据不匹配
41%10%1.5%0%1%9%0.5%数据不匹配
  1. 试图解决数据不匹配问题你需要:
     a) 通过误差分析尝试理解训练集分布和开发集分布之间数据属性之间的差异,
     b) 尝试获取更多与开发集出错样本性质有更好匹配性的训练数据,尤其是当你发现同样分布的那部分数据在测试集表现很好,而开发集很糟的时候。
  2. 人工数据合成:在一些情况下,人工合成数据允许你创建一个与开发集相当匹配的巨大数据集。但有时候合成一个对计算机而言真实的数据,相比对人而言真实的数据要困难得多。如果合成的数据不慎“泄露”了某些特征或属性,使得学习算法很容易将合成和非合成的样本区分开来,那么其很可能会“过拟合”这些特征或属性,例如所有合成音频的背景噪音都来自某一段汽车噪音音频时,此时很可能无法很好泛化到有不同汽车背景噪音的数据。因此最好多花时间下功夫,使合成的数据与实际数据的分布尽可能接近。

调试推理算法

  1. 优化验证测试(Optimization Verification test)是用于解决如下问题时使用的技术:给定输入 x x x,可以通过算法的目标(得分)函数 Score x ( y ) \text{Score}_x (y) Scorex(y)来获取标签 y y y的得分,但有时候没办法直接使用最大化函数 argmax y \text{argmax}_y argmaxy精确找到最大得分对应的标签(例如搜索空间太大),而是采用近似搜索方法,这些方法不保证得到最大化得分标签。此时如何分析造成误差的原因是来自目标得分函数,还是近似搜索算法呢?
  2. 优化验证测试:假设 y ∗ y^* y是“正确的”标签(即最大化得分的标签),但是算法输出了 y o u t y_{out} yout。计算不等式 Score x ( y ∗ ) ≥ Score x ( y o u t ) \text{Score}_x(y^*)\ge\text{Score}_x(y_{out}) Scorex(y)Scorex(yout)。如果该不等式成立,我们便可以将误差归咎于最大化近似搜索算法。否则,我们将误差归咎于目标函数 Score x ( y ) \text{Score}_x (y) Scorex(y)的计算方式。因此,优化验证测试能够反映改进学习算法与改进得分函数之间哪一个更具前途。

端到端深度学习

  1. 神经网络通常用于端到端学习系统,“端到端”这个术语指的是我们要求学习算法直接从输入得到期望的输出,即学习算法将系统的“输入端”连接到“输出端”。在数据量十分丰富的问题上,端到端系统往往很奏效,但它并不总是一个很好的选择。
  2. 流水线(pipeline)系统与端到端系统的取舍:流水线系统含有许多“人工设计”的成分,即许多先验知识,这使得系统可以用更少的数据进行训练;同时由于流水线的架构各个中间组件通常是更为简单的任务,一方面这些任务的标注数据更容易获取,另一方面这些简单任务的计算步骤更少更容易训练,所以可能是更优的。端到端系统缺乏人工设计知识,因此数据量少时表现会更差,同时由于任务更为复杂,获取两端的标注数据将较为困难,训练难度也会提升;但当网络足够大数据量足够多的时候,不受“人工设计”因素的限制,很可能得到更好的效果,另外端到端系统可以得到比仅仅数字更丰富的输出形式。

根据流水线组件进行误差分析

  1. 误差归因于流水线的特定组件的一般步骤:
    流水线
     假设在流水线中有三个步骤 A,B 和 C,其中 A 直接输出到 B,B直接输出到 C。对于系统在开发集上存在的每个错误样本,遵循 DAG(有向无环图) 顺序:
     a) 尝试人为修改 A 的输出为 “完美” 输出(例如,待检测目标的 “完美” 边界框),并在此输出上运行流水线其余的 B,C 部分。 如果算法现在给出了正确的输出,那么这表明,只要 A 给出了更好的输出,那么整个算法的输出就是正确的;因此,你可以将此误差归因于组件 A. 否则,请继续执行步骤 b)。
     b) 尝试人为修改 B 的输出为 “完美” 输出。如果算法现在给出正确的输出,则将误差归因于组件 B。 否则,继续执行步骤 c)。
     c) 将误差归因于组件 C。
  2. 组件误差分析与人类水平对比:很多误差分析方法对于大部分人类擅长任务都可以工作得很好,因为可以将误差与人类水平作对比,可以快速找到哪些组件是系统性能瓶颈所在,并专注于提高这些组件的性能。
  3. 如果每个组件都具有人类水平的性能(应与被给予与组件相同输入的人类进行比较),但流水线整体上还是不能达到人类水平的性能,则表明流水线有缺陷,应该重新设计,例如考虑给流水线增加一个提供额外信息的组件。

参考

  1. Andrew Ng. “Machine Learning Yearning.” (2018).
  2. https://github.com/amusi/machine-learning-yearning-cn
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值