吴恩达深度学习
吴恩达深度学习
目录
机器学习策略2
进行误差分析(Carrying out error analysis)
误差分析
如果你希望让学习算法能够胜任人类能做的任务,但你的学习算法还没有达到人类的表现,
那么人工检查一下你的算法犯的错误也许可以让你了解接下来应该做什么。
这个过程称为错误分析(或误差分析)
例子
假设你正在调试猫分类器,然后你取得了90%准确率(即10%错误率)
也许你的队员看了一下算法分类出错的例子,注意到算法将一些狗分类为猫。所以也许你的队友给你一个建议,如何针对狗的图片优化算法
你可以针对狗,收集更多的狗图,或者设计一些只处理狗的算法功能之类的但问题在于,你是不是应该去开始做一个项目专门处理狗?这项目可能需要花费几个月的时间才能让算法在狗图片上犯更少的错误,这样做值得吗?
可能与其花几个月做这个项目,有可能最后发现这样一点用都没有。这里有个错误分析流程,可以让你很快知道这个方向是否值得努力。
评估
首先,收集一下,比如说100个错误标记的开发集样本,然后手动检查,一次只看一个,看看你的开发集里有多少错误标记的样本是狗。
假设,100个错误标记样本中只有5%是狗
- 这意味即使你完全解决了狗的问题,你最多只能希望你的错误率从10%下降到9.5%
- 在机器学习中,有时我们称之为性能上限,就意味着,最好能到哪里,完全解决狗的问题可以对你有多少帮助
假设,100个错误标记样本中只有50%是狗
- 如果你真的解决了狗的问题,那么你的错误率可能就从10%下降到5%。
- 你可能觉得这值得一试,花时间去解决狗的问题可能效果就很好
并行评估
我们评估了这个样本里狗的问题是否值得解决。而有时你在做错误分析时,也可以同时并行评估几个想法
比如,你有几个改善猫检测器的想法
- 也许你可以改善针对狗图的性能
- 也许你注意到猫科动物(如狮子,豹,猎豹等等)经常被分类成小猫或者家猫。你希望想办法解决这个错误
- 也许你发现有些图像是模糊的。希望能设计出一些系统,能够更好地处理模糊图像
也许你有些想法,知道大概怎么处理这些问题,要进行错误分析来评估这三个想法。
具体方法:
我会做的是建立这样一个表格,我通常用电子表格来做,当然普通文本文件也可以
像下面表格那样,进行打勾,计算在错误样本中的占比
图像 | 狗 | 猫科动物 | 模糊不清 | 有Ins滤镜 | 评价 备注 |
---|---|---|---|---|---|
1 | √ | √ | 头牛犬 | ||
2 | √ | √ | |||
3 | √ | √ | 雨天模糊 | ||
……………… | ……………… | ……………… | ……………… | ……………… | ……………… |
占比 | 8% | 43% | 61% | 12% |
补充:这个步骤做到一半时,有时你可能会发现其他错误类型,比如说你可能发现有Instagram滤镜,那些花哨的图像滤镜,干扰了你的分类器。那么你可以在错误分析途中,增加这样一列,比如多色滤镜
最后,表格能告诉你:
- 比如说不管你对狗图片或者Instagram图片处理得有多好,在这些例子中,你最多只能取得8%或者12%的性能提升。
- 而在猫科图片这一类型,你可以做得更好。
- 或者模糊图像,这些类型有改进的潜力。
这猫科图片和模糊图像类型里,性能提高的上限空间要大得多
也许你可以选择其中两个,如果你的团队成员足够多也可以将其分成两个团队,分别想办法改善大猫的识别和改善模糊图片的识别
这个快速统计的步骤,你可以经常做,最多需要几小时,就可以真正帮你选出高优先级任务,并了解每种手段对性能有多大提升空间。
总结
进行错误分析
- 首先,找一组错误样本观察错误标记的样本。看看假阳性和假阴性,统计属于不同错误类型的错误数量
- 在这个过程中,你可能会发现归纳出新的错误类型,你就可以在途中新建一个错误类型
- 总之,通过统计不同错误标记类型占总数的百分比,可以帮你发现哪些问题需要优先解决,或者给你构思新优化方向的灵感
清除标注错误的数据
错误标记(Mislabeled)
- 概念:你的监督学习问题的数据由输入和输出标签 构成。如果你观察一下你的数据,发现有些输出标签 是错的。
- 术语:错误标记(mislabeled examples)(Incorrectly labeled data)。表示你的学习算法输出了错误的 值
- 问题:你的数据有些标签是错的,是否值得花时间去修正这些标签呢?
例子
我们看看在猫分类问题中,图片是猫,;不是猫,。
所以假设你看了一些数据样本,发现这(倒数第二张图片)其实不是猫,所以这是标记错误的样本。
是否应该修正错误标记
训练集中的随机误差不用管
- 深度学习算法对训练集中的随机错误相当健壮(robust)。只要这些错误样本离随机错误不太远
- 比如,有时可能做标记的人没有注意或者不小心,按错键了,如果错误足够随机,那么放着这些错误不管可能也没问题,而不要花太多时间修复它们。
只要总数据集总足够大,实际错误率可能不会太高。 - 比如,我见过一大批机器学习算法训练的时候,明知训练集里有个错误标签,但最后训练出来也没问题。
训练集中的系统性误差要管
- 深度学习算法对随机误差很健壮,但对系统性的错误没那么健壮。
- 比如,如果做标记的人一直把白色的狗标记成猫,那就成问题了。因为你的分类器学习之后,会把所有白色的狗都分类为猫。
开发和测试集中的误差看情况
方法:一般建议你在错误分析时,添加一个额外的列,这样你也可以统计标签 错误的样本数
表格如下
图像 | 狗 | 猫科动物 | 模糊不清 | 错误标记 | 评价 备注 |
---|---|---|---|---|---|
……………… | ……………… | ……………… | ……………… | ……………… | ……………… |
98 | √ | 漏掉了背景里的一只猫 | |||
99 | √ | ||||
100 | √ | 画出来的而不是真的猫 | |||
占比 | 8% | 43% | 61% | 6% |
是否值得修正这6%标记出错的样本?
设立开发集的目标是,你希望用它来从两个分类器和中选择一个。我的建议是:
- 如果标记错误已经严重影响了你开发集上评估算法的能力,那么就应该去花时间修正错误的标签
- 如果标记错误没有严重影响到你开发集上评估算法的能力,那么可能就不应该花宝贵的时间去处理
来看两种情况的例子:
例子一
系统错误率10%,标记出错占错误标本的6%,占总共的0.6%
这种情况下,我说有9.4%错误率需要集中精力修正,而标记出错导致的错误是总体错误的一小部分而已。
如果你一定要这么做,你也可以手工修正各种错误标签,但也许这不是当下最重要的任务标记出错对算法错误的整体评估标准影响较小
例子二
- 系统错误率2%,标记出错占错误标本的30%,占总共的0.6%
- 当测得的那么大一部分的错误都是开发集标记出错导致的,那似乎修正开发集里的错误标签似乎更有价值
- 比如:
当你测试两个分类器和时,在开发集上一个有2.1%错误率,另一个有1.9%错误率。
你不能再信任开发集了,因为它无法告诉你这个分类器是否比这个好,因为0.6%的错误率是标记出错导致的。 - 标记出错对算法错误的整体评估标准有严重的影响
另外这里还有一些额外的方针和原则需要考虑
首先,不管用什么修正手段,都要同时作用到开发集和测试集上
- 因为开发和测试集必须来自相同的分布。
其次,强烈建议同时检验算法判断正确和判断错误的样本
要检查算法出错的样本很容易,只需要看看那些样本是否需要修正,但还有可能有些样本算法判断正确,那些也需要修正(错误标记且判断错了)
这一点其实不好执行,很多人也不常做。假如错误率2%,检查正确的往往比检查错误的更花费时间
最后,修正开发集和测试集的部分时标签,你可能不会去对训练集做同样的事情
之前说过修正训练集中的标签其实相对没那么重要,所以你可能决定只修正开发集和测试集中的标签。这种做法其实是可以的
开发集和测试集应该来自同一分布,但开发集稍微和测试集/训练集不来自同一分布通常这是合理的,后面再来说如何处理这个问题
最后我讲几个建议:
- 首先,很多深度学习的训练,只是把数据喂给算法,然后训练它,并减少人工干预,减少使用人类的见解。
但我认为,在构造实际系统时,通常需要更多的人工错误分析,更多的人类见解来架构这些系统。- 尽管很多深度学习的研究人员不愿意承认这点
在机器学习中,有时候一些研究人员很鄙视手工操作
但如果你要搭建应用系统,那这个简单的人工的统计步骤,错误分析,可以节省大量时间,可以迅速决定什么是最重要的,或者最有希望的方向。
实际上,如果你观察100个错误标记的开发集样本,也许只需要5到10分钟的时间。这个在5到10分钟之内就能给你估计某个方向(例如针对狗来优化)有多少价值,并且可以帮助你做出更好的决定
- 尽管很多深度学习的研究人员不愿意承认这点
- 其次,不知道为什么,我看一些工程师和研究人员不愿意亲自去看这些样本。
也许做这些事情很无聊,坐下来看100或几百个样本来统计错误数量,但我经常亲自这么做。- 当我带领一个机器学习团队时,我想知道它所犯的错误,我会亲自去看看这些数据,尝试和一部分错误作斗争。
我想就因为花了这几分钟,或者几个小时去亲自统计数据,真的可以帮你找到需要优先处理的任务,我发现花时间亲自检查数据非常值得,所以我强烈建议你们这样做
- 当我带领一个机器学习团队时,我想知道它所犯的错误,我会亲自去看看这些数据,尝试和一部分错误作斗争。
快速搭建你的第一个系统,并进行迭代(Build your first system quickly, then iterate)
如果你正在开发全新的机器学习应用,我通常会给你这样的建议,你应该尽快建立你的第一个系统原型,然后快速迭代
你可以做很多事情来改进你的机器学习系统
我在语音识别领域研究了很多年,如果你正在考虑建立一个新的语音识别系统,其实你可以走很多方向,可以优先考虑很多事情
比如:
- 有一些技术可以让语音识别系统对嘈杂的背景更加健壮。嘈杂的背景可能是:
- 咖啡店噪音,背景里有很多人在聊天
- 车辆噪音、高速上汽车噪音、或者其他类型噪音
- 让语音识别系统在处理带口音时更健壮
- 还有特定的问题和麦克风与说话人距离很远有关,就是所谓的远场语音识别。
- 儿童的语音识别带来特殊的挑战,挑战来自单词发音方面,还有他们选择的词汇,他们倾向于使用的词汇。
- 比如说话人口吃
- 或者说了很多无意义的短语,比如“哦”,“啊”之类的。你可以选择很多不同的技术,让你听写下来的文本可读性更强
你可以做很多事情来进行改进
Q:如何选择前进的方向?
- 一般来说,对于几乎所有的机器学习程序可能会有50个不同的方向可以前进,并且每个方向都是相对合理的可以改善你的系统。
但挑战在于,你如何选择一个方向集中精力处理?
A:建立一个初始系统,一个快速和粗糙的实现(quick and dirty implementation)。
快速搭好你的第一个系统,然后开始迭代,即:
马上搭好一个机器学习系统原型,
快速设立开发集和测试集还有指标(如果你的目标定错了,之后改也是可以的)
然后找到训练集,训练一下,看看效果,
开始理解你的算法表现如何,在开发集测试集,你的评估指标上表现如何。这能让你确定偏差方差的范围、想出所有能走的方向并选择、知道下一步应该优先做什么、可以观察一些错误让你能错误分析
比如:如果错误分析让你了解到大部分的错误的来源是说话人远离麦克风,这对语音识别构成特殊挑战,那么你就有很好的理由去集中精力研究这些技术,所谓远场语音识别的技术,这基本上就是处理说话人离麦克风很远的情况。
该建议不适用于一个经验丰富的领域
当这个领域有很多可以借鉴的学术文献,处理的问题和你要解决的几乎完全相同。比如说,人脸识别就有很多学术文献,如果你尝试搭建一个人脸识别设备,那么可以从现有大量学术文献为基础出发,你可以一开始就搭建比较复杂的系统。
我见过有限团队想的不够,然后造出过于简单的系统。但更多的,我见到更多的团队想太多,构建太复杂的系统。
数据分布不一(different distributions)
数据分布不匹配时,进行训练和测试
例子一
例子:假设你在开发一个手机应用,用户会上传他们用手机拍摄的照片,你想识别用户从应用中上传的图片是不是猫。
现在你有两个数据来源
- 一个是你真正关心的数据分布,来自应用上传的数据
- 照片更业余,取景不太好,有些甚至很模糊,因为它们都是业余用户拍的
- 数量少,你的应用用户数还不多,也许你只收集到10,000张用户上传的照片
- 另一个数据来源就是你可以用爬虫程序挖掘网页直接下载
- 猫的图片取景专业、高分辨率、拍摄专业
- 数量多,通过爬虫挖掘网页,也许你从互联网上下载了超过200,000张猫图
问题:
你真正关心的是,最终系统处理来自应用程序的这个图片分布时效果好不好
你有一个相对小的数据集,只有10,000个样本来自那个分布,而你还有一个大得多的数据集来自另一个分布,图片的外观和你真正想要处理的并不一样。
但你又不想直接用这10,000张图片,因为这样你的训练集就太小了,使用这20万张图片似乎有帮助。
但是,困境在于,这20万张图片并不完全来自你想要的分布,那么你可以怎么做呢?
解决思路1:合并并随机(不推荐)
你可以做的一件事是将两组数据合并在一起,网页下载200k张和你用户的21k张,这样你就有21万张照片。
你可以把这21万张照片随机分配到训练、开发和测试集中。
我们假设
- 训练集:205000个样本
- 开发集:2500个样本
- 测试集:2500个样本
优劣
- 好处:你的训练集、开发集和测试集都来自同一分布,这样更好管理。
- 坏处:这坏处还不小,如果你观察开发集,这2500个样本其中很多图片都来自网页下载而不是手机的图片,但那并不是你真正关心的数据分布
(数学期望:有2381张图来自网页下载,只有119张图来自手机上传)
解决思路2:(推荐)
- 训练集:205k 个样本(网页下载的200k张图片,手机上传的图片5k张)
- 开发集:2.5k 个样本
- 测试集:2.5k 个样本
优劣
- 好处:你瞄准的目标就是你想要处理的目标
- 缺点:训练集分布和你的开发集、测试集分布并不一样
- 事实证明,该方案能在长期能给你带来更好的系统性能。
后面会讨论一些特殊的技巧,可以处理训练集的分布和开发集和测试集分布不一样的情况
例子二
假设你正在开发一个全新的产品,一个语音激活汽车后视镜(这在中国是个真实存在的产品,它正在进入其他国家)
训练集数据:
你拥有的所有语音数据,从其他语音识别问题收集来的数据
- 比如这些年你从各种语音识别数据供应商买来的数据,今天你可以直接买到成,对的数据,其中是音频剪辑,是听写记录。
- 或者也许你研究过智能音箱,语音激活音箱,
- 也许你做过语音激活键盘的开发之类的。
也许你从这些来源收集了500,000段录音,
开发/测试集数据
实际上来自语音激活后视镜的数据。“请帮我导航到这个街道地址”,或者说:“请帮助我导航到这个加油站”
也许你收集了20,000录音
分配
你的开发集和测试集,我把它简写成和,可能每个集包含10,000段语音,是从实际的语音激活后视镜收集的。
或者,如果你觉得不需要将20,000段来自语音激活后视镜的录音全部放进开发和测试集,也许你可以拿一半,把它放在训练集里,那么训练集可能是51万段语音,包括来自那里的50万段语音,还有来自后视镜的1万段语音
数据分布不匹配时,偏差与方差的分析
估计学习算法的偏差和方差真的可以帮你确定接下来应该优先做的方向
但是,当你的训练集来自和开发集、测试集不同分布时,分析偏差和方差的方式可能不一样
举例
例子:
猫分类器为例,在这个样本中:
- 贝叶斯最优错误率0%(忽略不计)
- 训练集误差是1%
- 开发集误差是10%
分析:
如果你的开发集来自和训练集一样的分布,你可能会说,这里存在很大的方差问题
但如果你的训练数据和开发数据来自不同的分布,你就不能再放心下这个结论了。
特别是,也许训练集都是清晰的、高分辨率的、容易识别的图片,而开发集上的图片难识别得多
解决方案:
使用 训练-开发集
训练-开发集
随机打散训练集,然后分出一部分训练集作为训练-开发集(training-dev),
就像开发集和测试集来自同一分布,训练集、训练-开发集也来自同一分布。
该集作用类似于开发集,注意你只能在训练集上而不能在训练-开发集上训练你的神经网络
下面举例说明用法
举四个例子
(贝叶斯错误率均估计为0%)
例子1 | 例子2 | 例子3 | 例子4 | |
---|---|---|---|---|
贝叶斯错误率 | 约0% | 约0% | 约0% | 约0% |
训练误差 | 1% | 1% | 10% | 10% |
训练-开发误差 | 9% | 1.5% | 11% | 11% |
开发/测试误差 | 10% | 10% | 12% | 20% |
结论 | 存在方差问题 | 方差问题就很小 存在数据不匹配的问题 | 存在可避免偏差问题 | 可避免偏差相当高 数据不匹配问题很大 |
再举两个例子
(用人类水平错误率估计贝叶斯错误率,且不为0%)
例子1 | 例子2 | |
---|---|---|
人类水平错误率 | 4% | 4% |
训练误差 | 7% | 7% |
训练-开发误差 | 10% | 10% |
开发/测试误差 | 12% | 6%(出乎意料的) |
结论 | 数字越往后数字越大 | 数字并没有一直变大 |
补充:
① 表格能大概说明:
可避免偏差问题有多大
方差问题有多大
数据不匹配的问题有多大② 这里没有将开发集和测试集分开。实际上,也应该分开来对比
开发集和测试集来自同一分布,如果存在很大差距的话。那么你就可能对开发集过拟合了
③ 数字不一定从上到下一直变大
说明:训练数据其实比你的开发集和测试集难识别得多。
比如该例子中的语音激活后视镜,就会产生这种情况
整体分析
我们是怎么进行分析的?分析的标准?一些其他的分析
一般的语音识别 General speech recognition | 后视镜语音识别 Rearview mirror speech data | |
---|---|---|
人类水平 Human level | 4% | 6% |
训练误差 Training error | 7% | 6% |
开发-训练误差 Training-dev error | 10% | —— |
开发/测试误差 Dev/Test error | —— | 6% |
(表格横向表示数据的分布来源)
单列分析
- 这两个数字之间的差异(Human level 4%和Training error 7%),衡量了可避免偏差大小(Avoidable error)
- 这两个数字之间的差异(Training error 7%和Training-dev error 10%),衡量了方差大小(Variance)
- 这两个数字之间的差异(Training-dev error 10%和Dev/Test dev 6%)。衡量了数据不匹配问题的大小
整个表格分析
事实证明,把剩下的两个数字(rearview mirror speech data 6%和Error on examples trained on 6%),也放到这个表格里也是有用的。比如:
- 这两个数字之间的差异(General speech recognition Human level 4%和Rearview mirror speech data 6%),说明对于人类来说,后视镜的语音数据实际上比一般语音识别更难
- 有时候填满整个表格,你可能会洞察到更多特征
比如你可以了解到偏差和方差,还有数据不匹配这些问题的不同程度
数据分布不匹配时,一些问题的处理
数据不匹配的其他问题(详见下一节)
当数据不匹配时,上一节我们解决了偏差和方差的一些问题,但是,如果问题不仅来自偏差和方差
比如:你做了错误分析,并发现数据不匹配是大量错误的来源,那么你怎么解决这个问题呢?
数据不匹配,有什么好办法可以处理数据不匹配的呢?
但结果很不幸,并没有很通用、特别系统的方法去解决数据不匹配问题,但你可以做一些尝试
如果我发现有严重的数据不匹配问题,我通常会亲自做错误分析,尝试了解训练集和开发测试集的具体差异
(注意:技术上,为了避免对测试集过拟合,要做错误分析,你应该人工去看开发集而不是测试集)
例子1、解决方案
但作为一个具体的例子,如果你正在开发一个语音激活的后视镜应用,
你可能要听一下来自开发集的样本,尝试弄清楚开发集和训练集到底有什么不同。
不同
- 开发集样本噪音很多,有很多汽车噪音
- 开发集可能经常识别错误街道号码。因为那里有很多导航请求都有街道地址,所以得到正确的街道号码真的很重要
解决策略
- 你可以尝试把训练数据变得更像开发集一点
- 你也可以收集更多类似你的开发集和测试集的数据
具体方案
- 比如说,你发现车辆背景噪音是主要的错误来源,那么你可以模拟车辆噪声数据
- 比如说,你发现很难识别街道号码,那么你可以有意识地收集更多人们说数字的音频数据加到你的训练集里
这里只给出了粗略的指南,列出一些你可以做的尝试,这不是一个系统化的过程,不能保证你一定能取得进展。
人工数据合成方案
你可以利用的其中一种技术是人工合成数据(artificial data synthesis)
也许实际上你没那么多实际在汽车背景噪音下录得的音频,或者在高速公路背景噪音下录得的音频。但是你可以合成。
- 假设你录制了大量清晰的音频,不带车辆背景噪音的音频。
这可能是你的训练集里的一段音频:“The quick brown fox jumps over the lazy dog”(音频播放)
顺带一提,这个句子在AI测试中经常使用,因为这个短句包含了从a到z所有字母。 - 然后你可以收集一段这样的汽车噪音
- 接着把两个音频片段放到一起,你就可以合成出带有汽车噪声的说话声
你还可能会合成其他音频效果,比如混响(就是声音从汽车内壁上反弹叠加的效果)
通过人工数据合成,你可以快速制造更多的训练数据,就像真的在车里录的那样,那就不需要花时间实际出去收集数据
人工数据合成的潜在问题
潜在问题:
比如说你在安静的背景里录得10,000小时音频数据,但你只录了一小时车辆背景噪音。
那么你可能将这1小时汽车噪音回放10,000次,并叠加到在安静的背景下录得的10,000小时数据。
但如果你这么做了,有一个风险,有可能你的学习算法对这1小时汽车噪音过拟合。
解决方法:
我不知道以较低成本收集10,000小时的汽车噪音是否可行。这是可以做的,但不保证能做。
但是使用10,000小时永不重复的汽车噪音,而不是1小时重复学习,算法有可能取得更好的性能。
人工数据合成的挑战在于,人耳是无法分辨这10,000个小时听起来和那1小时没什么区别,所以你可能自己没意识这个问题
另一个例子:
假设你在研发无人驾驶汽车,你可能希望检测出这样的车,然后用这样的框包住它。
很多人都讨论过的一个思路是,为什么不用计算机合成图像来模拟成千上万的车辆呢?
事实上,这里有几张车辆照片(下图后两张图片),其实是用计算机合成的。
虽然这个合成是相当逼真,人类很难分辨出来,但是问题依然存在
总而言之:
如果你认为存在数据不匹配问题,我建议你做错误分析
或者看看训练集,或者看看开发集,试图找出,试图了解这两个数据分布到底有什么不同,然后看看是否有办法收集更多看起来像开发集的数据作训练。
其中一种办法是人工数据合成,人工数据合成确实有效。
在语音识别中,显著提升了系统的表现,所以这是可行的。
但当你使用人工数据合成时,一定要谨慎,要记住你有可能从所有可能性的空间只选了很小一部分去模拟数据。
多个学习任务
在实践中,多任务学习的使用频率要低于迁移学习,也许其中一个例外是计算机视觉里的物体检测
迁移学习(Transfer learning)
概念
深度学习中,最强大的理念之一就是,有的时候神经网络可以从一个任务中习得知识,并将这些知识应用到另一个独立的任务中。
例如,也许你已经训练好一个神经网络识别像猫这样的对象,然后使用那些知识,或者部分习得的知识去帮助您更好地阅读x射线扫描图
这就是所谓的迁移学习
例子1
需求
假设你已经训练好一个图像识别神经网络,其中是图像,是某些对象,识别图像是猫、狗、鸟或其他东西。
如果你把这个神经网络拿来,然后让它适应或者说迁移,在不同任务中学到的知识,比如放射科诊断,就是说阅读射线扫描图。
做法
把神经网络最后的输出层删掉,还有最后一层的权重删掉。然后为最后一层重新赋予随机权重,我们称之为和随机初始化。
然后让它在放射诊断数据上训练(新的x-y对上训练)要用放射科数据集重新训练神经网络有几种做法,经验规则是
如果你的放射科数据集很小
你可能只需要重新训练最后一层的权重,就是随机初始化和并保持其他参数不变。
或者只训练输出层前的最后一层,或者也许是最后一两层
如果你的放射科数据集够多
你可以重新训练神经网络中剩下的所有层。
例子2
需求
假设你已经训练出一个语音识别系统,现在是音频或音频片段输入,而是听写文本
你已经训练了语音识别系统,让它输出听写文本现在我们说你想搭建一个“唤醒词”或“触发词”检测系统,所谓唤醒词或触发词就是我们说的一句话,可以唤醒家里的语音控制设备,
比如你说“Alexa”可以唤醒一个亚马逊Echo设备,或用“OK Google”来唤醒Google设备,用"Hey Siri"来唤醒苹果设备,用"你好百度"唤醒一个百度设备。
做法
要做到这点,你可能需要去掉神经网络的最后一层,然后加入新的输出节点,但有时你可以不只加入一个新节点,或者甚至往你的神经网络加入几个新层,
然后把唤醒词检测问题的标签喂进去训练。
再次说明,这取决于你有多少数据,你可能只需要重新训练网络的新层,也许你需要重新训练神经网络中更多的层。
(两个例子的图)

