Structuring Machine Learning Projects

ML Strategy (1)

Why ML Strategy(机器学习策略)

什么是机器学习策略?

假设我们正在调试🐱分类器,经过一段时间调试,系统的准确率达到了90%,但还有不少能提升准确率的方法,在下图中我们列出一部分

上述的诸多想法我们都可以进行测试,但问题在于,如果做出了错误的选择,可能会浪费大量时间,朝错误的方向前进(同时注意不到错误),因此我们需要一些策略,来判断哪些方法是值得一试的,哪些是可以舍弃的,或者提出新的方法


Orthogonaization(正交化)

搭建机器学习模型时所面临的一个重要的问题是:可以尝试和改变的东西太多了

以这台老电视机为例。当我们要调整图像时,需要调整旋钮,我们可以很简单的知道,如果有一个旋钮集成了图像的长、宽、色度等信息时,我们要对图像进行合适的调整其实是很麻烦的,因此,电视的设计者将旋钮分为多个,每一个都对应着不同的属性,这即是正交化的思想(正交即为互成90度)

我们将其放在机器学习中思考

对于一个监督学习系统。通常需要调整系统的“旋钮”,确保四件事:

  • 系统在训练集上的效果不错
  • 系统在开发集上有良好表现
  • 系统在测试集上表现良好
  • 真实结果反馈

对于“旋钮”,当算法在成本函数上不能很好的拟合训练集,这个旋钮就意味着“训练更大的网络”或者“选择更好的算法”;
当算法对开发集的拟合很差,那么应该有一组独立的“旋钮”去调试;
对于开发集,有“正则化”和“增大训练集”等“旋钮”;
对于测试集,“旋钮“可能是”更大的开发集”<这种情况有可能是对开发集过拟合了>;
对于反馈,”旋钮“就有可能是”改变开发集“或”成本函数“<错误可能是开发集分布设置不正确或是成本函数测量的指标不对>


Single number evaluation metric(单一数字评估指标)

对于下面的应用

上面两列分别是它的查准率和查全率,但当我们想判断选择哪个时,问题来了?这两者孰优孰劣?

我们引入F1分数(两者的调和平均数)进行比较,这种方法有助于快速迭代

通过它进行判断,我们最终选择了A


Satisficing and Optimizing Metric

要把顾及到的所有事物组合成单实数评估指标,有时并不容易,因此,在一些情况下,设立满足与优化指标是很有用的

下图为例

假设我们最看重的是准确度,但同时我们也应该注意到识别图像所花费的时间,因此我们可以将准确度与运行时间组合成一个整体评估指标

我们可以选择对两个数值加权求和,但通常,选择一个 ”定义优化 && 满足指标“ 的分类器应该更为合适


Train/Dev/Test Distributions

本节主题:如何设立开发集和测试集?

  • 开发集与测试集应来自于同一分布(可以取同一分布内的数据随机分布)
  • 开发集与测试集的结果应该是符合预期的

Size of the Dev and Test Sets

怎样确定开发集与测试集的规模?

Old


Model

怎样选择测试集的规模呢?

我们知道,测试集的目的是完成开发之后,测试集用来评估其性能,因此,方针就是,让测试集尽可能大,能够以高置信度评估性能


When to Change Dev/Test Sets and Metrics?(什么时候改变开发/测试集与指标)

假设正在创建一个猫分类器,试图找到很多猫的照片,算法A与B分别有3%与5%的错误率,这样看来,算法A似乎表现得很好

但是当实际应用时,算法A错把XX图像当成猫图,尽管它推送了更多猫图,但是与需求(only 🐱!)发生了冲突,而B,5%的错误率使分类器得到较少的图像,但是并没有传进XX图,因此从实际出发,算法B实际上是一个更好的算法

在上述事件中,发生的就是,事件A在评估指标上做的更好,但从需求的角度出发,它无疑是一个比较糟糕的算法

在这种情况下,评估指标加上开发集都倾向于选择A,但需求制定者更偏向于B,因此当你的评估指标无法正确衡量算法之间的优劣排序时,在这种情况下,原来的指标错误的预测算法A是更好的算法,这就发出了信号,你应该改变评估指标或者开发集/测试集了!

此时使用的分类错误率指标

$Error\,=\,\frac{1}{m_{dev}}\,\sum^{m_{dev}}_{i=1}I\{y^{(i)}_pred\,+\,y^{(i)}\}$

其中一个修改评估指标的方法是:添加权重项

$Error\,=\,\frac{1}{m_{dev}}\,\sum^{m_{dev}}_{i=1}w^{(i)}I\{y^{(i)}_pred\,+\,y^{(i)}\}$

通过这个公式。我们给予不符合预期的图片更大的权重,以此让它们迅速变大

从上面的例子我们可以得出一个粗浅的结论:如果评估指标无法正确评估好算法的排名,我们需要改变它


Why Human-level Performance?

机器学习往往擅长模仿人能做的事

可以发现,一旦超过人类的水平,增长的明显变缓,最终贴近于上面的那条线 — 贝叶斯最优错误率


Avoidable Bias

