Machine Learning Yearning

最近把Andrew NG的新书《Machine Learning Yearning》看完了,这本书好像去年就有章节通过邮件陆续发布出来,最近看到同事在Hi上分享了完结版,第一时间就下载下来了。感兴趣的同学可以到https://www.deeplearning.ai/machine-learning-yearning/官网注册下载。

全书只有100多页,很短小精悍,但是对于机器学习从业人员来说,有很多可以汲取的经验。但是值得注意,Andrew在书中也多次提及,做AI应用和做AI研究还是存在许多不同,所以书中有不少建议是针对工业界的AI应用开发提出的。下面是我在阅读本书中做的一些简要笔记,也一并分享出来。

书籍要点摘录

  • 深度学习(深层神经网络)近年来得到巨大关注,主要原因有二:Data availabilityComputational scale,因此如何获取大量数据和设计网络及优化计算是提升机器学习算法效果的关键。书中有给到一张数据规模、算法、性能的关系图表,目前来看,在更大数据上,大规模神经网络能够取得最优效果,但是经典的算法随着数据规模变大,性能趋于停滞。
  • 将数据划分为training/dev/test三部分是很重要的,在dev数据集上进行各种模型调优,在test上进行最后的验证(信心把握),特别注意的是训练时和真实应用时面临的数据可能分布上存在不同,所以我们应当尽可能采集到真实的dev和test数据集,并且确保这两者来自同一分布(控制变量,使得训练过程更容易定位问题——是否过拟合),以免未来实际应用时效果大相径庭;但是,在研究领域,如何能够得到更好的泛化性能,即使各个数据集来自不同分布,是一个热点话题。
  • 设置可量化的评价指标,包括单一的最优化指标(optimizing metric),例如准确率,用于不同算法模型的排序,以及可能存在的多个满意度指标(satisficing metrics),例如耗时、模型大小等,这些指标只需设置满意度阈值。达成这样的共识后,能够推动项目快速迭代。
  • 在实际项目过程中,需要快速建立起初始化的dev/test/metric,以便快速验证(idea-code-experiment),当发现初始设置已经不能满足需求甚至偏离了应用目标时(这种情况很有可能发生,例如在dev上过拟合了、实际数据分布发生变化、关注指标发生改变等等),再予以修正。
  • Error Analysis,在dev集中找到一定数量的错误样本(一般100条左右),进行错误分析(出错的各种原因),能够帮助我们发现系统所存在的问题,找到最富有希望、收益最高的优化方向(并且能够作出合理的收益预估),而不是凭空想象。错误分析时,有一类错误是值得特别关注的——人为标记错误,而通常在初期,这些错误占比较小、影响甚微,可以不用修正,但是需要一直追踪,因为随着系统优化,这类错误最后可能成为性能瓶颈。对于人为标记错误的修正,需要同时在dev/test集合上进行,且尽量避免只在系统识别错误的样例中进行,这可能引入新的偏差。
  • BiasVariance在统计学上有严格的定义,在机器学习领域,可将Bias简单理解为训练集上的误差,而Variance则是测试集(dev/test)误差变化的程度(通常比训练集更差)。这两个取值的不同关系,反映了不同问题,归纳如下:
现象 问题
low bias + high variance overfitting
high bias + low variance underfitting
high bias + high variance too bad
low bias + low variance good

