- 机器学习策略(ML Strategy)
- 正交化(Orthogonalization)
- 单一数字评估指标(Single number evaluation metric)
- 满足和优化指标(Satisficing and optimizing metrics)
- 什么时候该改变开发/测试集和指标(When to change dev/test sets and metrics)
- 为什么是人的表现?(Why human-level performance?)
- 改善模型表现
- 进行误差分析
- 清除标注错误的数据
- 快速搭建第一个系统并进行迭代
- 使用来自不同分布的数据进行训练和测试
- 不匹配数据划分的偏差和方差
- 处理数据不匹配问题
- 迁移学习(Transfer learning)
- 多任务学习(Multi-task learning)
- 什么是端到端的深度学习
- 使用端到端的深度学习
结构化机器学习项目
机器学习策略(ML Strategy)
假设你正在调试你的猫分类器,经过一段时间的调整,你的系统达到了90%准确率,但对你的应用程序来说还不够好。你可能有很多想法去改善系统如集更多的训练数据、训练集的多样性还不够应该收集更多不同姿势的猫咪图片、更多样化的反例集、再用梯度下降训练算法,训练久一点、尝试用一个完全不同的优化算法,比如Adam优化算法、尝试使用规模更大或者更小的神经网络、试试dropout或者正则化、或者修改网络的架构比如修改激活函数,改变隐藏单元的数目之类的方法。
正交化(Orthogonalization)
搭建建立机器学习系统的挑战之一是,可以尝试和改变的东西太多太多了。比如有很多的超参数可以调。那些效率很高的机器学习专家有个特点,他们思维清晰,对于要调整什么来达到某个效果,非常清楚,这个步骤我们称之为正交化。
TV
如果调整这个其中一个旋钮图像的高度、宽度、梯形角度、平移位置全部都会同时改变,如果有这样的旋钮那几乎不可能把电视调好让图像显示在区域正中。这种情况下,正交化指的是电视设计师设计这样的旋钮,使得每个旋钮都只调整一个性质,这样调整电视图像就容易得多,就可以把图像调到正中。
Car
一辆车有三个主要控制,第一是方向盘,方向盘决定往左右偏多少,还有油门和刹车。就是这三个控制,其中一个控制方向,另外两个控制你的速度,这样就比较容易解读,知道不同控制的不同动作会对车子运动有什么影响。所以这里正交化的概念是指,想出像出一个维度,这个维度做的是控制车的转向角,还有另一个维度来控制车的速度,其余类似分别控制。
ML策略的正交化
- 训练集拟合得好不好,通过增大神经网络规模,或选用其他优化算法比如Adam,等等,来调整。
- 训练集拟合好了后,验证集拟合得好不好,可以通过正则化,或增大训练集规模来调整。
- 验证集拟合好了后,测试集拟合得好不好,不好则证明在验证集上过拟合了,可以增大验证集规模来调整。
- 训练集拟合好了后,在现实世界中表现效果如何,不好则说明验证集分布设置不正确或代价函数测量的指标不对,要通过改变验证集和代价函数来调整。
PS:需要注意的是,这也是为什么 early stopping 吴恩达不推荐用,因为同时影响一、二步。
单一数字评估指标(Single number evaluation metric)
无论是调整超参数,或者是尝试不同的学习算法,或者在搭建机器学习系统时尝试不同手段,有一个单实数评估指标进展会快得多,它可以快速告诉你,新尝试的手段比之前的手段好还是差。所以当团队开始进行机器学习项目时,推荐为问题设置一个单实数评估指标。
应用机器学习是一个非常经验性的过程,通常是有一个想法,再编程序,然后跑实验,看看效果如何,然后使用这些实验结果来改善现有的想法,然后继续走这个循环,不断改进你的算法。
比如说对于猫的分类器,之前你搭建了某个分类器A,通过改变超参数,还有改变训练集等手段,你现在训练出来了一个新的分类器B,所以评估你的分类器的一个合理方式是观察它的查准率(precision)和查全率(recall)
- 查准率(精确率、Precision):宁可漏掉,也不错杀,希望查出来的都是对的,我们预测为1的里,实际为 1 的是多少。,
- 查全率(召唤率、Recall):宁可错杀,也不漏掉,希望把对的都给查出来,实际为 1 的里,我们预测为 1 的是多少。
根据你的需求可以选择其中一个指标,但使用查准率和查全率作为评估指标的时候,有个问题,如果分类器A在查全率上表现更好,分类器B在查准率上表现更好,你就无法判断哪个分类器更好。如果尝试了很多不同想法,很多不同的超参数,希望能够快速试验不仅仅是两个分类器,如果有两个评估指标,就很难去快速地从多个中选出适合的那一个,所以我并不推荐使用两个评估指标,需要找到一个新的评估指标,能够结合查准率和查全率。
这是就是用 P 和 R 的调和平均数(倒数平均),称作 F1 分数
个例子中,可以马上看出,分类器的
分数更高。假设
分数是结合查准率和查全率的合理方式,所以要选择分类器
,淘汰分类器
。
满足和优化指标(Satisficing and optimizing metrics)
一般地说,如果你要考虑N个指标,有时候选择其中一个指标做为优化指标是合理的。所以你想尽量优化那个指标,然后剩下
个指标都是满足指标,意味着只要它们达到一定阈值,
如果你需要顾及多个指标,比如说,有一个优化指标,你想尽可能优化的,然后还有一个或多个满足指标,需要满足的,需要达到一定的门槛。现在你就有一个全自动的方法,在观察多个成本大小时,选出”最好的”那个。现在这些评估指标必须是在训练集或开发集或测试集上计算或求出来的。还需要做一件事,就是设立训练集、开发集,还有测试集。
什么时候该改变开发/测试集和指标(When to change dev/test sets and metrics)
比方说识别猫的模型,验证集上,模型 A 准确率 3%,模型 B 准确率 5 %,但模型 A 会推送一些色情图片。那么显然 A 是我们无法接受了,应该选 B 更好。
既然直接按准确率来的指标我们无法满意,那就应当设计新的指标,这时就要设计新的验证集指标
比方说对
其中一个修改评估指标的方法是,这里(与
之间)加个权重项即。
我们可以加入一个参数,比方说对 porn 惩罚 10 倍,或者 100 倍这样
如果你希望得到归一化常数,在技术上,就是对所有
求和,这样错误率仍然在0和1之间,即:
加权的细节并不重要,实际上要使用这种加权,必须自己过一遍开发集和测试集,在开发集和测试集里,自己把信息标记出来,这样你才能使用这个加权函数。
如果你的评估指标无法正确评估好算法的排名,那么就需要花时间定义一个新的评估指标。这是定义评估指标的其中一种可能方式(上述加权法)。评估指标的意义在于,准确告诉你已知两个分类器,哪一个更适合你的应用。关键在于,如果你对旧的错误率指标不满意,那就不要一直沿用你不满意的错误率指标,而应该尝试定义一个新的指标,能够更加符合你的偏好,定义出实际更适合的算法。
为什么是人的表现?(Why human-level performance?)