在计算机视觉上,人类达到的误差与贝叶斯错误率相差不多,这时候我们将它们近似,在这种情况下,具有同样的训练错误率与开发错误率,我们决定于减少偏差(方差)的策略,而训练错误率与开发错误率之间的偏差,就大概说明了算法在方差问题上的改善空间,可以运用正则化等手段

我们将贝叶斯错误率的估计与训练错误率之间的差值,称为可避免偏差,这一概念,说明了有一些别的偏差,或错误率有个无法超越的最低水平

由此,对于上述情况
左边适合调整可避免偏差,而右边调整方差
因此,不同的场景,有不同的策略


Understanding Human-level Performance

思考人类水平错误率的方式之一,是将其作为贝叶斯错误率的替代或估计(这时我们往往将其看作多数人考虑后的错误率,而非个人)

在定义人类水平错误率时,要清楚目标所在,如果要表明可以超过单个人类,那么就有理由在某些场合部署你的系统


Improving your Model Performance(改善模型表现)

总结:正交化 设立开发集与测试集 用人类水平错误率估计贝叶斯错误率 估计可避免偏差与方差

想让一个监督学习算法达到实用,基本上需要完成2件事:

首先,算法对训练集的拟合很好,这可以看作可避免偏差很低

其次,在训练集中效果优良,然后推广到开发集和测试集也很好,这就是说方差不是太大

在正交化精神下,我们模拟出了”旋钮”,可以修正可偏差问题(训练更大的网络/训练更久),还有一套独立的“旋钮”可以用来处理方差问题(正则化/收集更多训练数据)

总结一下前几解的步骤,若想提高机器学习系统的性能,可以看训练错误率与贝叶斯估计值之间的距离,从而判断可避免偏差的大小(对训练集大小的优化还有多少空间),然后看开发错误率与训练错误率之间的距离,从而判断方差问题的大小(应该做多少努力,使算法表现能够从训练集推广到开发集)

当目标在减少可避免偏差时,可以尝试:

  • 使用规模更大的模型
  • 训练更久
  • 使用更好的优化算法(加入momentum/RMSprop)/算法(Adam)
  • 寻找更好的新神经网络架构
  • 一组更好的超参数

当目标在改变方差时,可以尝试:

  • 收集更多数据训练(可以更好的推广到系统看不到的开发集数据)
  • 正则化
  • 数据扩增
  • 寻找更好的新神经网络架构(超参数搜索)

ML Strategy (2)

Carrying Out Error Analysis(误差分析)

我们以下面的情况为例

对于已经大致训练好的🐱图分类器,它的错误率为90%,但是它对一些🐕图仍束手无策

这种情况下,我们难道还需要专门做一个项目去处理🐕?这样值得吗?

这里提供一套错误分析流程,去帮助判断这个方向是否值得努力

  • 收集部分带有错误标记的开发集例子
  • 挨个观察标记中有多少是🐕
  • 查看🐕在错误标记中所占的比例,判断对其进行更改的效果是否值得

人工统计在一些时候,确实能节省大量时间

使用表格判断方法是极为可取的


Cleaning up Incorrectly labeled data

当观察数据时,发现某些输出标签Y是错的,是否值得花时间去修正呢?

首先去考虑训练集,深度学习算法对于训练集中的随机错误是相当健壮的,即如果错误项离随机错误项不太远,

若错误足够随机,那么不管这些错误可能也没问题,而并不需要花太多时间去修复它们

深度学习对随机错误比较健壮,但对系统性的错误相对就没那么健壮了

而当开发集与测试集标记出现问题时该怎么办呢?

当你担心上述问题时,一般推荐在进行错误分析时,添加一个额外的列,统计它们的错误例子数

对于极少数例子数,你的分类器输出和标签不同,是因为标签出错,而非分类器出错

同时,你也可以统计因为标签错误所占的百分比

现在面临的问题是:是否值得修正6%标记出错的例子

建议是:如果错误非常严重,很大程度上影响了你在开发集上评估算法的能力,那么就应该去花时间修正错误的标签,但当它们没有严重影响到用开发集评估成本偏差的能力,那么处理的必要就相对较轻了

这里再提示一下设立开发集的主要目的:用它来从两个分类器A和B中选择一个

我们有时无法直观的从开发集中选择一个分类器,因为它无法体现哪个分类器比较好,标记出错产生的错误率即是其原因,这是就有充分的理由去修正开发集里的错误标签

我们这时就可以对上图右方开发集的错误标签动手,因为其标记出错 ,对算法错误的整体评估标准有严重的影响;而在左边的开发集中,标记错误对算法影响的百分比还是相对较小的

而再修改开发集数据之前,手动重新检查标签,并尝试修正一些标签,还有一些额外的方针与原则需要考虑

  • 不管用何种修正手段,都要同时作用在开发集与测试集上(开发集是一个目标,当你命中目标之后,希望算法能够推广到测试集上,这样能够更高效的在来自同一分布的开发集和测试集上迭代)
  • 同时检验算法判断正确和错误的例子,错误的可能还有正确的,反之同理,若是只修改正确的,对算法的偏差可能会变大

