3 结构化机器学习项目 ML策略
假设你正在训练一个分类器模型,一段时间后其准确率达到了90%,之后你想再提高一点,但很有可能尝试了许许多多的办法努力了六个月之后,效果微乎其微。我们将学习一些分析方法,避免你南辕北辙。
正交化
建立机器学习系统的挑战之一是,有太多的超参数可以调整和尝试,而我们可以注意到高效的机器学习人员,都非常清楚需要调整什么,这一过程称之为正交化。
例如一个老式的电视右边有一排旋钮,一个控制纵向缩放,一个控制横向缩放,一个控制梯形化程度,一个进行移动画面,一个进行旋转画面等等,又或者一辆汽车各个操作有其自己的功能,而不是设计一个按键,使其同时完成两个以上的功能,这样就会使得我们失去对单一功能的精准控制。正交化指两个变量呈90°角,通过正交控制,能精准的控制其中的每一个变量使其达到你想要的效果。
从训练集、开发集、测试集到真正使用一个模型,中间你会发现各种各样的异常情况,而针对每一步产生的情况,都有对应这种情况的解决办法,后面会慢慢学习,这里的例子主要是为了再次体会正交化。之前提过,提前结束梯度下降是一个很多人都在使用的正则化的方法,不过吴恩达个人不建议使用,因为它同时控制了提高开发集表现和降低训练集拟合程度两件事情,这违背了正交化的思想。
单一数字评估指标
无论使用哪一种方法,我们常常应当设置一个单一的量化评估指标。
例如上表中有两个分类器A和B,精准率表示训练集上的准确率,召回率表示在开发集上的准确率。可以看出,精准率上A的表现更好,召回率上B的表现更好,你就无法判断哪个分类器更好了。并且如果你尝试许多不同的算法,尝试调整更多的超参就会同时有许多的分类器供你选择,以便你可以在这个基础上继续迭代。所以与其使用两个指标纠结,不如使用一个更加综合的指标F1分数,简单的理解就是精准率P和召回率R的(调和)平均值。一个好的验证集(开发集)和一个好的单一评估指标可以提高迭代效率。
再举一个例子,这是一个算法应用在各个国家时的错误率,当选择很多时,很难快速决策,那么就设置一个平均值,能够直接找出C是表现最好的。
满足和优化指标
将你关心的所有问题综合成一个单一指标并不是一件容易的事,所以有时需要建立满足和优化指标。
例如一个分类器,除了精确度你还关心它的运行时间,我们可以设立一个单一指标cost然后给它一个将两个指标结合的公式,但二者的线性加权和看起来有一些刻意。所以当你需要一个分类器在确保运行时间的情况下提供最大的准确率时,你可以设置一个满足指标即时间不能大于100ms,然后尽可能的优化准确率。也就是说如果你有N个指标,选择其中一个加以优化是比较合理的,那么其余的就都是满足指标,意味着他们只需要满足条件即可。
再举一例,假设你在建立一个检测唤醒词(触发词)系统,例如用hey siri唤醒苹果设备,
训练、开发、测试集的划分
机器学习的流程是你有很多想法,在训练集上训练了很多模型,并优化他们在开发集上的表现,最后选择一个最好的在测试集上测试它。
首先确保开发集和测试集来自相同的分布,因为我们通常在设立一个开发集和评估指标时,相当于设立了一个目标,我们所有的工作都是为了更靠近这个目标。如果测试集的数据和开发集测试不同,相当于我们对着一个目标努力了很久而却在另一个目标上测试了。
如果你有几百几千或者上万个样例,通常用七三分训练集和测试集,或者六二二加上开发集。但如果有百万级别以上的大量数据,训练集会占用更大的比例,开发集和测试集占1%就足够了。
调整开发集\评估指标
如果你的一个单一指标显示在A和B两个猫分类器中A的表现更好,但A分类器会偶尔将色情图片识别为猫而提供给用户,这就使A分类器不管准确率有多高也不能投入使用。所以这个时候应该马上更换一个新的评估指标而不要凑合着用老的,你可以在训练集和开发集中找出色情图片并标识,并在最终的评估指标中给它一个权重。
机器学习问题一般第一步要先确定目标,也就是一个可以表示你最终目标的评估指标,至于如何优化你的算法使之满足你的目标是第二步。此处吴恩达想再次强调正交化思想,把要做的事情一步一步分清楚。
再举一例,如果两个A和B猫分类器在开发集和评估指标上看A的效果更好,但在实际应用中,会发现B的效果更好。你发现原因是你的所有数据集都是在网上找到的更专业的拍摄、更好的取景、更清晰的猫的正面的图片。而你的用户在实际应用中都是用手机拍摄的猫的局部或是非常模糊或是奇怪的表情的猫。这时也需要调整开发集和评估指标,实质上是你的开发集、测试集和你真正关心的那一部分数据不统一。你真正关心的是用户在实际应用中的效果而不是理想情况下的效果。
机器学习与人的表现
机器学习尤其是深度学习的发展,使得其在很多领域的表现超越了人的表现。一个深度学习模型在初期会以很快的速度接近人类的表现,超越人类以后进步的速度会随着时间日趋放缓,逐渐接近但不会超过一个理论最佳水平,称为贝叶斯最优误差。为什么超越人类的表现后,进步速度会放缓?人类的表现在许多任务中都离贝叶斯最优误差不远,算法超越人类后并没有很大的改善空间。只要你的表现还不如人类水平就可以通过某些工具来提高。对于人类擅长的任务,如图片、语音、文字的阅读和识别,只要你的算法还不如人类,你就可以让人类帮你标记数据进行学习,也可以让人类帮你分析为什么算法做错了,有很多策略都可以优化你的算法。然而一旦你的表现优于人类,这些方法就很难用了。
可避免偏差
例如你在训练一个猫分类器,人类在这方面已经表现的相当不错假设人类错误率是1%,而此时你的算法在训练集和开发集上分别是8和10%,那么这个时候算法实际上都没有很好的拟合训练集,也就是具有大偏差,可以尝试训练更大的神经网络或者训练更长的时间。但如果这个任务中,人类的错误率高达7.5%,那么现在这个算法应该说表现的很不错,这时的任务主要是消除方差,也就是使训练集和开发集的表现更相近。另外提一下,在计算机视觉任务中,人类的表现可以作为贝叶斯误差的代理量,因为人类非常擅长视觉识别任务。
训练集上的误差到贝叶斯误差中间的一段距离成为可避免偏差,训练集上的误差和开发集上的误差之差则是对方差问题的一种度量。所以对比两个例子,就可以发现在二者在偏差和方差上各有侧重,所以最终的解决方案也就不同。
human performance (人类表现)
上图中举例了一个各种类型的人去判断右边这张片子的准确率,包括了普通人,普通放射科医生,有经验的医生,和有经验的专家团队。那么我们应当选最后一个专家团队作为人类表现,以及贝叶斯误差估计值。因为我们总有办法可以让误差缩小到0.5%。 然后再对比偏差方差,决定该优化哪一个。
超越人类:
我们之前讨论过,当性能接近或超越人类水平时,机器学习的进展会越来越慢。但是为什么?
如图左边这一列,展示了四种情况下是误差,那么我们的贝叶斯误差估计值应当取team of humans,这时可以看到方差的优化空间更大,应当关注方差。而再看右边这一列,你的训练集和开发集误差都已经优于我们所已知的贝叶斯最优误差,你就不知道我们是算法是否过拟合?还是说存在一个比我们知道的更低的贝叶斯误差?也就是说我们没有足够的信息来确定下一步该怎么做,所以效率就降低了。此外,如果你的误差已经比人类通过团队讨论得出的误差还要低,那么本来就很难再依靠人类直觉判断如何优化。
注意,不要形成对以上这种人类的表现作为最佳状态的思维定式,这仅仅适用于语音图像识别等人类擅长的领域。在其他许多领域,例如智能广告或商品的推荐、导航时长预估、判断某个人是否会还贷等机器学习都已经取得了远远超过人类的表现。但注意,这几项内容都是从结构化的数据中进行学习的,例如你常点击的广告或商品的数据库。这些都是非自然感知的问题。当然,最近的深度学习发展到在某些自然感知领域也超越了人类表现。
误差分析
假设你在做一个猫分类器,在开发集上的正确率只有90%,而你发现在数据集上,你的分类器误将一些狗识别成猫了,为了使猫分类器在识别狗的问题上表现的更好,那就需要训练分类器认识一些狗的特征,所以问题就变成你是否应该开启一个侧重于狗的项目?这可能要花上好几个月。所以现在要先看看所有分错的图片,假设一百张分错的图片中只有五张是狗,那么即使解决这个问题综合性能提升也不大。在机器学习中我们称之为表现上限,也就是说即便你完全解决了这个问题,错误率也只能提高到9.5%。但是如果分错的狗占比相当大,那么也许这个方向的努力是值得的。
通常情况,你可以做一个表格,看看在开发集和测试集上的错误,各个情况分别占比多少。
标记错误的数据
如果你的训练集出现了随机标注错误的情况,那么如果能修正是最好的,不能修正问题也不大。深度学习对随机的错误表现很稳健。但如果是系统错误,例如你总是把白色的狗错误标记成猫,那问题就大了。
对于开发集和测试集上因为标记错而出错的数据,你可以在上一节讲到的误差分析时,在表格中加一列(我不知道为什么没有讲到这里直接从总错误中减掉标错的就行了)。通过它在总错误中的占比来判断是否需要人工将标记错的标签改回来。因为实际上你的开发集是用来在A\B\C几个模型中选择一个较好的,所以要看标签标错的错误占比是否会影响你的判断。同时,如果你对开发集做了什么修正,建议同时修改测试集,以确保两者来自于相同分布。
另外对于标错的数据,还有算法预测对的那一部分,可能实际上也只是标错了。
最后,有些研究者和工程师不愿意研究数据,实际上花点时间人工检查一下我们的数据,十分有助于确定下一步应该做什么。
快速搭建系统
如果你在进行一个机器学习项目,应该快速构建第一个系统,然后进行迭代。因为每一个领域都有很多很多的问题值得研究,例如语音识别就有几十个问题可以优化解决包括各种类型的噪音、方言、结巴、麦克风问题等等。但我们一开始无法考虑到所有的问题,应该先快速的搭建一个系统,然后进行误差分析,考虑偏差、方差等等,再具体规划下一个要解决的问题是什么。
但是,这个建议不适用于你熟悉或是已有大量文献可以做参考的情况,这样你一开始就可以搭建一个复杂的系统。
训练集的数据分布与开发集和测试集不同
训练集应该有足量的已标记数据用于训练,这就导致许多团队将能找到的任何数据都塞进训练集。因此越来越多的团队可能都在使用与开发集来自不同分布的训练集。
注意,不要将现有的所有数据全部混合然后再进行分集,因为这会导致你的开发集中的许多数据都不是你的真实目标,你将来会为你不关心的数据做出相当大的努力。例如你在做猫分类器,那就将用户拍的图片设置为开发集和测试集,其他在网上爬来的图片用做训练集,如果用户拍摄的照片足够多,也可以分一点到训练集。再例如你需要做一个后视镜语音导航,那么用户说的具体地址的语音就是你真正关心的数据,而你的训练集很可能是大量其他领域的语音数据。
当出现题目所述的这种情况时,对偏差和方差的判断也会有所变化。例如一个开发集误差大于训练集误差的算法,原本我们认为其方差过大,不能很好的泛化到开发集。但由于两者来自不同分布,所以你很难说这一部分误差有多少是因为算法在训练时没有接触过开发集中的数据。这时我们定义一个新的数据集叫训练-开发集,它的数据随机取自训练集。这样训练集和这个新的开发集就来自相同分布,但注意取出训练-开发集后,原训练集就要剔除这一部分数据。这时,你又多了一个可以参考的数据集,就很容易判断最终产生的误差到底是因为数据不匹配还是确实是高方差。当然不要忘了,如果训练集误差和贝叶斯最优误差都很大,那是大偏差问题。最后如果你的开发集要比测试集表现更好,可能是开发集过拟合了,换一个更大的开发集。
(这个视频后面还有例子,如果需要再看)
数据不匹配
需要再看
迁移学习
有时,你也许可以将一个识别猫的神经网络迁移到识别X光照片的。假设你有一个已经训练好的猫分类器,这时只需将最后一层输出层重新随机设定一个参数,然后放在X光样本上学习,如果数据量较小可以只学习最后一层,如果有一个大数据量,可以将所有层都重新学习。这个训练的初试化阶段被称为预训练。
之所以这可能起作用,是因为你在图像识别问题中学习到的边界检测、曲线检测、明暗对象检测等低层次的信息,也许可以帮助你更好的进行放射扫描结果的诊断。
当你在被迁移的模型中拥有大量数据,而在需要新解决的问题上拥有较少的数据时,迁移学习是有用的。
(未完待续)
多任务学习
可以训练一个神经网络来完成多任务,例如判断一个图片中是否有汽车、红绿灯、行人、交通标志。那么每个图片的输出就是一个思维列向量。(1,0,1,0)表示有汽车和行人但没有红绿灯和交通标志。
(详情再看)
端到端的深度学习
利用一个庞大的神经网络也实现一个流程的事务,直接输入原始特征,输出预测结果。