bias = optimal error rate(“unavoidable bias”) + avoidable bias,因此high bias通常是指avoidable bias的值的大小,而variance通常可以通过增大数据集来减小,因此variance总是可以避免的。

  • 减少avoidable bias的技巧:1. 增大模型规模;2. 修改输入特征(基于错误分析);3. 减小正则化(L1/L2 regularization, dropout, etc);4. 修改模型结构。
  • 减小variance的技巧:1. 增加数据;2. 增大正则化;3. 引入early stoppint;4. 特征选择(特别是数据规模较小时);5. 减小模型规模(更多应出于模型效率的考虑,否则方法2更好);6. 减少avoidable bias的2和4点同样适用于减小variance。而这里的2/3/4/5往往在减小variance的同时,可能会增加bias,因此variance和bias通常为一对tradeoff,需要综合考虑。
  • 把学习曲线画出来(横轴为训练集规模,纵轴为错误率,dev/train/human三条线),有助于可视化分析bias和variance的情况。当较小的数据集导致曲线抖动时,可以通过采样平均、等比例采样等进行纠正。
  • 如果我们面临的任务是人类擅长的,在构建机器学习系统时,我们可以有更多参考。human-level performance是重要的参考指标之一,通过错误分析可以洞见存在问题,雇用更多人进行数据标注,用该指标帮助分析当前所处阶段等等。
  • 如果training和dev/test的数据分布不一致时,学术界有一些研究,例如domain adaptation、transfer learning、multitask learning等,但是理论和实践目前存在较大的gap。在小数据时代,我们能够获取到的数据有限且同分布,但是大数据时代下,往往某一特定条件下的数据难以获得,但是类似数据在网络中大量存在。在此情况下,如果能够用更大的模型、更大的数据进行训练,通常能够取得更好的效果。比较常见的做法是大数据+少量真实采集数据作为训练,剩余真实采集数据作为dev/test。此外,还要考虑数据的兼容性,如果数据本身的来源对目标影响很大,不能直接进行融合,通常需要将来源信息也注明(更建议的是不使用该数据)。实践中,如果我们希望对不同类型的数据予以不同的关注程度,可以通过重赋权实现,这样还可以一定程度减缓不同分布数据混合训练的弊端、节省计算资源等。
  • 如果不同分布数据混合训练,除high variance和high bias外,通常会引出另外一个问题,data mismatch,为了检查是否出现了该问题,需要再设置一份training dev set(和training set同分布,通过比较该数据集和dev/test数据集上的性能差异,便可判断是否出现了data mismatch的问题)。如果出现data mismatch,我们需要通过错误分析,比较training data和developoing data存在的差异来找到原因。找到这些差异后,我们可以利用现有的巨量训练数据,人工生成一些更加接近真实测试数据的训练数据,例如给语音加噪、图像裁剪等等。但是在产生这种人工数据时,需要尽可能避免所施加的变化因子极容易被机器识别出来,造成系统的过拟合(很多时候,这个建议很难实现)。
  • 在很多推理任务中,例如机器翻译、语音识别、强化学习等(O=\underset{S}{\mathrm{argmin}}F_A(S)),最终的错误原因大致可以分为两类,其一是优化方法(optimization or search algorithm),其二是打分方法(object or scoring algorithm)所带来的问题。针对某个失败样例,我们通过计算F_A(S^*)F_A(O)S^*表示真实标记,O表示系统输出)的大小就可以判定是那个原因造成的(Optimization verification test),如果F_A(S^*)>F_A(O),则为optimization problem,如果采用beam search可以尝试增大beam size;如果F_A(S^*) \leq F_A(O),则为object problem,需要调优模型打分。实际上,我们需要分析整个dev数据集上的错误样本,以判定整体上那个原因占据主导。
  • 端到端学习(End-to-End)越来越受到关注,但是并非任何时候都适用。以语音识别为例,传统的语音识别包括好几个部分,例如特征提取(MFCC)、音素识别、语言模型等等,每个部分都有很多人工知识在里面,在数据较少时,是一个很好的补充,但是同时丢失忽略了一些潜在的信息。所以,当数据量大时,让机器自己从头到尾自己去学习,往往能够取得更好的效果。有时,因为数据可获性(data availability)和任务难度(task simplicity),端到端学习是很困难的,例如目前的自动驾驶,这时候进行合理的模块拆分(pipeline components)将使得学习更加高效。这其实和软件工程中的自顶向下思想是一样的
  • 模块拆分后,对系统进行错误分析,可以发现系统短板,加速优化实验。通常要求拆分后是一个有限无环图,可以被表达成从左到右的一个路径(并列的可以随机赋予先后顺序),以Input\rightarrow A\rightarrow B\rightarrow C\rightarrow Output 为例,1. 如果使A最优化,结果有大幅提升,则错误可归因于A,否则2. 如果继续使B最优化,结果有大幅提升,则错误可归因于B,否则3. 错误归因于C。实际上除了严格遵循上面的做法,还有很多其他错误分析的方法,例如每个模块都和人类能够达到的水平做比较(假定人类在这类任务上已经做的足够好)。但是,有时候我们会发现,即使每个模块各自已经做的足够好(human-performance),但是一旦合起来,整个系统的性能却不如人意,这时候需要检查我们的模块设计是否有问题,是否在拆分中丢失了重要的信息。

初版勘误纪要

  • Page17, the “wrong” alarm picture shoule be setted under “we can randomly assign …, right?”

Published by

admin

天空没有翅膀的痕迹,但我已飞过

Leave a Reply

Your email address will not be published. Required fields are marked *