随着时间的推移,继续训练算法时,可能模型越来越大,数据越来越多,但是性能无法超过某个理论上限,这就是所谓的贝叶斯最优错误率(Bayes optimal error)。所以贝叶斯最优错误率一般认为是理论上可能达到的最优错误率,就是说没有任何办法设计出一个到
的函数,让它能够超过一定的准确度。例如,对于语音识别来说,如果
是音频片段,有些音频就是这么嘈杂,基本不可能知道说的是什么,所以完美的准确率可能不是100%。或者对于猫图识别来说,也许一些图像非常模糊,不管是人类还是机器,都无法判断该图片中是否有猫。所以,完美的准确度可能不是100%。

在准确率小于人类水平时,提升起来很快,超过人类水平时,提升起来越来越难,原因如下
低于人类水平时,
人类可以标记数据,增大数据规模;
人类可以观察算法处理的例子,分析为什么算法做错了;
你也可以更好地分析误差和偏差。
改善模型表现
想要让一个监督学习算法达到实用,首先,你的算法对训练集的拟合很好,这可以看成是你能做到可避免偏差很低。第二件是在训练集中做得很好,然后推广到开发集和测试集也很好,这就是说方差不是太大。
总结一下如果你想提升机器学习系统的性能,建议看看训练错误率和贝叶斯错误率估计值之间的距离,让你知道可避免偏差有多大。换句话说,就是你觉得还能做多好,你对训练集的优化还有多少空间。然后看看你的开发错误率和训练错误率之间的距离,就知道你的方差问题有多大。你应该做多少努力让你的算法表现能够从训练集推广到开发集,算法是没有在开发集上训练的。

