吴恩达深度学习
吴恩达深度学习
目录
机器学习策略1
为什么要选择ML策略?(Why ML Strategy?)
什么是机器学习策略呢?
假设你正在调试你的猫分类器,经过一段时间的调整该系统达到了90%准确率。
但对你的应用程序来说还不够好,你可能有很多想法去改善你的系统。比如:
- 你可能想我们去收集更多的训练数据吧
- 可能你的训练集的多样性还不够,你应该收集更多不同姿势的猫咪图片,或者更多样化的反例集
- 或者你想再用梯度下降训练算法,训练久一点
- 或者你想尝试用一个完全不同的优化算法,比如Adam优化算法
- 或者尝试使用规模更大或者更小的神经网络
- 或者你想试试dropout或者L2正则化
- 或者你想修改网络的架构
- 比如修改激活函数
- 改变隐藏单元的数目
- 等等
选择的重要性
当你尝试优化一个深度学习系统时,你通常可以有很多想法可以去试。
但问题在于,如果你做出了错误的选择,你完全有可能白费6个月的时间,往错误的方向前进,在6个月之后才意识到这方法根本不管用。
比如,我见过一些团队花了6个月时间收集更多数据,却在6个月之后发现,这些数据几乎没有改善他们系统的性能。
所以,假设你的项目没有6个月的时间可以浪费。那么你需要快速有效地判断哪些想法是靠谱的,哪些是可以放心舍弃的,或者甚至提出新的想法。
我想这些内容是这门课程独有的。
比如说,很多大学深度学习课程很少提到这些策略。事实上,机器学习策略在深度学习的时代也在变化,因为现在对于深度学习算法来说能够做到的事情,比上一代机器学习算法大不一样。
正交化(Orthogonalization)
搭建建立机器学习系统的挑战之一是,你可以尝试和改变的东西太多太多了。比如说,有那么多的超参数可以调。
我留意到,那些效率很高的机器学习专家有个特点,他们思维清晰,对于要调整什么来达到某个效果,非常清楚。
什么是正交化?
举例:老式电视按钮
这是个老式电视,有很多旋钮可以用来调整图像的各种性质
- 有一个旋钮用来调图像垂直方向的高度,
- 还有一个旋钮用来调整图像宽度,
- 还有一个旋钮用来调整梯形角度,
- 还有一个旋钮用来调整图像左右偏移,
- 还有一个旋钮用来调图像旋转角度之类的。
正交化指的是电视设计师设计这样的旋钮,使得每个旋钮都只调整一个性质。
实现上电视设计师花了大量时间设计电路,那时通常都是模拟电路来确保每个旋钮都有相对明确的功能。
这样调整电视图像就容易得多。与之相反的是
想象一下如果你有一个旋钮,会调整的是图像高度,图像宽度,梯形角度,图像在水平轴上的坐标之类的。
当你调整这个(其中一个)旋钮,那么图像的高度、宽度、梯形角度、平移位置全部都会同时改变。
如果旋钮设计成这样,那几乎不可能把电视调好,让图像显示在区域正中。
举例:车辆的控制
你想想学车的时候,一辆车有三个主要控制。其中一个控制方向,另外两个控制你的速度
- 方向盘,方向盘决定你往左右偏多少
- 油门
- 刹车
想象一下,如果有人这么造车,造了个游戏手柄。
- 手柄的一个轴控制的是转向角-速度
- 然后还有一个轴控制的是转向角车速
理论上来说,通过调整这两个旋钮你是可以将车子调整到你希望得到的角度和速度。
正交化的概念是指:(有点编程那种思想)
- 你可以想出一个维度,这个维度你想做的是控制转向角
- 还有另一个维度来控制你的速度
那么你就需要一个旋钮能分别控制两者,那控制起来会很简单。但如果你有一个控制旋钮将两者混在一起,那将会很难控制。
正交化名字的含义:
正交意味着互成90度。
设计出正交化的控制装置,最理想的情况是和你实际想控制的性质一致,这样你调整参数时就容易得多。
正交化与机器学习
那么这与机器学习有什么关系呢?为了保证学习系统良好,你通常需要确保四件事情:
- Fit training set well on cost function
- Fit dev set well on cost function
- Fit test set well on cost function
- Performs well in real world
翻译一下:
- 首先,模型在训练集上拟合得不错
- 接着,模型在开发集上拟合得不错
- 然后,模型在测试集上拟合得不错
- 最后,模型在实际使用中表现令人满意。比如说,你希望这些猫图片应用的用户满意
我们回到电视调节的例子,如果你的电视图像太宽或太窄,你想要一个旋钮去调整,而不想要仔细调节五个不同的旋钮。
所以类似地,如果你的算法在成本函数上不能很好地拟合训练集,你想要一个或者一组特定的旋钮调整你的算法,让它很好地拟合训练集。
你用来调试的旋钮可能是
训练更大的网络
- 切换到更好的优化算法,比如Adam优化算法
- 等等
你希望有一组独立的旋钮去调试,比如说
- 首先,你需要让你的算法在训练集上做得很好
- 接着,你的算法在训练集上做得很好,但开发集上做得不行
- 类比到电视,你调好了电视的宽度,如果高度不太对,你就需要另一个旋钮来调节高度,并且你希望这个旋钮尽量不会影响到宽度。
- 你有一组正则化的旋钮可以调节,尝试让满足第二个条件。
- 增大训练集可以是另一个可用的旋钮,它可以帮助你的学习算法更好地归纳开发集的规律。
- 然后,如果算法在开发集上做的很好,但测试集上做得不好
- 如果是仅仅是测试集上不好,那么你需要调的旋钮,可能是更大的开发集。
但如果它在开发集上做的不错但测试集不行,这可能意味着你对开发集过拟合了,你需要往回退一步,使用更大的开发集。
- 如果是仅仅是测试集上不好,那么你需要调的旋钮,可能是更大的开发集。
- 最后,如果算法在测试集上做得很好,但无法给你的猫图片应用用户提供良好的体验
- 这意味着你需要回去,改变开发集或成本函数。
因为如果根据某个成本函数,系统在测试集上做的很好,但它无法反映你的算法在现实世界中的表现, - 这要么你的开发集分布设置不正确
- 要么你的成本函数测量的指标不对
- 这意味着你需要回去,改变开发集或成本函数。
你要非常清楚到底是四个问题中的哪一个,知道你可以调节哪些不同的东西可以尝试解决那个问题
early stopping 存在的问题
early stopping 这个技巧也还不错,很多人都这么干。但当我训练神经网络时,我一般不用 early stopping
原因:
个人而言,我觉得用early stopping有点难以分析,因为这个旋钮会同时影响你对训练集的拟合。
因为如果你早期停止,那么对训练集的拟合就不太好,但它同时也用来改善开发集的表现。
所以这个旋钮没那么正交化,因为它同时影响两件事情,就像一个旋钮同时影响电视图像的宽度和高度。
不是说这样就不要用,如果你想用也是可以的。但如果你有更多的正交化控制,使用其他手段来调整网络会更简单
指标
熟悉一下这章的常用单词
指标名 | 英文 |
---|---|
单一数值评估指标 / 单实数评估指标 | Single number evaluation metric |
整体评估指标 | Overall evaluation metric |
满足指标 | Satisficing metrics |
优化指标 | Optimizing metrics |
单一数字评估指标(Single number evaluation metric)
查准率和查全率(/Precision和Recal / 精准率和召回率)
比如说对于你的猫分类器
Classifier | Precision | Recall | F1 Score |
---|---|---|---|
A | 95% | 90% | 92.4% |
B | 98% | 85% | 91.0% |
评估你的分类器的一个合理方式是观察它的这两个值:
- 查准率(precision),课程字幕的翻译里叫精准率
- 定义:你的分类器标记为猫的例子中,有多少真的是猫
如果分类器查准率是95%,这意味着你的分类器说这图有猫的时候,有95%的机会真的是猫
- 定义:你的分类器标记为猫的例子中,有多少真的是猫
- 查全率(recall) ,课程字幕的翻译里叫召回率
- 定义:对于所有真猫的图片,你的分类器正确识别出了多少百分比
如果分类器查全率是90%,这意味着对于所有真正的猫图,分类器准确地分辨出了其中的90%
- 定义:对于所有真猫的图片,你的分类器正确识别出了多少百分比
F1分数
查准率和查全率之间往往需要折衷,两个指标都要顾及到
Q:如果分类器在查全率上表现更好,分类器在查准率上表现更好,如何判断哪个分类器更好?
A:在机器学习文献中,结合查准率和查全率的标准方法是所谓的分数
单一数值评估指标(Single number evaluation metric)
而F1分数可以作为 单一数值评估指标(有时我叫单实数评估指标)(Single number evaluation metric)
我发现很多机器学习团队就是这样,有一个定义明确的开发集用来测量查准率和查全率,再加上这样一个单一数值评估指标,能让你快速判断分类器或者分类器更好。
所以有这样一个开发集,加上单实数评估指标,你的迭代速度肯定会很快,它可以加速改进您的机器学习算法的迭代过程。
我们来看另一个例子:
假设你在开发一个猫应用来服务四个地理大区的爱猫人士,美国、中国、印度还有世界其他地区。
我们假设你的两个分类器在来自四个地理大区的数据中得到了不同的错误率,比如算法在美国用户上传的图片中达到了3%错误率,等等。
算法 | 美国 | 中国 | 印度 | 其他 | 平均 |
---|---|---|---|---|---|
A | 3% | 7% | 5% | 9% | 6% |
B | 5% | 6% | 5% | 10% | 6.5% |
C | 2% | 3% | 4% | 5% | 3.5% |
D | 5% | 8% | 7% | 2% | 5.25% |
E | 4% | 5% | 2% | 4% | 3.75% |
F | 7% | 11% | 8% | 12% | 9.5% |
仅通过前四列的数字,很难扫一眼这些数值就快速判断算法或算法哪个更好。
看着那么多数字,然后快速选一个最优是很难的。最好能选择合理的单实数评估指标,用单一指标来快速评估。
所以在这个例子中,假设平均表现是一个合理的单实数评估指标,通过计算平均值,你就可以快速判断。
满足指标、优化指标(Satisficing metrics & Optimizing metrics)
要把你顾及到的所有事情组合成单实数评估指标有时并不容易
分数或者用其他是衡量准确度的指标。但除了准确度之外,我们还需要考虑运行时间。比如以下例子
Classifier | Accuracy | Running time |
---|---|---|
A | 90% | 80ms |
B | 92% | 95ms |
C | 95% | 1,500ms |
方法一,整体评估指标(Overall evaluation metric)
你可以这么做,将准确度和运行时间组合成一个整体评估指标
比如:。不过这种组合方式太刻意,只是两个数值的线性加权求和
方法二,满足和优化指标(Satisficing and Optimizing metrics)
限制一个值的范围(这个就很像是数学建模里的多变量转单变量线性规划模型的里一种方法)
你还可以做其他事情,就是你可能选择一个分类器,能够最大限度提高准确度,但必须满足运行时间要求。比如对图像进行分类的时间必须小于等于100毫秒
在这种情况下
- 准确度 是一个优化指标
- 优化指标需要尽可能地好
- 运行时间是一个满足指标
- 满足指标必须足够好
- 该例子中,它只需要小于100毫秒,达到之后,你不在乎或不那么在乎这指标有多好。
实际情况可能是,只要运行时间少于100毫秒,你的用户不会在乎运行时间是100ms还是50ms甚至更快在此例中,通过该方法得知B算法最好
多个指标的情况:
更一般地,如果你要考虑个指标,有时候选择其中一个指标做为优化指标是合理的,你只需尽量优化那个指标,然后剩下个指标都是满足指标,只要满足阈值即可
另一个例子
假设你正在构建一个系统来检测唤醒语,也叫触发词,这指的是语音控制设备
- 比如亚马逊Echo的 “Alexa”
- 或者谷歌设备的 “Okay Google”
- 或者苹果设备的 “Hey Siri”
- 或者百度设备的 “你好百度” 或 “小度小度”
这些就是唤醒词,可以唤醒这些语音控制设备,然后监听你想说的话。
所以你可能会在乎触发字检测系统的准确性,所以当有人说出其中一个触发词时,有多大概率可以唤醒你的设备。
你可能也需要顾及假阳性(false positive)的数量,就是没有人在说这个触发词时,它被随机唤醒的概率有多大?所以这种情况下,当某人说出唤醒词时,需要最大化你的设备被唤醒的概率。然后必须满足24小时内最多只能有1次假阳性。
准确度是优化指标,然后每24小时发生一次假阳性是满足指标,你只要每24小时最多有一次假阳性就满足了。
训练 / 开发 / 测试集
训练 / 开发 / 测试集划分(Train/dev/test distributions)
训练 / 开发 / 测试集划分
在这个视频中,我想集中讨论如何设立开发集和测试集
- 训练集(train set)
- 开发集(dev set / development set),也叫保留交叉验证集(hold out cross validation set)、交叉集、验证集
- 测试集(test set)
机器学习中的工作流程是
- 首先用训练集训练不同的模型
- 然后用开发集来评估不同的思路,然后选择一个。不断迭代去改善开发集的性能,直到最后你可以得到一个令你满意的成本
- 最后用测试集去评估
举个例子,你要开发一个猫分类器
然后你在这些区域里运营,美国、英国、其他欧洲国家,南美洲、印度、中国,其他亚洲国家和澳大利亚,那么你应该如何设立开发集和测试集呢?
其中一种做法是(糟糕的做法)
- 开发集:你可以选择其中4个区域,可以是前四个或者是随机选的区域,构成开发集
- 测试集:然后选择其他四个区域,这些数据构成测试集
事实证明,这个想法非常糟糕,因为这个例子中,你的开发集和测试集来自不同的分布。我建议你们不要这样,而是让你的开发集和测试集来自同一分布。
在实际开发时大概会是这样的:
设定目标:
设立你的开发集加上一个单实数评估指标,这就是像是定下目标,然后告诉你的团队,那就是你要瞄准的靶心。逼近目标:
你一旦建立了这样的开发集和指标,团队就可以快速不断迭代,尝试不同的想法,使用不同方法去逼近目标,跑实验,可以很快地使用开发集和指标去评估不同分类器,针对开发集上的指标优化,然后尝试选出最好的那个,不断逼近靶心。发现GG:
你的团队可能会花上几个月时间在开发集上迭代优化,当你们最终在测试集上测试系统时。结果发现,来自这四个国家或者说下面这四个地区的数据(即测试集数据)和开发集里的数据可能差异很大。
花了那么多个月的时间去针对开发集优化,在测试集上的表现却不佳。总结:
所以,如果你的开发集和测试集来自不同的分布,就像你设了一个目标,让你的团队花几个月尝试逼近靶心。
结果在几个月工作之后发现,你说“等等”,测试的时候,"我要把目标移到这里"。
然后团队可能会说"好吧,为什么你让我们花那么多个月的时间去逼近那个靶心,然后突然间你可以把靶心移到不同的位置?"。
正确的做法
- 我建议的是你将所有数据随机洗牌,放入开发集和测试集,所以开发集和测试集都有来自八个地区的数据,并且开发集和测试集都来自同一分布,这分布就是你的所有数据混在一起。
另一个例子
这是个真实的故事,但有一些细节变了。
我知道有一个机器学习团队,花了好几个月在开发集上优化,开发集里面有中等收入邮政编码的贷款审批数据。
具体的机器学习问题是,输入为贷款申请,你是否可以预测输出,是他们有没有还贷能力?这系统能帮助银行判断是否批准贷款。开发集来自贷款申请,这些贷款申请来自中等收入邮政编码,zip code就是美国的邮政编码。
但是在这上面训练了几个月之后,团队突然决定要在,低收入邮政编码数据上测试一下。
这个分布数据里面中等收入和低收入邮政编码数据是很不一样的,他们花了大量时间针对前面那组数据优化分类器,但在后面那组数据中效果很差
所以这个特定团队实际上浪费了3个月的时间,不得不退回去重新做很多工作。这里实际发生的事情是,这个团队花了三个月瞄准一个目标,三个月之后经理突然问"你们试试瞄准那个目标如何?",这新目标位置完全不同,这件事对于这个团队来说非常崩溃。
总结
所以我建议你们在设立开发集和测试集时,要选择这样的开发集和测试集:
能够反映你未来会得到的数据,认为很重要的数据,必须得到好结果的数据。
特别是,我们希望通过在同一分布中设立开发集和测试集,你就可以瞄准你所希望的机器学习团队瞄准的目标。
不管你未来会得到什么样的数据,一旦你的算法效果不错,要尝试收集类似的数据。而且,不管那些数据是什么,都要随机分配到开发集和测试集上。
因为这样,你才能将瞄准想要的目标,让你的团队高效迭代来逼近同一个目标,希望最好是同一个目标。
开发 / 测试集的大小(Size of dev and test sets)
在上一个视频中你们知道了你的开发集和测试集为什么必须来自同一分布,但它们规模应该多大?
大小的切分
小样本
你可能听说过一条经验法则:
70%训练集,30%测试集,
或60%训练集,20%开发集,20%测试集。在机器学习的早期,这样分是相当合理的,特别是以前的数据集大小要小得多。
所以如果你总共有100个样本,甚至几千个样本或一万个样本,这些做法也还是合理的。
大样本
- 但在现代机器学习中,比如说你有1百万个训练样本。70/30不再适用了,这样分可能更合理:
- 98%训练集,1%开发集,1%测试集
分析
我们用和缩写来表示开发集和测试集
测试集的大小:
目的:目的是完成系统开发之后,测试集可以帮你评估投产系统的性能
大小:测试集足够大,能够以高置信度评估系统整体性能。但是除非你需要对最终投产系统有一个很精确的指标,一般来说测试集不需要上百万个例子。
经验:对于你的应用程序,也许你想,有10,000个或者100,000个例子就能给你足够的置信度来给出性能指标了。
这数目可能远远小于比如说整体数据集的30%,取决于你有多少数据。
如果你有1百万个样本,那么1%就是10,000个样本,这对于开发集和测试集来说可能已经够了。
开发集和测试集
测试集并不必须
- 对于某些应用,你也许不需要对系统性能有置信度很高的评估,也许你只需要训练集和开发集。我认为,不单独分出一个测试集也是可以的
没有测试集的合理性
如果你的开发集非常大,这样你就不会对开发集过拟合得太厉害。这种情况,只有训练集和测试集也不是完全不合理的。因为你可以使用这组不带偏差的数据来测量系统的性能
不过吴恩达老师个人不建议在搭建系统时省略测试集,因为有个单独的测试集比较令我安心。
名称上的混淆
- 不过在机器学习的历史里,不是每个人都把术语定义分得很清的,有时人们说的开发集,其实应该看作测试集。
如果你真的在调试这个集,这个开发集或这个测试集,这最好称为开发集。
一般来说称为训练集、开发集就好。
- 不过在机器学习的历史里,不是每个人都把术语定义分得很清的,有时人们说的开发集,其实应该看作测试集。
什么时候该改变开发 / 测试集和指标?(When to change dev/test sets and metrics)
你已经学过如何设置开发集和评估指标,就像是把目标定在某个位置,让你的团队瞄准。
但有时候在项目进行途中,你可能意识到,目标的位置放错了。这种情况下,你应该移动你的目标。
什么时候应该改变评估指标
例子一
我们来看一个例子
假设你在构建一个猫分类器,试图找到很多猫的照片,向你的爱猫人士用户展示,你决定使用的指标是分类错误率。
- 算法A:3%错误率
- 算法似乎做得更好,但算法由于某些原因,把很多色情图像分类成猫了。
如果你部署算法,那么用户就会看到更多猫图,因为它识别猫的错误率只有3%,但它同时也会给用户推送一些色情图像。
这是你的公司完全不能接受的,你的用户也完全不能接受。(noter:不,我完全可以接受 o(///▽///)q)
- 算法似乎做得更好,但算法由于某些原因,把很多色情图像分类成猫了。
- 算法B:5%错误率
- 相比之下,算法有5%的错误率,这样分类器就得到较少的图像,但它不会推送色情图像。
所以从你们公司的角度来看,以及从用户接受的角度来看,算法实际上是一个更好的算法,因为它不让任何色情图像通过。
- 相比之下,算法有5%的错误率,这样分类器就得到较少的图像,但它不会推送色情图像。
在这个例子中
- 算法A在评估指标上做得更好,它的错误率达到3%,但实际上是个更糟糕的算法。
但评估指标加上开发集它们都倾向于选择算法,这是你们自己定下来的指标评估出来的。 - 但你和你的用户更倾向于使用算法,因为它不会将色情图像分类为猫。
所以当这种情况发生时,当你的评估指标无法正确衡量算法之间的优劣排序时,你应该改变评估指标。或者要改变开发集或测试集。
例子二
假设你的两个猫分类器和,分别有用开发集评估得到3%的错误率和5%的错误率。
但测试时,都是使用网上下载的图片构成的测试集上,这些是高质量,取景框很专业的图像。
- 也许你在部署算法产品时,你发现算法看起来表现更好,在开发集上也表现不错。
- 但当你部署到手机应用时,算法作用到用户上传的图片时,那些图片取景不专业,没有把猫完整拍下来,或者猫的表情很古怪,也许图像很模糊。你的用户真正关心的是,他们上传的图片能不能被正确识别
当你实际测试算法时,你发现算法表现其实更好。
如果你在指标上表现很好,在开发集或和测试集分布中表现很好,但你的实际应用时表现不好,那么就需要修改指标或者你的开发测试集
修改的思路方法(并不重要)
(修改方法对于本节来说这点其实并不重要,重要的是知道:
如果你的评估指标无法正确评估好算法的排名,那么就需要花时间定义一个新的评估指标)
原来,你用的分类错误率指标可以写成这样:
这个评估指标的问题在于:它对色情图片和非色情图片一视同仁
其中一个修改评估指标的方法是,这里(与之间)加个权重项,即:
- 如果图片不是色情图片,则。
- 如果是色情图片,可能就是10甚至100。
这样你赋予了色情图片更大的权重,让算法将色情图分类为猫图时,惩罚权重加大10倍。
如果你希望得到归一化常数,在技术上,就是对所有求和,这样错误率仍然在0和1之间,即:
加权的细节并不重要,实际上要使用这种加权,你必须自己过一遍开发集和测试集,把色情图片标记出来,这样你才能使用这个加权函数。
指标与正交化
你可能注意到了,到目前为止我们只讨论了如何定义一个指标去评估分类器。
我们定义了一个评估指标帮助我们更好的把分类器排序,能够区分出它们在识别色情图片的不同水平,这实际上是一个正交化的例子。
我想你处理机器学习问题时,应该把它切分成独立的步骤。
第一步
- 设定目标、定义指标,定义你要瞄准的目标。
如何设立目标是一个完全独立的问题,把它看成是一个单独的可以调节的旋钮
- 设定目标、定义指标,定义你要瞄准的目标。
第二步
然后我们可以分开考虑如何改善系统在这个指标上的表现
在逼近目标的时候,也许你的学习算法针对某个长这样的成本函数优化
将\\ J=\frac{1}{m}\sum\limits_{i=1}^{m}{L({{\hat y}^{(i)}},{y^{(i)}})}\\ 优化成\\ J=\frac{1}{\sum{{^{(i)}}\sum\limits_{i=1}^{m}{{{w}^{(i)}}L({{\hat y}^{(i)}},{{y}^{(i)}})}
再次说明,如何定义并不重要,关键在于正交化的思路
总结、经验
所以我的建议是,即使你无法定义出一个很完美的评估指标和开发集,你直接快速设立出来,然后使用它们来驱动你们团队的迭代速度。
如果在这之后,你发现选的不好,你有更好的想法,那么完全可以马上改。
对于大多数团队,我建议最好不要在没有评估指标和开发集时跑太久,因为那样可能会减慢你的团队迭代和改善算法的速度。
人的表现
贝叶斯最优错误率
为什么是人的表现?(Why human-level performance?)
Q:在过去的几年里,更多的机器学习团队一直在讨论如何比较机器学习系统和人类的表现,为什么呢?
A:我认为有两个主要原因
- 首先,因为深度学习系统的进步,机器学习算法突然变得更好了。在许多机器学习的应用领域已经开始见到算法已经可以威胁到人类的表现了。
- 其次,事实证明当你试图让机器做人类能做的事情时,可以精心设计机器学习系统的工作流程,让工作流程效率更高。
所以在这些场合,比较人类和机器是很自然的,或者你要让机器模仿人类的行为。
贝叶斯最优错误率
别名
- 中文:贝叶斯最优错误率,也叫贝叶斯错误率、贝叶斯最佳错误率
- 英文:Bayes optimal error,有时写作Bayesian,即省略optimal
定义
- 随着时间的推移,当您继续训练算法时,可能模型越来越大,数据越来越多,但是性能无法超过某个理论上限 —— 这就是贝叶斯最优错误率
- 贝叶斯最优错误率一般认为是理论上可能达到的最优错误率,就是说没有任何办法设计出一个到的函数,让它能够超过一定的准确度
- 开发目标:一直提高训练集表现,直到接近贝叶斯错误率。理论上是不可能超过贝叶斯错误率的,除非过拟合
举例
- 对于语音识别来说,如果是音频片段,有些音频就是这么嘈杂,基本不可能知道说的是什么,所以完美的准确率可能不是100%。
- 或者对于猫图识别来说,也许一些图像非常模糊,不管是人类还是机器,都无法判断该图片中是否有猫。所以,完美的准确度可能不是100%
结合图像
紫线:算法性能
蓝线:人类水平
绿线:贝叶斯最优错误率实际开发中
当你开始往人类水平努力时,进展是很快的。
但是过了一段时间,当这个算法表现比人类更好时,那么进展和精确度的提升就变得更慢了。
也许它还会越来越好,但性能增速,准确度上升的速度这个斜率,会变得越来越平缓。我们都希望能达到理论最佳性能水平
人的表现与贝叶斯最优错误率
事实证明,机器学习的进展往往相当快,直到你超越人类的表现之前一直很快,当你超越人类的表现时,有时进展会变慢。
我认为有两个原因,为什么当你超越人类的表现时,进展会慢下来。
原因一
人类水平在很多任务中离贝叶斯最优错误率已经不远了,人们非常擅长看图像,分辨里面有没有猫或者听写音频。
所以,当你超越人类的表现之后也许没有太多的空间继续改善了。
原因二
只要你的表现比人类的表现更差,特别是人类相当擅长的任务(包括看图识别事物,听写音频,或阅读语言等),那么可以使用某些工具来提高性能
你可以让人帮忙或者花钱请人帮你标记例子,这样你就有更多的数据可以喂给学习算法
你可以人工错误率分析。让人类看看你算法处理的例子,知道错误出在哪里,并尝试了解为什么人能做对而算法做错
你可以更好地偏差/方差分析。知道人类在特定任务上能做多好,可以帮助你更好地了解你应该重点尝试减少偏差还是减少方差
一旦你超越了人类的表现,这些工具就没那么好用了
可避免偏差(Avoidable bias)
我们讨论过,你希望你的学习算法能在训练集上表现良好,但有时你实际上并不想做得太好。
你得知道人类水平的表现是怎样的,可以确切告诉你算法在训练集上的表现到底应该有多好,或者有多不好
例子
我们经常使用猫分类器来做例子
例子一
错误率:
假设人类错误率是1%
学习算法达到8%的训练错误率和10%的开发错误率策略:
你的算法在训练集上的表现和人类水平的表现有很大差距的话,说明你的算法对训练集的拟合并不好,应该把重点放在减少偏差上
比如说训练更大的神经网络,或者跑久一点梯度下降等等
例子二
错误率:
假设人类的表现不是1%而是7.5%。也许你的数据集中的图像非常模糊,即使人类都无法判断这张照片中有没有猫。
学习算法错误率不变策略:
你可能希望专注减少学习算法的方差
也许你可以试试正则化,让你的开发错误率更接近你的训练错误率。
总结
算法1 | 算法2 | |
---|---|---|
训练集错误率 | 8% | 8% |
开发集错误率 | 10% | 10% |
人类错误率(接近Bayes) | 1% | 7.5% |
方差指标 | 2% | 2% |
可避免偏差 | 7% | 0.5% |
应该采用的策略 | 专注于避免偏差策略 | 专注于避免方差策略 |
人类水平错误率估计或代替贝叶斯最优错误率
在之前的课程关于偏差和方差的讨论中,我们主要假设有一些任务的贝叶斯错误率几乎为0,但实际不是。
通常会用人类水平的错误率估计或代替贝叶斯最优错误率
对于计算机视觉任务而言,这样替代相当合理。因为人类实际上是非常擅长计算机视觉任务的,人类能做到的水平和贝叶斯错误率相差不远。
什么是可避免偏差
对贝叶斯错误率的估计和训练错误率之间的差值称为可避免偏差,大概说明你的算法在方差问题上还有多少改善空间。
例子中
- 算法一,方差指标都是2%,可避免偏差7.0%
- 专注减少可避免偏差可能潜力更大
- 算法二,方差指标都是2%,可避免偏差0.5%
- 要减少这个2%比减少这个0.5%空间要大得多
当你理解人类水平错误率,你就可以在不同的场景中专注于不同的策略,选择使用避免偏差策略还是避免方差策略。
理解人的表现(Understanding human-level performance)
什么是 人类水平错误率 ?
假设你要观察一张放射科的图像,然后作出分类诊断
- 假设一个普通的人类,未经训练的人类,在此任务上达到3%的错误率
- 普通的医生,也许是普通的放射科医生,能达到1%的错误率
- 经验丰富的医生做得更好,错误率为0.7%
- 还有一队经验丰富的医生,就是说如果你有一个经验丰富的医生团队,让他们都看看这个图像,然后讨论并辩论,他们达成共识的意见达到0.5%的错误率
那么思考以下问题
- Q:所以我想问你的问题是,你应该如何界定人类水平错误率?人类水平错误率3%,1%,0.7%还是0.5%?
- A:人类水平错误率最有用的方式之一是把它作为贝叶斯错误率的替代或估计
- 就是如果你想要替代或估计贝叶斯错误率,那么一队经验丰富的医生讨论和辩论之后可以达到0.5%的错误率。我们知道贝叶斯错误率小于等于0.5%
- 我们不知道多少更好,也许有一个更大的团队,更有经验的医生能做得更好,所以也许比0.5%好一点,但是我们知道最优错误率必须在0.5%以下
- 那么在这个背景下,我就可以用0.5%估计贝叶斯错误率。所以我将人类水平定义为0.5%
为了发表研究论文或者部署系统,也许人类水平错误率的定义可以不一样
在定义人类水平错误率时,要弄清楚你的目标所在
- 如果您的目标是要表明你可以超越单个人类,证明系统是实用的,那么就有理由在某些场合部署你的系统,也许这个定义(1%)是合适的
- 如果您的目标是替代贝叶斯错误率,那么这个定义(经验丰富的医生团队——0.5%)才合适
几个例子
例子一
比方说,在医学图像诊断例子中,你的训练错误率是5%,你的开发错误率是6%。
我们的人类水平表现,我将它看成是贝叶斯错误率的替代品,取决于你是否将它定义成普通单个医生的表现,还是有经验的医生或医生团队的表现。
你可能会用1%或0.7%或0.5%,可避免偏差大概是4%或4.3%或5.5%但不管你怎么定义人类水平错误率,可避免偏差比都比方差的问题更大。你应该专注于减少偏差的技术。
例子二
比如说你的训练错误率是1%,开发错误率是5%
人类水平表现是1%或0.7%还是0.5%,其实也不怎么重要。
不管你使用哪一个定义,4%的方差指标比任何一种定义的可避免偏差都大。你应该主要使用减少方差的工具。
例子三
前两个例子没必要严格计算 人类水平错误率,那什么时候需要呢
比如你的训练错误率是0.7%,你的开发错误率是0.8%如果你用0.5%来估计贝叶斯错误率,你测量到的可避免偏差是0.2%,这是你测量到的方差问题0.1%的两倍。
虽然偏差和方差都存在问题,但是可避免偏差问题更严重。如果你用0.7代替贝叶斯错误率,你测得的可避免偏差基本上是0%,那你就可能忽略可避免偏差了。实际上你应该试试能不能在训练集上做得更好。
为什么当机器学习接近人类水平时取得进展会越来越难
- 前两个例子中:当你远离人类水平时,更容易知道优化目标重点应该放在偏差还是方差上
- 第三个例子中:一旦你接近0.7%错误率,你需要非常小心估计贝叶斯错误率。所以当接近人类水平时,更难分辨出问题是偏差还是方差
什么时候应该估计贝叶斯错误率
今天讲的和之前课程中见到的重大区别是,以前直接比较的是训练错误率和0%,相比之下这节中我们有一个更微妙的分析
当贝叶斯错误率几乎为零时,可以那么像前者那样做。
例如识别猫,人类表现接近完美,所以贝叶斯错误率也接近完美。
但数据噪点很多时,比如背景声音很嘈杂的语言识别,有时几乎不可能听清楚说的是什么。此时更好的估计贝叶斯错误率很有必要
超过人的表现(Surpassing human- level performance)
很多团队会因为机器在特定的识别分类任务中超越了人类水平而激动不已,我们谈谈这些情况,看看你们自己能不能达到。
机器学习进展为什么会在接近或者超越人类水平的时候变得越来越慢?
先来一个简单的例子
- 一组人类专家充分讨论辩论之后,达到0.5%的错误率
- 单个人类专家错误率是1%
- 你训练出来的算法有0.6%的训练错误率,0.8%的开发错误率
可避免偏差是多少?是0.5%
0.5%是你对贝叶斯错误率的估计,所以可避免偏差就是0.1%。
然后方差是0.2%,和减少可避免偏差比较起来,减少方差可能空间更大。
再看一个比较难的例子
- 一个人类专家团和单个人类专家的表现和以前一样,都是0.5%错误率
- 但你的算法可以得到0.3%训练错误率,还有0.4%开发错误率
可避免偏差是多少?现在其实很难回答
基于本例中给出的信息,你实际上没有足够的信息来判断优化你的算法时应该专注减少偏差还是减少方差,这样你取得进展的效率就会降低。
还有比如说,如果你的错误率已经比一群充分讨论辩论后的人类专家更低,那么依靠人类直觉去判断你的算法还能往什么方向优化就很难了。
在这个例子中,一旦你超过这个0.5%的门槛,要进一步优化你的机器学习问题就没有明确的选项和前进的方向了。这并不意味着你不能取得进展,你仍然可以取得重大进展,但现有的一些工具帮助你指明方向的工具就没那么好用了。
机器学习 vs 人类水平
现在,机器学习有很多问题已经可以大大超越人类水平了。例如:
结构化数据 的例子:
- 我想网络广告,估计某个用户点击广告的可能性,可能学习算法做到的水平已经超越任何人类了
- 还有提出产品建议,向你推荐电影或书籍之类的任务。我想今天的网站做到的水平已经超越你最亲近的朋友了
- 物流预测,从到开车需要多久,或者预测快递车从开到需要多少时间。
- 或者预测某人会不会偿还贷款,这样你就能判断是否批准这人的贷款。
非结构化数据 的例子:
- 今天已经有语音识别系统超越人类水平了
- 一些计算机视觉任务,一些图像识别任务
- 一些医疗方面的任务,比如阅读ECG或诊断皮肤癌,或者某些特定领域的放射科读图任务
在深度学习的最新进展中,其中一个振奋人心的方面是,即使在自然感知任务中,在某些情况下,计算机已经可以超越人类的水平了
改善你的模型的表现(Improving your model performance)
这章笔记的前面,我们学过:
- 正交化
- 如何设立开发集和测试集
- 用人类水平错误率来估计贝叶斯错误率
- 如何估计可避免偏差和方差
现在把它们全部组合起来写成一套指导方针
所以我想要让一个监督学习算法达到实用,基本上希望或者假设你可以完成两件事情。
- 首先,降低可避免偏差
- 然后,让方差不是太大
如果你想提升机器学习系统的性能
- 看看训练错误率和贝叶斯错误率估计值之间的距离,让你知道可避免偏差有多大。换句话说,就是你觉得还能做多好,你对训练集的优化还有多少空间
- 然后看看你的开发错误率和训练错误率之间的距离,就知道你的方差问题有多大。换句话说,你应该做多少努力让你的算法表现能够从训练集推广到开发集
减少可避免偏差的策略
- 使用规模更大的模型
- 训练更久
- 使用更好的优化算法,比如说加入momentum、RMSprop、Adam
- 寻找更好的新神经网络架构,或者模型,比如循环神经网络和卷积神经网络
- 使用更好的超参数
- 改变激活函数,改变层数或者隐藏单位数(虽然你这么做可能会让模型规模变大)
减少方差的策略
- 你可以收集更多数据,因为收集更多数据去训练可以帮你更好地推广到系统看不到的开发集数据
- 正则化,比如正则化、dropout正则化
- 数据增强
- 试用不同的神经网络架构
- 超参数搜索