上述的两种注意事项实现较麻烦,因此也通常不会这么做,原因是:如果分类器很准确,那么判断错的次数比判断正确的次数要少得多

亲自花时间去检验错误是非常值得的



Training and testing on different distributions

深度学习对训练数据的“胃口”很大,当你收集到足够多带标签的数据构成训练集时,算法效果最好,即便它们都来自于和开发集与测试集不同的数据来训练,这里有一些做法可以来处理训练集与测试集存在差异的状况

以下题为例:

对于来自于web与app的🐱图

我们要通过上面的数据,划分数据,给出以下两种方案:

Option1

Option2

我们的需求是建立一个系统,令其在处理手机上传图片分布时效果良好,因此我们选择第二种,因为它精确的“对准”了目标

缺点在于训练集分布和开发集、测试集分布并不一样


Bias and Variance with mismatched data distributions

估计学习算法的偏差和方差来确定接下来的优先方向,但是当训练集和开发、测试集来自于不同分布时,分析偏差和方差的方式可能不同

通过对人类水平错误率、训练集错误率、训练 - 开发集错误率、开发集错误率进行分析,可以推断出可避免方差、方差、、数据不匹配问题各自多大


Addressing data mismatch(定位数据不匹配)

对来自不同分布的训练集与开发测试集,错误分析显示存在数据不匹配问题的状况,没有完全系统的解决方案,但可以尝试以下方案:

  • 亲自进行错误分析,尝试了解训练集与开发集的具体差异
  • 收集更多类似开发集和测试集的数据(包括人工合成)

Transfer learning(迁移学习)

神经网络从一个任务中习得知识,并将只是应用到另一个独立的任务中,即为迁移学习

假设已经训练好一个图像识别神经网络

可以是判断🐱🐕,我们想将其用于X光诊断,做法是,将最后一层以及进入最后一层的权重删掉,然后为最后一层重新赋予权重,让后将其放在放射诊断数据上训练

什么时候迁移学习是有意义的?

若你想从任务A学习,并迁移一些新知识到任务B,那么

  • 当A与B都有同样的输入x时,迁移学习是有意义的,
  • 当任务A的数据比任务B多得多时,迁移学习的意义更大(在想提高任务B的性能,因为B的每个数据更有价值 )
  • 任务A的低层次特征可以帮助B的学习,那么迁移学习更有意义一些

Multi-task learning(多任务学习)

在迁移学习中,步骤是串行的,只是从任务A学习,然后迁移到任务B,而在多任务学习中,步骤是并行的,即试图让单个神经网络同时做多件事,希望每个任务都能帮助到其他所有任务

以上图为例,我们想同时辨别图片中的车、警示牌、行人、路灯等,因此对于输入图像$x^{(i)}$,那么将不再是一个标签(label)$y^{(i)}$,而是有四个标签


因此,$y^{(i)}$是个$4*1$向量

与之对应的$Y$,及如上所示

与softmax回归的主要区别在于,softmax将单个标签分配给单个样本,而这张图可以存在很多不同标签

训练一个神经网络,试图最小化函数,就需要多任务学习,因为现在的需求是建立单个神经网络,观察每张图,解决4个问题

同时,多任务学习也可以处理只有部分物体被标记的情况

多任务学习什么时候有意义?

  • 训练的一组任务可以共用低层次特征
  • 通常情况下,每个任务的数据量都相当大
  • 多任务学习往往在以下场合更有意义:
    • 可以训练一个足够大的网络去完成所有任务
    • 因此多任务学习的替代方法是,为每个任务训练一个单独的神经网络

End-to-end deep learning(端到端深度学习)

举以下例子,

目标是输入x,比如说一段音频,然后将其映射到一个输出y(即这段音频的听写文本),

传统上,语音识别需要很多桥段的处理,首先会提取一些特征(MFCC),提取出一些低层次特征之后,可以应用机器学习算法,在音频片段中找到音位(声音的基本单位),将音位串在一起构成独立的词,然后将词串起来构成音频片段的听写文本,输出即是听写文本

端到端则是输入音频,直接输出听写文本

注意的是,端到端的方法适用于大规模数据进行训练,而较小规模的数据在传统流水线上效果反而更优秀 ,而如果是中间规模的数据,也可以使用中间件的方法,输入的依然还是音频,然后绕过特征提取,直接尝试从神经网络输出音位

比如人脸识别系统,当人接近传感器时,会先捕捉整体图像(中间件),再通过裁剪获取局部的人脸信息,再进行辨别

在数据对直接进行端到端学习有困难,而能较好地解决子问题时,通过解决子问题再回归到一端其实更为适合

端到端的优点:

  • 数据说话
  • 所需的手工设计的组件更少

端到端的缺点:

  • 需要大量数据
  • 排除了可能有用的手工组件

学习算法有两个数据来源,一个是数据,另一个是手工设计的组件、功能······

当尝试使用端到端深度学习构建深度学习系统时,关键问题在于数据量的多少,已有数据能否支持直接学到从x映射到y