偏差和方差要正交化地去优化
首先是减小偏差,方法有训练更大的网络模型、训练更久、使用更好的优化算法(momentum、RMSprop、Adam)、寻找更好的新神经网络架构(CNN、RNN)、更好的超参数(激活函数、层数、隐藏单元数)
其次是减小方差,方法有用更多的训练数据、正则化(L2、dropout、数据增强)、试用更好的神经网络架构或超参数。
进行误差分析
对于错误结果建立表格进行人工分析差错。进行错误分析,找一组错误样本,可能在你的开发集里或者测试集里,观察错误标记的样本,看看假阳性(false positives)和假阴性(false negatives),统计属于不同错误类型的错误数量。在这个过程中,你可能会得到启发,归纳出新的错误类型。总之,通过统计不同错误标记类型占总数的百分比,可以帮你发现哪些问题需要优先解决,或者给你构思新优化方向的灵感。
清除标注错误的数据
有时候预测错误也可能是标注数据的人真实标签标注的不对,这时候要不要处理,可以用误差分析的方法,就是抽取错误预测的样本做上面那样的表格看百分比,占了明显一部分,那就优先修正,否则就不着急,当然最后想修正完全可以去做。浏览一下训练集,检查一下这些标签,并修正它们也没什么害处。有时候修正这些错误是有价值的,有时候放着不管也可以,只要总数据集总足够大,实际错误率可能不会太高。我见过一大批机器学习算法训练的时候,明知训练集里有个错误标签,但最后训练出来也没问题。
如果这些标记错误严重影响了你在开发集上评估算法的能力,那么就应该去花时间修正错误的标签。但是,如果它们没有严重影响到你用开发集评估成本偏差的能力,那么可能就不应该花宝贵的时间去处理。
修正时,需要注意的几个问题
要对验证集和测试集都修正,以确保二者来自同一分布一般来讲,预测错误的比较少,预测正确的比较多,我们可能懒得一个一个查预测正确的样本,但是如果修正了预测错误的部分后效果不是很好,或者你觉得占比太大,那么有必要考虑对预测正确的样本也一个一个地查。训练集太大了,没有一个一个查的可能性,于是你的 训练集 将和 验证集/测试集 来自于不同分布。学习算法其实非常鲁棒,训练集的分布稍稍不同一般来讲没太大关系,验证集和测试集肯定要保证同一分布。
快速搭建第一个系统并进行迭代
如果你正在开发全新的机器学习应用,你应该尽快建立你的第一个系统原型,然后快速迭代。如果你正在考虑建立一个新的语音识别系统,其实你可以走很多方向,可以优先考虑很多事情。
建立这个初始系统的所有意义在于,它可以是一个快速和粗糙的实现(quick and dirty implementation)。初始系统的全部意义在于,有一个学习过的系统,有一个训练过的系统,让你确定偏差方差的范围,就可以知道下一步应该优先做什么,让你能够进行错误分析,可以观察一些错误,然后想出所有能走的方向,哪些是实际上最有希望的方向。
使用来自不同分布的数据进行训练和测试
深度学习算法对训练数据的胃口很大,当你收集到足够多带标签的数据构成训练集时,算法效果最好,这导致很多团队用尽一切办法收集数据,然后把它们堆到训练集里,让训练的数据量更大,即使有些数据,甚至是大部分数据都来自和开发集、测试集不同的分布。在深度学习时代,越来越多的团队都用来自和开发集、测试集分布不同的数据来训练,这里有一些微妙的地方,一些最佳做法来处理训练集和测试集存在差异的情况,
举例
比如识别猫,用户上传的有10000张图片,从网页下载了200000张图片,一种方式是把所有这些照片混合,然后划分训练集验证集测试集,然而你真正关心的预测目标是用户上传的这种可能有点模糊的图片所以这种方式不好
一般推荐用下面这种方式,如果你觉得验证/测试集用不上 10000,你可以抽出一半划分成 200000+5000 / 2500 / 2500,如果你觉得 10000 对于验证和测试并不算多那就直接 200000 / 5000 / 5000。
不匹配数据划分的偏差和方差
对于 偏差/方差分析不妨思考,训练集上误差1%,验证集上误差10%,如果不同分布,那么真的是方差大过拟合了吗?不一定,也可能单纯是数据不匹配导致的那要怎么判断把训练集再划出一部分做一次验证,这部分来自原训练集里,同分布,于是可以判断是否真的过拟合即 训练集、训练-验证集、验证集。
举例
比如在这三个集合上分别 1%、2%、10%,那么说明没过拟合,但是数据不匹配要解决
比如在这三个几何上分别 1%、9%、10%,那么说明过拟合了,首先解决过拟合,可能完全由过拟合导致的在验证集上误差大。如果解决过拟合后,验证集表现好了,那就说明完全过拟合导致,这样解决完就OK了。如果解决过拟合后,验证集方差依然很大,那说明除了过拟合,数据不匹配问题也是有着影响的,也要解决。
处理数据不匹配问题
如果发现有严重的数据不匹配问题,通常需要做错误分析,尝试了解训练集和开发测试集的具体差异。技术上,为了避免对测试集过拟合,要做错误分析,人工去看开发集而不是测试集。一种方法就是多收集类似于验证集和测试集的数据,另一种方法就是人工合成数据。
比如语音识别,既然没有噪音,那就制造噪音,把没噪音的数据和汽车鸣笛噪音合成一下,这是完全可行的。但是10000个小时的语音数据,反复使用 1 个小时的汽车噪音,这一个小时的汽车噪音会过拟合,特别是,如果这组汽车里录的音频可能是你可以想象的所有汽车噪音背景的集合,如果你只录了一小时汽车噪音,那你可能只模拟了全部数据空间的一小部分,你可能只从汽车噪音的很小的子集来合成数据。
再比如汽车图像,假设你在研发无人驾驶汽车,你可能希望检测出这样的车,然后用这样的框包住它。很多人都讨论过的一个思路是,为什么不用计算机合成图像来模拟成千上万的车辆呢?事实上,这里有几张车辆照片(下图后两张图片),其实是用计算机合成的,我想这个合成是相当逼真的,我想通过这样合成图片,你可以训练出一个相当不错的计算机视觉系统来检测车子。
如果你认为存在数据不匹配问题,建议做错误分析,或者看看训练集,或者看看开发集,试图了解这两个数据分布到底有什么不同,然后看看是否有办法收集更多看起来像开发集的数据作训练。
我们谈到其中一种办法是人工数据合成,人工数据合成确实有效。在语音识别中这是可行的。但当你使用人工数据合成时,一定要谨慎,要记住你有可能从所有可能性的空间只选了很小一部分去模拟数据。
迁移学习(Transfer learning)
深度学习中,最强大的理念之一就是,有的时候神经网络可以从一个任务中习得知识,并将这些知识应用到另一个独立的任务中。所以例如,也许你已经训练好一个神经网络,能够识别像猫这样的对象,然后使用那些知识,或者部分习得的知识去帮助您更好地阅读x射线扫描图,这就是所谓的迁移学习。
这个原理是什么呢,你在猫识别中已经训练学会的一些知识可以迁移,前面一些层可能实现了一些点、线或简单图案的识别,可以接着拿来用。对猫的识别叫作 预训练,进一步对放射科图像识别叫作微调。
迁移学习的意义是什么呢,放射科的图片可能很少,而猫的图片可能很多,放射科图片太少以至于直接训练效果很不好,所以可以用猫预训练,完成二者共通的知识的学习。
另一个例子是语音识别,最后你可能想要的是唤醒词触发,前者数据很多,后者很少。你已经学会了识别语音内容,只需要更进一步更好地识别唤醒语,那这时候,首先微调肯定要重新随机一个输出层参数,然后你可能考虑前面的知识全都有意义都不用变了,于是在输出层前新增两层隐藏层来训练。
迁移学习的条件
- 任务A和任务B有相同的输入
- 任务A有比任务B多得多得数据
- 任务A得低层特征对任务B的训练有帮助
迁移学习最有用的场合是,如果你尝试优化任务B的性能,通常这个任务数据相对较少,例如,在放射科中你知道很难收集很多X射线扫描图来搭建一个性能良好的放射科诊断系统,所以在这种情况下,你可能会找一个相关但不同的任务,如图像识别,其中你可能用1百万张图片训练过了,并从中学到很多低层次特征,所以那也许能帮助网络在任务B在放射科任务上做得更好,尽管任务B没有这么多数据。迁移学习什么时候是有意义的?它确实可以显著提高你的学习任务的性能,但我有时候也见过有些场合使用迁移学习时,任务A实际上数据量比任务B要少,这种情况下增益可能不多。
多任务学习(Multi-task learning)
迁移学习是串行的(从任务A里学习只是然后迁移到任务B),而多任务学习是并行的多任务学习只需要最后输出层几个任务就几个单元多标签即可。
例
假设你在研发无人驾驶车辆,那么你的无人驾驶车可能需要同时检测不同的物体,比如检测行人、车辆、停车标志,还有交通灯各种其他东西。比如在左边这个例子中,图像里有个停车标志,然后图像中有辆车,但没有行人,也没有交通灯。

