前言
本系列文章是吴恩达深度学习攻城狮系列课程的笔记,分为五部分。
这一部分讲了机器学习的优化策略,从宏观的角度指导优化的方向。
我的笔记不同于一般的笔记,我的笔记更加凝练,除了结论以及公式,更多的是对知识的理解,结合课程可以加速理解,省去很多时间,但是请注意,笔记不能替代课程,应该结合使用。
传送门
结构化机器学习项目,我建议放在最后看。
首先学这一节对你后面的学习没有影响,我就是跳过去学的。而且他更多的讲的是策略,尤其是举了很多后面的例子,你听了不仅不太好懂,而且没啥意思,所以我建议放在最后看。
神经网络与深度学习(Neural Networks and Deep Learning)
改善深层神经网络:超参数调整,正则化,最优化(Hyperparameter Tuning)
卷积神经网络(Convolutional Neural Networks)
序列模型与循环神经网络(Sequence Models)
结构化机器学习项目(Structuring Machine Learning Projects)
结构化机器学习项目(Machine Learning Strategy)
机器学习策略概述
所谓的策略,就是给你一个最有前景的优化方向。
比如现在的准确率是90%,要想提高表现(实际上一个好的表现不一定只是准确率),有很多种方式,但是有的方式可能很有用,也可能一点用都没有,选错了就可能浪费大量的时间和钱,如何选择最有价值的方法,就是这里要提到的策略。
正交化(orthogonalization)
评价一个机器学习项目一般分成四步:
- 训练集拟合
- 开发集拟合
- 测试集拟合
- 现实世界适用
对机器学习项目可以进行大量的修改,理想中的修改应该只会带其中一个环节有影响,这就是正交化。
正交化不好的反例就是提前终止训练,这可以减少对训练集的拟合,但是会同时增加对开发集的拟合,同时影响到两个环节,就是正交化做的不好。
实际上,并不能完全正交化,只能尽量。
评价指标
数字评估指标的单一性
如何对比调整前后的模型哪个更好?
最简单的办法是指定单一的数字评估指标,这样非常直观迅速。
但是有个问题就是,评价一个东西往往没有那么简单,仅仅用单一指标往往无法评价的很好。所以肯定需要折中。
常见的指标有:
- precision(查准率):预测为真的值中,实际为真的值占比。
- recall(查全率):实际为真的值中,被预测为真的占比。
但是这两个各有弊端,通常需要折中。比如100%的查准率,只能保证说他真就是真,不能保证那些预测为假的不是真。又比如100%的查全率,只能保证所有真值都被预测出来,不能保证有假的被错认成真的。
折中的结果就是F1 Score(Precision和Recall的调和平均Harmonic mean),这样将两个指标合并起来就可以快速判断那个更好,更快地迭代。
推广一下,以后肯定是要结合多种指标的,到时候就会有一个更好的单一指标去作为这若干指标的代表。
满足指标与优化指标
- 满足指标:必须满足的,前提条件。但是反过来,只要满足了,就不需要再优化了,或者说就已经不需要再比较了。
- 优化指标:尽可能的优化
通过以上两点可以看出,前面所说的唯一指标,应该指所有优化指标的综合,并不包括满足指标。
满足指标应当是单独列出,当做一个门槛使用。
即,1+N个指标。1个优化指标,N个满足指标。
数据集划分
数据集区分
现代数据集分成三部分:样本集、验证集(开发集)、测试集。
dev set有时候叫hold out cross validation set,即保留交叉验证集(验证集)。
Ripley, B.D(1996)在他的经典专著Pattern Recognition and Neural Networks中给出了这三个词的定义。
- Training set: A set of examples used for learning, which is to fit the parameters [i.e., weights] of the classifier.
- Validation set(dev set): A set of examples used to tune the parameters [i.e., architecture, not weights] of a classifier, for example to choose the number of hidden units in a neural network.
- Test set: A set of examples used only to assess the performance [generalization] of a fully specified classifier.
翻译:
- 训练集:学习样本数据集,通过匹配一些参数来建立一个分类器。建立一种分类的方式,主要是用来训练模型的。
- 验证集:对学习出来的模型,微调分类器的参数,如在神经网络中选择隐藏单元数。验证集还用来确定网络结构或者控制模型复杂程度的参数。
- 测试集:主要用于测试训练好的模型的分类能力(识别率等)
简化:
- 训练集:训练模型
- 开发集(验证集):测试参数,以及各种类型的模型,寻找最好的方案。
- 测试集:最后再把最好的模型验证一下,并不涉及到模型修改。
重点在于区分开发集和测试集。
开发集和测试集应该属于同一个分布。否则在开发集上表现最好的模型在测试集上就会出问题。
以前是没有测试集的,基本是7:3的训练:验证,但是你直接把验证好的模型放到现实中还是容易出问题,所以test set相当于最后把关。
然而有一个疑点,既然都分布相同了,那测试集和开发集有区别吗?其实,同分布是不可能的,我认为,适度的不同分布正是检测泛化性能的机会,所以人们都是在test set上检测泛化性的。
数据集划分比例
小样本(1k左右):7:3或者6:2:2
即,小样本的时候可以不使用测试集,实际上很多人把开发集叫成测试集,但是严格来说,所谓的30%的测试集实际上是开发集。
大样本(超过1w,比如100w):98:1:1,总之随着样本增大而增大训练集的比例,毕竟训练好了才能测好。
什么时候改变指标/开发集/测试集
当指标不能准确地反应目标用户的意志的时候,就应该换了。
或者说,虽然你的指标很高,但是效果却不满意,好比枪打的很准,却不是你想要的目标。
这个时候就应该调整指标,适应你的目标。
当然,也可能是你的开发集,测试集出了问题,这个问题通常出现在你认为的好样本和实际场景有偏差,比如你都是用高清高质量图像训练的,结果现实场景都是渣图,自然指标定的再好也没用。
人类表现
贝叶斯水平-人类水平-机器学习水平
首先是有两个水平,一个是人类水平,另一个是贝叶斯最佳错误率水平。这个水平代表了理论上最好的水平,这往往受限于样本本身,比如你给的图片就很垃圾,那么准确率就不可能是100%。
机器学习的表现发展有一个曲线,在达到人类水平之前,增长速度是很快的,达到人类水平以后,增长速度会逐渐变慢,直到趋近于贝叶斯最佳错误水平。
一种解释是,超过人类的表现,人类就难以理解了,也难以制造合适的样本,毕竟样本是从人类身上出来的。
我的猜想是,前面可以通过仿生技术,参考人类本身而取得进步,但是超过人类以后,就是一种创造了。
bias and variance(偏差和方差)
bias=贝叶斯表现-训练集表现
variance=训练集表现-开发集表现
当训练集表现和人类表现差距较大时,这就属于bias,减少bias就是提高表现。
当训练集表现和人类表现差不多的时候,或者远小于variance的时候,或者无法提升的时候,应该考虑降低variance,即减少训练集和开发集之间的差异,追求好的泛化性。
通常这个bias叫做avoidable bias,是贝叶斯表现-训练集表现,而不是绝对的不可达到的最好表现。
深入理解“人类表现”
人类水平也有不同定义,分新手,平均,专家,专家团
新手级别只能说是及格了。
平均水平(typical )可以说是实用。
专家水平已经具备大面积应用的潜力。
专家团级别的已经几乎是人类极限,所以可以用作贝叶斯错误的估计。
超越人类表现
当超越人类表现以后,甚至是超越人类最好表现以后,就已经没有前进的方向了,因为你已经无法计算avoidable bias了,或者说只能以理想中的完美表现作为方向了。
如果要超越人类,那就要获得比人类标注更好的,更多的数据,这就涉及到无监督学习之类的了,总之,要想超越人类就别想着从人类身上学习了,比如要想获得更好的嗅觉,或许可以考虑去狗的身上发现答案。
总结:改善模型表现的流程
首先确定一个好的指标
然后在三个数据集上跑
比较bias和variance,采取某种正交化方法进行优化
- 对于bias,可以采用更大的数据集,更好的训练算法,更好的架构,更好的超参数
- 对于variance,可以使用更多数据,加正则化,更好的架构,更好的超参数
从这里就可以看出所谓的正交化并不一定就是完全的正交化,只能说比较正交。
如此循环,直到逼近,超越人类表现
具体实施
误差分析(error analysis)
误差分析基本思路
误差分析的目的是抓出主要问题。主要问题具备的性能上限比较高,次要问题可能花很大精力最后提高的性能有限。
- 获取大量错误样本(比如100个)
- 手工标注一个表格,每一行是一个错误样本,每一列是错误类型,表示因为什么而错,最右边一列可以写上辅助内容,最下边一行可以写上错误类型占比。
- 比例比较大的就是主要问题,主要问题可能有两三个
- 针对性的对系统进行优化,如果问题比较多,可以分几个团队做
清除标注错误的数据
有时候,问题不是出在模型,而是出在样本上了,所以可能要清洗掉有问题的数据。
一般来说,考虑到人本身就会有失误的几率,样本出现偶尔的,随机性的失误是完全正常,合理的,学出来的模型也会继承这种微弱的失误几率,影响不大。
但是,如果是系统性错误,那这个系统错误也会被学习到,总之就是有什么问题就会学到什么问题。如果人故意标错,或者这个人是一个红绿色盲,那么这个模型也会被教坏,学出来也就是个红绿色盲。
这个错误也可以放到上一节说的表格里。
- 如果影响比较大,那必然是系统错误,这就要动手清理一下了。
- 如果影响不大,但是有两个模型在开发集中表现相似,比如一个2.1%,另一个1.9%,但是光是样本标注造成的错误就有0.6%,很难说这两个模型到底那个好,这时就得解决了主要问题才能进行下一步的提升。(其实这种本质上还是1的情况,若不是他影响大,怎能左右的了结果呢?)
补充
- 处理错误的时候同时应用在dev和test两个数据集上,保持同分布特性
- 检测所有样本,包括正确的样本(一般没人做,因为太麻烦了,付出和回报不成比例)
- 允许训练集和开发/测试集有轻微的不同分布,但是尽可能保证开发和测试同分布。
- 虽然手工处理错误数据听起来很low,但是实际效果会比较好,要实事求是。
粗略搭建,快速迭代
项目初期的问题在于可以走的方向太多了,如果想一上来就走完那必然会出问题。
如果你具有大量的经验,文献积累,那可以一上来就搞复杂的。
但是如果你没有基础,最好的方式就是先大概选定一个方向,粗略地搭建一个系统,之后再快速迭代。只有先迈出第一步,才能有更多的视野,获取更多的信息,更好地走出下一步。否则,即使你深思熟虑,你也会受到信息的限制,第一步走不好。
- 建立数据集和指标(metric)
- 快速开发
- 使用bias/variance/误差分析等技术进行优化
数据不匹配相关的处理
训练集和测试集不同分布时如何划分
给出一个场景:
- 你拥有大量(20w)A分布的数据,但是他不是你理想的数据
- 你只有少量(1w)B分布的数据,但是他是最理想的数据
如何抉择?
一种笨且不好的办法就是直接混合,打乱,保证同分布,但是这样的话,你的理想样本就会被大幅度稀释,尤其是在dev set或者test set里,这么少的理想样本根本就反映不出你的训练目标。
更好的办法是,把理想样本分50%到训练集中,剩下50%均分到开发集和测试集中,这样可以保证你训练目标的准确性,缺点在于,训练与验证的不同分布会导致更大的variance,只能寄希望于你的模型有足够的泛化性,能把着少量的样本消化了,精准的认出理想样本。
另一种意义上,高泛化性才是真正的智能,使我们应该努力的方向,而模式识别只是过渡与半成品。
诊断偏差来源
首先要确定偏差和方差是否是因为不同数据分布导致的。
如果有较大的variance,那么可能有两种原因:
- 模型的泛化性太差
- 训练集和开发集的分布不同
要确认是哪种原因引起的,一般是构造training-dev,这个集是从训练集中随机提取出来的一部分,很明显,这个集和训练集是同分布的。
排除同分布因素以后,误差分析就变成了四个:
- bias=人类水平-训练集
- variance=训练集-trainingDev set
如果这个variance没啥变化,依旧效果差,那说明泛化性就是很差,或者说是过拟合了,稍微有一点没见过的就判断不出来到了。 - data mismatch(数据不匹配)=trainingDev set-开发集
如果这一部分比较大,说明是分布不同导致的。 - 过拟合程度=test-dev
因为这两个理论上是同分布的,如果差距太大,也可以代表过拟合
解决数据不匹配问题
- 有意识地收集更多的理想数据,改善训练集,向开发集靠拢,保持同分布。
- 手工合成理想数据,将训练集改善
手工合成的例子,比如很多实际数据带有噪声,而你拿到的训练集没有噪声,这个时候可以把噪声合成进去。
缺点在于可能过拟合,因为比如有1w个小时的原数据,你只录了1小时的噪声,你人耳感觉这一小时和1w小时的噪音没啥区别,但是实际上如果你把这1h的噪声复制1w次丢进去合成,最后就可能造成过拟合。
更深层次讲,人工合成的本质缺陷在于人的想象力是有限的,有限的样本,和现实的分布还是有所区别,所以仍然不能彻底解决不同分布的问题,甚至会导致过拟合。
人工合成的一个应用就是GAN,GAN生成的数据虽然欺骗不了人眼,但是可以欺骗AI。
从这两点也可以看出人类的高泛化性,是机器难以匹敌嘚
宏观学习策略
迁移学习(transfer learning)
比如现在有大量的动物分类数据,但是只有少量X光片识别数据。
你可以在动物分类数据上训练一个模型,然后再应用到X光片识别上,这就是迁移学习。
- 预训练。首先在大数据样本中,训练模型。
- 微调。冻结权重,只保留最后一两层的变化权,同时更换输出层适应新的问题。改变网络结构后,再用少量的新任务样本去训练网络。
如果新任务样本有很多,也可以用大量样本训练,但是你可能需要吧前面的层也解冻,这样做已经丧失了迁移学习的大部分优点(其实就模式识别来说也没必要迁移了),可能唯一的好处就是能加速训练,毕竟前面的权重已经调整的相对比较好了。
之所以迁移学习有效,是因为神经网络的前几层通常学到的是底层次的特征提取,识别,这些可以说是通用的。而微调阶段只是把输出层变了,之后的训练也只是改变预训练层与可变层之间的权重罢了。
最后总结下迁移学习的特点:
- 相同类型的输入,输出可以不同
- A任务的数据量大于B
- A任务的底层特征对B有用
多任务学习(multi-task learning)
如果要用一个数据集,一个模型去完成多个同性质任务,这就是多任务学习。
比如有图片,然后有四个任务,要识别行人,车辆,路障,交通灯,输入是一样的,输出代表四个任务。
这样,输出就是一个4维向量,1代表有,0代表无,?代表不确定,这和soft-max的不同在于,这个可以有多个1,实际上是四个不同但又性质类似的任务
之所以能在一个网络上共享四个任务,是因为这四个任务性质类似,可以共享数据集和前面的网络,因为前面的网络的底层信息是对这类任务通用的(这里可见迁移学习的影子)。
而共享数据集,其实也可以相当于把若干个任务的样本集中起来了,变相的扩大了数据集。
既然数据集大了,那模型其实也要对应的大,多任务学习的缺点在于,模型必然大,否则效果还不如拆开用小模型。这么来看,迁移学习也自有他的优点,所以迁移学习用的更频繁(CV例外)。
端到端学习(end-to-end learning)
基本概念
所谓端到端学习就是原数据直接转化为目标结果,不需要进行中间件转化。
以语音识别举例,非端到端学习需要很多步骤:
- MFCC,提取底层次特征
- 通过传统ML技术提取Phoneme音元
- 音元转化为单词
- 最后进行翻译
而端到端就很粗暴,直接一个大网络,直接把audio转化为翻译的函数学到了。
端到端技术需要两个条件,一是大数据,伴随而来的就是大网络。只有在数据量够大的情况下,才能超越非端到端学习。
而数据量很少的时候,端到端是干不过传统技术的,这也证明,现在神经网络的小样本学习能力很差,需要大量的样本才能把非端到端过程中的处理隐式地学下来。
不适用端到端的例子
然而端到端并不一定就是最好的。有时候把步骤拆开效果更好。
比如门禁系统。
一步到位的方案可能遇到的情况很多,包括远近的干扰。但是拆成两步,先判断人脸位置后放大,最后进行识别,这么做效果更好。
从现实类比,人类要识别一个人,一般是先察觉到有人过来,然后稍微一看才知道是谁,这恰恰是拆开的过程。
又比如X影响识别,因为数据量太少,所以不能应用现有的端到端技术。
我认为,有两种情况不适合端到端,不容易产生好的效果:
- 不符合现实流程
- 数据太少
使用端到端的时机
先举出优缺点
好处:
- 令数据本身说话,而不会受到人类主观意志的影响。很多时候人类相当然的一些运行规律可能并不是真正的事实,强加到pipeline里可能会导致效果不好
- 简化工作流程
缺点:
- 需要大数据(小样本学习能力差)
- 排除了一些有用的中间件,或者说可能忽略客观的运行过程而执意将所有流程统一
现在的自动驾驶技术并不能实现端到端,即输入图片给出方向盘信息,而是要经过一系列过程:
- 通过深度学习技术将图像中的车,行人,道路等路况识别出来
- 基于路况,进行motion planning,得到路线
- 最后通过控制系统,把路线转化为方向盘之类的操作。
这让我想到了实验室做的NCP(neural circuit policy),之前我看那篇论文的时候,他老是在强调他这个技术是端到端,我当时一头雾水,怎么端到端很难吗?今天看完,端到端确实是很有前景但是很难实现的技术