预训练和微调
如果你重新训练神经网络中的所有参数,那么这个在图像识别数据的初期训练阶段,有时称为预训练(pre-training),
因为你在用图像识别数据去预先初始化,或者预训练神经网络的权重。
如果你以后更新所有权重,然后在放射科数据上训练,有时这个过程叫微调(fine tuning)。
如果你在深度学习文献中看到预训练和微调,你就知道它们说的是这个意思,预训练和微调的权重来源于迁移学习。
为什么有效?
在这个例子中你做的是,把图像识别中学到的知识应用或迁移到放射科诊断上来,为什么这样做有效果呢?
有很多低层次特征,比如说边缘检测、曲线检测、阳性对象检测(positive objects),
从非常大的图像识别数据库中习得这些能力可能有助于你的学习算法在放射科诊断中做得更好,算法学到了很多结构信息,图像形状的信息,其中一些知识可能会很有用,所以学会了图像识别,它就可能学到足够多的信息,可以了解不同图像的组成部分是怎样的,学到线条、点、曲线这些知识,也许对象的一小部分,这些知识有可能帮助你的放射科诊断网络学习更快一些,或者需要更少的学习数据。
适用场合
迁移学习什么时候是有意义的呢?
适用场合是:(将任务A迁移到任务B)
任务A和任务B有相同的输入x
任务A数据量多于任务B
(不满足该点也能用,可能不会有害,但迁移学习可能就没有意义了)
来自A的低级特征可能有助于学习B
例如
图像识别
假设图像识别任务中你有1百万个样本,所以这里数据相当多。可以学习低层次特征,可以在神经网络的前面几层学到如何识别很多有用的特征。
但是对于放射科任务,也许你只有一百个样本,所以你的放射学诊断问题数据很少,也许只有100次射线扫描
语音识别
对于语音识别,也许你已经用10,000小时数据训练过你的语言识别系统,所以你从这10,000小时数据学到了很多人类声音的特征
但对于触发字检测,也许你只有1小时数据,所以这数据太小,不能用来拟合很多参数。
所以在这种情况下,预先学到很多人类声音的特征人类语言的组成部分等等知识,可以帮你建立一个很好的唤醒字检测器,即使你的数据集相对较小
多任务学习(Multi-task learning)
概念
- 迁移学习:你的步骤是串行的,你从任务里学习只是然后迁移到任务。
- 多任务学习中:你是同时开始学习的,试图让单个神经网络同时做几件事情,然后希望这里每个任务都能帮到其他所有任务。
例子
假设你在研发无人驾驶车辆,那么你的无人驾驶车可能需要同时检测不同的物体,比如检测行人、车辆、停车标志,还有交通灯各种其他东西。
比如下图中,图像里有个停车标志,然后图像中有辆车,但没有行人,也没有交通灯。
如果这是输入图像,那么输出不是一个标签 ,而是有4个标签。 是个4×1向量。(有点类似与softmax输出层)
训练集输出的向量化:
这里我们设定四个节点,是4×1向量
- 第一个:预测有没有 行人
- 第二个:预测有没有 车
- 第三个:预测有没有 停车标志
- 第四个:预测有没有 交通灯
定义损失函数:
与之前逻辑回归相比:公式多了红色的部分,你要对求和
与softmax回归的主要区别在于:softmax将单个标签分配给单个样本,而这张图可以有很多不同的标签
(即概率和可以不为一)不是说每张图都只是一张行人图片,汽车图片、停车标志图片或者交通灯图片。多个物体可能同时出现在一张图里。
训练四个神经网络 or 训练一个多任务神经网络
另外你也可以训练四个不同的神经网络,而不是训练一个网络做四件事情。但神经网络一些早期特征,在识别不同物体时都会用到,然后你发现:
训练一个神经网络做四件事情会比训练四个完全独立的神经网络分别做四件事性能要更好,这就是多任务学习的力量。
只有部分物体被标记
另一个细节,到目前为止,我是这么描述算法的,好像每张图都有全部标签。
事实证明,多任务学习也可以处理图像只有部分物体被标记的情况。
比如一个训练样本中,给数据贴标签的人告诉你里面有一个行人,没有车,但他们没有标记是否有停车标志,或者是否有交通灯
那么那两项就是标记为问号
即使是这样的数据集,你也可以在上面训练算法
训练时,对从1到4求和时,你就只对带0和1标签的值求和。即当有问号的时候,你就在求和时忽略那个项,这样只对有标签的值求和
适用场合
那么多任务学习什么时候有意义呢?当三件事为真时,它就是有意义的。
第一,你训练的一组任务,可以共用低层次特征。
- 比如对于无人驾驶的例子,同时识别交通灯、汽车和行人是有道理的,这些物体有相似的特征
第二,每个任务的数据量很接近(这个准则没有那么绝对,不一定是对的)
类比迁移学习
你从任务学到知识然后迁移到任务,所以如果任务有1百万个样本,任务只有1000个样本,
那么你从这1百万个样本学到的知识,真的可以帮你增强对更小数据集任务的训练。那么多任务学习又怎么样呢?原理
比如说你要尝试同时识别100种不同类型的物体,每个任务大概有1000个样本。
比如我们专注加强第100个任务的表现。如果你试图单独去做这个任务,你只有1000个样本,效果可能会很差。
而通过在其他99项任务的训练(加起来有99000个样本),可以提供很多知识来增强这个任务的性能。其他任务也是同理。第二点不是绝对正确的准则
但关键在于,如果对于单个任务有1000个样本了,那么其他任务之和最好有超过1000个样本,这样其他任务的知识才能帮你改善这个任务的性能
第三,可以训练一个足够大的神经网络来完成所有任务
- 多任务学习的替代方法是为每个任务训练一个单独的神经网络
但一般来说训练一个神经网络做多件事情会比训练多个完全独立的神经网络分别做多件事性能要更好 - 研究员Rich Carona几年前发现:
多任务学习会降低性能的唯一情况,是训练单个神经网络相比性能更低的情况就是你的神经网络还不够大。
但如果你可以训练一个足够大的神经网络,那么多任务学习肯定不会或者很少会降低性能,比单独训练神经网络来单独完成各个任务性能要更好。
- 多任务学习的替代方法是为每个任务训练一个单独的神经网络
实际上,多任务学习我觉得使用频率比迁移学习要少得多,也许其中一个例外是计算机视觉里的物体检测
端到端的深度学习(end-to-end deep learning)
概念
深度学习中最令人振奋的最新动态之一就是端到端深度学习的兴起,那么端到端学习到底是什么呢?
- 旧方案:以前有一些数据处理系统或者学习系统,它们需要多个阶段的处理
- 新方案:那么端到端深度学习就是忽略这些不同的阶段,将其代替为单个神经网络
为什么叫这个名字
这是端到端学习的输入端,是输出端,所以你需要很多这样的数据,在输入端和输出端都有数据,这样可以训练这些系统。
这就是为什么我们称之为端到端学习,因为你直接学习出从系统的一端到系统的另一端。
例子1 - 语音识别
(端对端更优)
以语音识别为例,你的目标是输入,比如说一段音频,然后把它映射到一个输出,就是这段音频的听写文本。
传统的方案
语音识别需要很多阶段的处理。首先你会提取一些特征,一些手工设计的音频特征。
也许你听过MFCC,这种算法是用来从音频中提取一组特定的人工设计的特征。
在提取出一些低层次特征之后,你可以应用机器学习算法在音频片段中找到音位,所以音位是声音的基本单位。
比如说“Cat”这个词是三个音节构成的,Cu-、Ah-和Tu-,算法就把这三个音位提取出来。
将音位串在一起构成独立的词,将词串起来构成音频片段的听写文本
端到端深度学习
- 和这种有很多阶段的流水线相比,你训练一个巨大的神经网络。输入就是一段音频,输出直接是听写文本
比较 / 选用
AI的其中一个有趣的社会学效应是,随着端到端深度学习系统表现开始更好,
有一些花了大量时间或者整个事业生涯设计出流水线各个步骤的研究员,不只是语言识别领域的,也许是计算机视觉,还有其他领域。
他们花了大量的时间,写了很多论文,有些甚至整个职业生涯的一大部分都投入到开发这个流水线的功能或者其他构件上去了。
端到端深度学习就只需要把训练集拿过来,直接学到了和之间的函数映射,直接绕过了其中很多步骤。
对一些学科里的人来说,这点相当难以接受,他们无法接受这样构建AI系统但有些情况,端到端方法完全取代了旧系统,某些投入了多年研究的中间组件也许已经过时了
端到端深度学习的挑战之一是,你可能需要大量数据才能让系统表现良好
- 比如,你只有3000小时数据去训练你的语音识别系统,那么传统的流水线效果真的很好
- 但当你拥有非常大的数据集时,比如10,000小时数据或者100,000小时数据,这样端到端方法突然开始很厉害了
选用
- 所以当你的数据集较小的时候,传统流水线方法其实效果也不错,通常做得更好
- 你需要大数据集才能让端到端方法真正发出耀眼光芒
例子2 - 门禁识别
(非端对端更优)
这张图上是一个研究员做的人脸识别门禁,是百度的林元庆研究员做的。
这是一个相机,它会拍下接近门禁的人,如果它认出了那个人,门禁系统就自动打开,让他通过,所以你不需要刷一个RFID工卡就能进入这个设施。
系统部署在越来越多的中国办公室,希望在其他国家也可以部署更多,你可以接近门禁,如果它认出你的脸,它就直接让你通过,你不需要带RFID工卡。
那么,怎么搭建这样的系统呢?
方案1,一步到位
尝试直接学习图像到人物身份的函数映射
但事实证明这不是最好的方法。
其中一个问题是,人可以从很多不同的角度接近门禁,
他们可能在绿色位置,可能在蓝色位置。有时他们更靠近相机,所以他们看起来更大,有时候他们非常接近相机,那照片中脸就很大了。
在实际研制这些门禁系统时,他不是直接将原始照片喂到一个神经网络,试图找出一个人的身份。
方案2,多步方法
相反,迄今为止最好的方法似乎是一个多步方法
- 首先,你运行一个软件来检测人脸,所以第一个检测器找的是人脸位置,检测到人脸,然后放大图像的那部分,并裁剪图像,使人脸居中显示,然后就是这里红线框起来的照片
- 再喂到神经网络里,让网络去学习,或估计那人的身份
研究人员发现,比起一步到位,把这个问题分解成两个更简单的步骤。
- 首先,是弄清楚脸在哪里
- 第二步是看着脸,弄清楚这是谁
这第二种方法让学习算法,或者说两个学习算法分别解决两个更简单的任务,并在整体上得到更好的表现。
顺便说一句,如果你想知道第二步实际是怎么工作的,我这里其实省略了很多。
训练第二步的方式,训练网络的方式就是输入两张图片,然后你的网络做的就是将输入的两张图比较一下,判断是否是同一个人。
比如你记录了10,000个员工ID,你可以把红色框起来的图像快速比较,看看这张红线内的照片,是不是那10000个员工之一,来判断是否应该允许其进入这个设施或者进入这个办公楼。
比较 / 选用
为什么两步法更好呢?实际上有两个原因:
- 一是,你解决的两个问题,每个问题实际上要简单得多
- 第二,两个子任务的训练数据都很多
- 具体来说,有很多数据可以用于人脸识别训练,对于这里的任务1来说,任务就是观察一张图,找出人脸所在的位置,把人脸图像框出来,所以有很多数据,有很多标签数据,其中是图片,是表示人脸的位置,你可以建立一个神经网络,可以很好地处理任务1。
- 然后任务2,也有很多数据可用,今天,业界领先的公司拥有,比如说数百万张人脸照片,所以输入一张裁剪得很紧凑的照片,比如这张红色照片,下面这个,今天业界领先的人脸识别团队有至少数亿的图像,他们可以用来观察两张图片,并试图判断照片里人的身份,确定是否同一个人,所以任务2还有很多数据。
- 相比之下,如果你想一步到位,这样的数据对就少得多,其中是门禁系统拍摄的图像,是那人的身份,
你没有足够多的数据去解决这个端到端学习问题,但你却有足够多的数据来解决子问题1和子问题2
实际上,把这个分成两个子问题,比纯粹的端到端深度学习方法,达到更好的表现。
不过如果你有足够多的数据来做端到端学习,也许端到端方法效果更好。但在今天的实践中,并不是最好的方法。
例子3 - 机器翻译
(端对端更优)
比如机器翻译
传统上,机器翻译系统也有一个很复杂的流水线,比如英语机翻得到文本,然后做文本分析,基本上要从文本中提取一些特征之类的,经过很多步骤,你最后会将英文文本翻译成法文。
因为对于机器翻译来说的确有很多 (英文,法文) 的数据对,端到端深度学习在机器翻译领域非常好用,那是因为在今天可以收集对的大数据集,就是英文句子和对应的法语翻译。
所以在这个例子中,端到端深度学习效果更好。
例子4 - X光照片
(非端对端更优)
最后一个例子,比如说你希望观察一个孩子手部的X光照片,并估计一个孩子的年龄。
这个问题的典型应用,从X射线图估计孩子的年龄,这是儿科医生用来判断一个孩子的发育是否正常。
处理这个例子的一个非端到端方法,就是照一张图,然后分割出每一块骨头,所以就是分辨出那段骨头应该在哪里,那段骨头在哪里,那段骨头在哪里,等等。然后,知道不同骨骼的长度,你可以去查表,查到儿童手中骨头的平均长度,然后用它来估计孩子的年龄,所以这种方法实际上很好。
相比之下,如果你直接从图像去判断孩子的年龄,那么你需要大量的数据去直接训练。
据我所知,这种做法今天还是不行的,因为没有足够的数据来用端到端的方式来训练这个任务。
你可以想象一下如何将这个问题分解成两个步骤,
- 第一步是一个比较简单的问题,也许你不需要那么多数据,也许你不需要许多X射线图像来切分骨骼。
- 而任务二,收集儿童手部的骨头长度的统计数据,你不需要太多数据也能做出相当准确的估计,所以这个多步方法看起来很有希望,也许比端对端方法更有希望,至少直到你能获得更多端到端学习的数据之前。
例子5 - 无人驾驶
最后我讲一个更复杂的例子,你可能知道我一直在花时间帮忙主攻无人驾驶技术的公司drive.ai,无人驾驶技术的发展其实让我相当激动。
你怎么造出一辆自己能行驶的车呢?
这不是端到端的深度学习方法
第一步:
你可以把你车前方的雷达、激光雷达或者其他传感器的读数看成是输入图像。
但是为了说明起来简单,我们就说拍一张车前方或者周围的照片,然后驾驶要安全的话,你必须能检测到附近的车,你也需要检测到行人,你需要检测其他的东西,当然,我们这里提供的是高度简化的例子。
第二步:
弄清楚其他车和形如的位置之后,你就需要计划你自己的路线。
所以换句话说,当你看到其他车子在哪,行人在哪里,你需要决定如何摆方向盘在接下来的几秒钟内引导车子的路径。
如果你决定了要走特定的路径,也许这是道路的俯视图,这是你的车,也许你决定了要走那条路线,这是一条路线,那么你就需要摆动你的方向盘到合适的角度,还要发出合适的加速和制动指令。
总结:
所以从传感器或图像输入到检测行人和车辆,深度学习可以做得很好。
但一旦知道其他车辆和行人的位置或者动向,选择一条车要走的路,这通常用的不是深度学习,而是用所谓的运动规划软件完成的。
如果你学过机器人课程,你一定知道运动规划,然后决定了你的车子要走的路径之后。
还会有一些其他算法,我们说这是一个控制算法,可以产生精确的决策确定方向盘应该精确地转多少度,油门或刹车上应该用多少力。
选用
这节讨论是否要使用端到端深度学习方法
端到端深度学习的一些优缺点(Pros and Cons,并不是单词缩写)
优点
只让数据说话(而不是被迫引入人类的成见)(有利有弊)
使用纯机器学习方法,直接从到输入去训练的神经网络,可能更能够捕获数据中的任何统计信息。
例如:
在语音识别领域,早期的识别系统有这个音位概念,就是基本的声音单元,如cat单词的“cat”的Cu-、Ah-和Tu-,
这个音位是人类语言学家生造出来的,我实际上认为音位其实是语音学家的幻想。虽然用音位描述语言也还算合理,但是不要强迫你的学习算法以音位为单位思考。这点有时没那么明显。
如果你让你的学习算法学习它想学习的任意表示方式,而不是强迫你的学习算法使用音位作为表示方式,那么其整体表现可能会更好。所需的手工设计组件更少
所以这也许能够简化你的设计工作流程,你不需要花太多时间去手工设计功能,手工设计这些中间表示方式。
缺点
可能需要大量的数据
例如之前的门禁系统的例子
你可以收集大量子任务数据。
比如人脸识别,我们可以收集很多数据用来分辨图像中的人脸;当你找到一张脸后,也可以找得到很多人脸识别数据。但是对于整个端到端任务,可能只有更少的数据可用。
排除了可能有用的手工设计组件(有利有弊)
机器学习研究人员一般都很鄙视手工设计的东西,但如果你没有很多数据,你的学习算法就没办法从很小的训练集数据中获得洞察力。
所以手工设计组件在这种情况,可能是把人类知识直接注入算法的途径,这总不是一件坏事。
选用
双刃剑
手工设计组件算是双刃剑,可能有坏处,可能有好处,但往往好处更多,手工设计的组件往往在训练集更小的时候帮助更大。
学习算法有两个主要的知识来源
- 一个是数据
- 另一个是你手工设计的任何东西,可能是组件,功能,或者其他东西。
利:
当你有大量数据时,手工设计的东西就不太重要了。
但是当你没有太多的数据时,构造一个精心设计的系统,实际上可以将人类对这个问题的很多认识直接注入到问题里,对算法里应该挺有帮助的。弊:
精心设计的人工组件可能非常有用,但也有可能真的伤害到你的算法表现。
例如,强制你的算法以音位为单位思考,也许让算法自己找到更好的表示方法更好。
我认为关键的问题是,你有足够的数据能够直接学到从映射到足够复杂的函数吗?
“必要复杂度/复杂性需要(complexity needed)” (这啥意思,视频好像没解释?)
局部使用深度学习:
还有一种情况,就是前面举的无人驾驶的例子。
你想使用机器学习或者深度学习来学习某些单独的组件
相比之下,谈论纯端到端深度学习方法是很激动人心的,你输入图像,直接得出方向盘转角,但是就目前能收集到的数据而言,还有我们今天能够用神经网络学习的数据类型而言,这实际上不是最有希望的方法,或者说这个方法并不是团队想出的最好用的方法。而我认为这种纯粹的端到端深度学习方法,其实前景不如这样更复杂的多步方法。因为目前能收集到的数据,还有我们现在训练神经网络的能力是有局限的。