和 Softmax 多分类区分
多任务学习不是一个结果,而是多个结果,比如你预测一张图有没有人、有没有车、有没有红绿灯,这不是互斥的
多任务学习的条件
- 多个任务间有共同的低层特征
- 多个任务间的数据量差不多大

输入不同可以靠合并解决
然后需要了解的是多任务学习效果一般来讲一定不会比独立来做的差,不妨想象一下你的输入可能更多了或者合并维度更大了,尤其是共通的低层,训练得一定更好,所以最后结果肯定要好的能使得多任务效果比独立差的唯一原因只有网络规模不够大
多任务学习往往在以下场合更有意义,当你可以训练一个足够大的神经网络,同时做好所有的工作,所以多任务学习的替代方法是为每个任务训练一个单独的神经网络。在实践中,多任务学习的使用频率要低于迁移学习。很多迁移学习的应用,你需要解决一个问题,但你的训练数据很少,所以你需要找一个数据很多的相关问题来预先学习,并将知识迁移到这个新问题上。但多任务学习比较少见,就是你需要同时处理很多任务,都要做好,你可以同时训练所有这些任务,也许计算机视觉是一个例子。在物体检测中,我们看到更多使用多任务学习的应用,其中一个神经网络尝试检测一大堆物体,比分别训练不同的神经网络检测物体更好。平均来说,目前迁移学习使用频率更高,比多任务学习频率要高,但两者都可以成为你的强力工具。
什么是端到端的深度学习
以前有一些数据处理系统或者学习系统,它们需要多个阶段的处理。那么端到端深度学习就是忽略所有这些不同的阶段,用单个神经网络代替它。
端到端就是流水线,分成多任务多步骤进行,打破了常规的一步搞定思维,非常好用打个比方,百度上班打卡的人脸识别直接一步搞定行吗?挺大一个人训练预测人脸这样效果并不好,那么我们怎么做的呢第一步,预测人脸位置,把人脸那一块图片截出来放大,然后第二步做人脸识别,这样效果就很好。
所以端到端深度学习系统是可行的,它表现可以很好,也可以简化系统架构,让你不需要搭建那么多手工设计的单独组件,但它也不是灵丹妙药,并不是每次都能成功。
使用端到端的深度学习
是否使用端到端的深度学习,关键在于了解它的优缺点
所谓端到端,就是 X->U->V->W->…->y,从 X 端到 y 端的映射
优点
- 第一,让数据说话:X 适合预测 U,你是让数据自己学习,并且你是确切地表示成 U,而不是你直接 X 预测 y 为了利用到一个隐藏的 U 而加入的 M、N 之类的人工设计的过程。自己学习如何到 U 肯定更好。M、N可能并不合适,并含有一些人为偏见,比如 cat,你认为中间表示成 科 哎 特 这样的音节比较好,实际上这毫无意义,这就是人工过程的偏见。
- 第二,就像上面所说的那样,一步步分阶段分步骤分任务地预测,因此你不需要花太多时间取人工设计功能、人工设计中间表示方式。

缺点
- 第一,可能需要大量的数据。比如百度上班打卡人脸识别,不用端到端,那你就只需要人身照、以及是否匹配的标签。而端到端,那你第一步就要有框出人脸部分的标签数据。你想一想分任务过程中的真实标签肯定全都要人工标记的,用预测的来做下一轮训练那就没意义了。而且当你选择端到端,就是放弃了许多手工设计,全靠预测意味着小样本学习效果肯定不好。中间任务为了效果更好,你也可能针对性地再去收集一些额外数据。所以说数据量肯定要很大的。
- 第二,端到端的学习排除了可能有用的手工设计组件。机器学习研究人员一般很鄙视手工设计。但是如果你数据量不够大,人工特征工程就很有意义。而且人工特征工程也是把人类知识注入模型的一种途径,尤其在小样本学习中非常有用。当然优缺点中我们都说过这个,人工过程就是一把双刃剑。
