第二周:机器学习策略(2)(ML Strategy (2))
2.1 进行误差分析(Carrying out error analysis)
如果希望让学习算法能够胜任人类能做的任务,但学习算法还没有达到人类的表现,那么人工检查一下算法犯的错误可以了解接下来应该做什么,这个过程称为错误分析
假设正在调试猫分类器,取得了90%准确率,相当于10%错误,注意到算法将一些狗分类为猫,需要对模型的一些部分做相应调整,才能更好地提升分类的精度
收集错误样例:
在开发集(测试集)中,获取大约100个错误标记的例子,然后手动检查,一次只看一个,看看开发集里有多少错误标记的样本是狗
100个数据中有5个样例是狗,如果对数据集的错误标记做努力去改进模型的精度,可以提升的上限是5%,仅可以达到9.5%的错误率,称为性能上限(ceiling on performance)。
这种情况下,这样耗时的努力方向不是很值得的事
100个数据中,有50多个样例是狗,改进数据集的错误标记是一个值得的改进方向,可以将模型的精确度提升至95
并行分析:
修改那些被分类成猫的狗狗图片标签
修改那些被错误分类的大型猫科动物,如:狮子,豹子等
提升模糊图片的质量
为了并行的分析,可以建立表格来进行。在最左边,人工过一遍想分析的图像集,电子表格的每一列对应要评估的想法,如狗的问题,猫科动物的问题,模糊图像的问题,最后一列写评论
在这个步骤做到一半时,可能会发现其他错误类型,比如可能发现有Instagram滤镜,那些花哨的图像滤镜,干扰了分类器。在这种情况下可以在错误分析途中,增加一列多色滤镜 Instagram滤镜和Snapchat滤镜,再过一遍,并确定新的错误类型百分比,这个分析步骤的结果可以给出一个估计,是否值得去处理每个不同的错误类型
可以把团队可以分成两个团队,其中一个改善大猫的识别,另一个改善模糊图片的识别
总结:
进行错误分析,应该找一组错误样本,可能在开发集或者测试集,观察错误标记的样本,看看假阳性(false positives)和假阴性(false negatives),统计属于不同错误类型的错误数量。在这个过程中,可能会得到启发,归纳出新的错误类型,通过统计不同错误标记类型的百分比,可以发现哪些问题需要优先解决
2.2 清楚标注错误的数据(Cleaning up Incorrectly labeled data)
监督学习问题的数据由输入和输出标签 构成,如果发现有些输出标签 是错的,是否值得花时间去修正这些标签?
倒数第二不是猫,是标记错误的样本。“标记错误的样本”表示学习算法输出了错误的 值,如果数据有一些标记错误的样本,该怎么办?
训练集:深度学习算法对于训练集中的随机错误是相当健壮的(robust)。只要这些错误样本离随机错误不太远,有时可能做标记的人没有注意或者不小心,按错键了,如果错误足够随机,放着这些错误不管可能也没问题,而不要花太多时间修复它们,只要总数据集足够大,实际错误率可能不会太高
深度学习算法对随机误差很健壮,但对系统性的错误没那么健壮。如果做标记的人一直把白色的狗标记成猫,那就成问题。因为分类器学习之后,会把所有白色的狗都分类为猫。但随机错误或近似随机错误,对于大多数深度学习算法来说不成问题
开发集和测试集有标记出错的样本:在错误分析时,添加一个额外的列,统计标签 错误的样本数。统计因为标签错误所占的百分比,解释为什么学习算法做出和数据集的标记不一样的预测1
是否值得修正6%标记出错的样本:
如果标记错误严重影响了在开发集上评估算法的能力,应该去花时间修正错误的标签
如果没有严重影响到用开发集评估成本偏差的能力,不应该花时间去处理
看3个数字来确定是否值得去人工修正标记出错的数据:
看整体的开发集错误率,系统达到了90%整体准确度,10%错误率,应该看错误标记引起的错误的数量或者百分比。6%的错误来自标记出错,10%的6%是0.6%,剩下的占9.4%,是其他原因导致的,比如把狗误认为猫,大猫图片。即有9.4%错误率需要集中精力修正,而标记出错导致的错误是总体错误的一小部分而已,应该看其他原因导致的错误
错误率降到了2%,但总体错误中的0.6%还是标记出错导致的。修正开发集里的错误标签更有价值
开发集的主要目的是从两个分类器和中选择一个。当测试两个分类器和时,在开发集上一个有2.1%错误率,另一个有1.9%错误率,但是不能再信任开发集,因为它无法告诉你这个分类器是否比这个好,因为0.6%的错误率是标记出错导致的。现在就有很好的理由去修正开发集里的错误标签,因为右边这个样本标记出错对算法错误的整体评估标准有严重的影响,而左边相对较小
如果决定要去修正开发集数据,手动重新检查标签,并尝试修正一些标签,这里还有一些额外的方针和原则需要考虑:
不管用什么修正手段,都要同时作用到开发集和测试集上,开发和测试集必须来自相同的分布。开发集确定了目标,当击中目标后,希望算法能够推广到测试集上,这样能够更高效的在来自同一分布的开发集和测试集上迭代
如果打算修正开发集上的部分数据,最好也对测试集做同样的修正以确保它们继续来自相同的分布。可以让一个人来仔细检查这些标签,但必须同时检查开发集和测试集
要同时检验算法判断正确和判断错误的样本,如果只修正算法出错的样本,算法的偏差估计可能会变大,会让算法有一点不公平的优势
修正训练集中的标签相对没那么重要,如果训练集来自稍微不同的分布,对于这种情况学习算法其实相当健壮,通常是一件很合理的事情
几个建议:
构造实际系统时,需要更多的人工错误分析,更多的人类见解来架构这些系统
搭建机器学习系统时,花时间亲自检查数据非常值得,可以帮你找到需要优先处理的任务,然后确定应该优先尝试哪些想法,或者哪些方向
2.3 快速搭建你的第一个系统,并进行迭代(Build your first system quickly, then iterate)
如果正在开发全新的机器学习应用,应该尽快建立第一个系统原型,然后快速迭代
改进语音识别系统特定的技术:
对于几乎所有的机器学习程序可能会有50个不同的方向可以前进,并且每个方向都是相对合理的可以改善系统。但挑战在于如何选择一个方向集中精力处理。如果想搭建全新的机器学习程序,就是快速搭好第一个系统,然后开始迭代。首先快速设立开发集和测试集还有指标,决定目标所在,如果目标定错,之后改也可以。但一定要设立某个目标,然后马上搭好一个机器学习系统原型,找到训练集训练一下,看算法表现如何,在开发集测试集,评估指标表现如何。当建立第一个系统后,就可以马上用到偏差方差分析和错误分析,来确定下一步优先做什么。如果错误分析到大部分的错误来源是说话人远离麦克风,就有很好的理由去集中精力研究这些技术,所谓远场语音识别的技术,就是处理说话人离麦克风很远的情况
建立初始系统所有意义:是一个快速和粗糙的实现(quick and dirty implementation),有一个学习过的系统,有一个训练过的系统,确定偏差方差的范围,知道下一步应该优先做什么,能够进行错误分析,观察一些错误,然后想出所有能走的方向,哪些是实际上最有希望的方向
当这个领域有很多可以借鉴的学术文献,处理的问题和要解决的几乎完全相同,比如人脸识别有很多学术文献,如果搭建一个人脸识别设备,可以从现有大量学术文献为基础出发,一开始就搭建比较复杂的系统。但如果第一次处理某个新问题,还是构建一些快速而粗糙的实现,然后用来找到改善系统要优先处理的方向
2.4 在不同的划分上进行训练并测试(Training and testing on different distributions)
猫咪识别
假设只收集到10,000张用户上传的照片和超过20万张网上下载的高清猫图:
做法一:将两组数据合并在一起,把这21万张照片随机分配到训练、开发和测试集中。假设已经确定开发集和测试集各包含2500个样本,训练集有205000个样本。
好处:训练集、开发集和测试集都来自同一分布
坏处:开发集的2500个样本中很多图片都来自网页下载的图片,并不是真正关心的数据分布,因为真正要处理的是来自手机的图片
2500个样本有张图来自网页下载,平均只有119张图来自手机上传。设立开发集的目的是告诉团队去瞄准的目标,而瞄准目标的大部分精力却都用在优化来自网页下载的图片
建议:开发集和测试集都是2500张来自应用的图片,训练集包含来自网页的20万张图片还有5000张来自应用的图片,现在瞄准的目标就是想要处理的目标,才是真正关心的图片分布
语音激活后视镜
假设有很多不是来自语音激活后视镜的数据
分配:
训练集500k段语音,开发集和测试集各包含10k段语音(从实际的语音激活后视镜收集)
也可以拿一半放训练集里,训练集51万段语音,开发集和测试集各5000
2.5 不匹配数据划分的偏差和方差(Bias and Variance with mismatched data distributions)
当训练集和开发集、测试集不同分布时,分析偏差和方差的方式:
算法只见过训练集数据,没见过开发集数据(方差)
开发集数据来自不同的分布
为了弄清楚哪个因素影响更大,定义一组新的数据,称之为训练-开发集,是一个新的数据子集。从训练集的分布里分出来,但不会用来训练网络
随机打散训练集,分出一部分训练集作为训练-开发集(training-dev),训练集、训练-开发集来自同一分布
只在训练集训练神经网络,不让神经网络在训练-开发集上跑后向传播。为了进行误差分析,应该看分类器在训练集上的误差、训练-开发集上的误差、开发集上的误差
假设训练误差是1%,训练-开发集上的误差是9%,开发集误差是10%,存在方差,因为训练-开发集的错误率是在和训练集来自同一分布的数据中测得的,尽管神经网络在训练集中表现良好,但无法泛化到来自相同分布的训练-开发集
假设训练误差为1%,训练-开发误差为1.5%,开发集错误率10%。方差很小,当转到开发集时错误率大大上升,是数据不匹配的问题
如果训练集误差是10%,训练-开发误差是11%,开发误差为12%,人类水平对贝叶斯错误率的估计大概是0%,存在可避免偏差问题
如果训练集误差是10%,训练-开发误差是11%,开发误差是20%,有两个问题
可避免偏差问题
数据不匹配问题
如果加入测试集错误率,而开发集表现和测试集表现有很大差距,可能对开发集过拟合,需要一个更大的开发集
如果人类的表现是4%,训练错误率是7%,训练-开发错误率是10%。开发集是6%。可能开发测试集分布比实际处理的数据容易得多,错误率可能会下降
Human level 4%和Training error 7%衡量了可避免偏差大小,Training error 7%和Training-dev error 10%衡量了方差大小,Training-dev error 10%和Dev/Test dev 6%衡量了数据不匹配问题的大小
rearview mirror speech data 6%和Error on examples trained on 6%:获得这个数字的方式是让一些人标记他们的后视镜语音识别数据,看看人类在这个任务里能做多好,然后收集一些后视镜语音识别数据,放在训练集中,让神经网络去学习,测量那个数据子集上的错误率,如果得到rearview mirror speech data 6%和Error on examples trained on 6%,说明在后视镜语音数据上达到人类水平
General speech recognition Human level 4%和rearview mirror speech data 6%:说明后视镜的语音数据比一般语音识别更难,因为人类都有6%的错误,而不是4%的错误
总结:
开发集、测试集不同分布:
可以提供更多训练数据,有助于提高学习算法的性能
潜在问题不只是偏差和方差问题,还有数据不匹配
2.6 定位数据不匹配(Addressing data mismatch)
解决train set与dev/test set样本分布不一致的两条建议:
为了让训练数据更接近开发集,可以人工合成数据(artificial data synthesis)。例如说话人识别问题,实际应用场合(dev/test set)是包含背景噪声的,而训练样本train set很可能没有背景噪声。为了让train set与dev/test set分布一致,可以在train set上人工添加背景噪声,合成类似实际场景的声音。这样会让模型训练的效果更准确。但是不能给每段语音都增加同一段背景噪声,会出现对背景噪音过拟合,这就是人工数据合成需要注意的地方
研发无人驾驶汽车,用计算机合成图像
如果只合成这些车中很小的子集,学习算法可能会对合成的这一个小子集过拟合
2.7 迁移学习(Transfer learning)
将已经训练好的模型的一部分知识(网络结构)直接应用到另一个类似模型中去。比如已经训练好一个猫类识别的神经网络模型,直接把该模型中的一部分网络结构应用到使用X光片预测疾病的模型中去,这种学习方法被称为迁移学习(Transfer Learning)
如果已经有一个训练好的神经网络用来做图像识别。想要构建另一个X光片进行诊断的模型。迁移学习的做法是无需重新构建新的模型,而是利用之前的神经网络模型,只改变样本输入、输出以及输出层的权重系数,即对新的样本(X,Y),重新训练输出层权重系数,其它层所有的权重系数保持不变
如果需要构建新模型的样本数量较少,可以只训练输出层的权重系数,保持其它层所有的权重系数不变
如果样本数量足够多,可以只保留网络结构,重新训练所有层的权重系数。这种做法使得模型更加精确,因为样本对模型的影响最大
选择哪种方法通常由数据量决定
如果重新训练所有权重系数,初始由之前的模型训练得到,这一过程称为pre-training。之后,不断调试、优化的过程称为fine-tuning。pre-training和fine-tuning分别对应上图中的黑色箭头和红色箭头
迁移学习能这么做的原因是神经网络浅层部分能够检测出许多图片固有特征,例如图像边缘、曲线等。使用之前训练好的神经网络部分结果有助于更快更准确地提取X光片特征。二者处理的都是图片,而图片处理是有相同的地方,第一个训练好的神经网络已经实现如何提取图片有用特征。即便是即将训练的第二个神经网络样本数目少,仍然可以根据第一个神经网络结构和权重系数得到健壮性好的模型
迁移学习可以保留原神经网络的一部分,再添加新的网络层,可以去掉输出层后再增加额外一些神经层
迁移学习的应用场合主要包括三点:
Task A and B have the same input x.
You have a lot more data for Task A than Task B.
Low level features from A could be helpful for learning B.
2.8 多任务学习(Multi-task learning)
在迁移学习中,步骤是串行的,从任务里学习然后只是迁移到任务。在多任务学习中是同时开始学习的,试图让单个神经网络同时做几件事情,希望每个任务都能帮到其他所有任务
假设无人驾驶需要同时检测行人、车辆、停车标志,还有交通灯各种其他东西
如果输入图像,那么 不再是一个标签,而是有4个标签。在这个例子中,没有行人,有一辆车,有一个停车标志,没有交通灯。所以 是个4×1向量。将训练集的标签水平堆叠起来,从一直到:
矩阵变成矩阵
输出四个节点,第一个节点是预测图中有没有行人,第二个预测有没有车,第三预测有没有停车标志,第四预测有没有交通灯,所以是四维
整个训练集的平均损失:
是单个预测的损失,所以这是对四个分量的求和,行人、车、停车标志、交通灯,标志指的是logistic损失:
Multi-task learning与Softmax regression的区别在于:
Multi-task learning是multiple labels的,即输出向量y可以有多个元素为1
Softmax regression是single label的,即输出向量y只有一个元素为1
神经网络一些早期特征,在识别不同物体时都会用到,训练一个神经网络做四件事情会比训练四个完全独立的神经网络分别做四件事性能要更好
多任务学习也可以处理图像只有部分物体被标记的情况。比如没有标记是否有停车标志,或者是否有交通灯。也许有些样本都有标记,有些样本只标记了有没有车,然后还有一些是问号
即使是这样的数据集,也可以在上面训练算法,同时做四个任务,即使一些图像只有一小部分标签,其他是问号。训练算法的方式是对从1到4只对带0和1标签的值求和,当有问号就在求和时忽略那个项
多任务学习当三件事为真时有意义的:
训练的一组任务,可以共用低层次特征。对于无人驾驶的例子,同时识别交通灯、汽车和行人是有道理的,这些物体有相似的特征
如果每个任务的数据量很接近,这个准则没那么绝对,不一定对
想要从多任务学习得到很大性能提升,其他任务加起来必须要有比单个任务大得多的数据量
多任务学习会降低性能的唯一情况是神经网络还不够大。但如果可以训练一个足够大的神经网络,多任务学习肯定不会或者很少会降低性能
2.9 什么是端到端的深度学习?(What is end-to-end deep learning?)
以前有一些数据处理系统或者学习系统需要多个阶段的处理。端到端深度学习就是忽略所有这些不同的阶段,用单个神经网络代替它
语音识别
目标是输入,比如说一段音频,然后把它映射到一个输出,就是这段音频的听写文本:
传统上语音识别需要很多阶段的处理。首先提取一些特征,一些手工设计的音频特征,比如MFCC,这种算法是用来从音频中提取一组特定的人工设计的特征。在提取出一些低层次特征之后,应用机器学习算法在音频片段中找到音位(声音的基本单位),比如“Cat”这个词是三个音节构成的,Cu-、Ah-和Tu-,算法把这三个音位提取出来,然后将音位串在一起构成独立的词,然后将词串起来构成音频片段的听写文本
端到端深度学习是训练一个巨大的神经网络,输入一段音频,输出直接是听写文本。只需要把训练集拿过来,直接学到了和之间的函数映射,绕过了其中很多步骤
端到端深度学习的挑战之一是需要大量数据才能让系统表现良好,比如只有3000小时数据去训练语音识别系统,那传统的流水线效果很好。但当有非常大的数据集时,比如10,000小时数据或者100,000小时数据,端到端方法突然开始很厉害。所以当数据集较小时,传统流水线方法效果更好。如果数据量适中,也可以用中间件方法,如输入还是音频,然后绕过特征提取,直接尝试从神经网络输出音位
门禁识别系统
最好的方法是一个多步方法,首先运行一个软件来检测人脸,然后放大图像并裁剪图像,使人脸居中显示,然后红线框起来的照片再喂到神经网络里,让网络去学习,或估计那人的身份
比起一步到位,一步学习,把这个问题分解成两个更简单的步骤更好:
首先弄清楚脸在哪里
第二步是看着脸,弄清楚这是谁
这种方法让两个学习算法分别解决两个更简单的任务,并在整体上得到更好的表现
训练第二步的方式:输入两张图片,网络将两张图比较一下,判断是否是同一个人。比如记录了10,000个员工ID,可以把红色框起来的图像快速比较,看看红线内的照片是不是那10000个员工之一,判断是否应该允许其进入
为什么两步法更好:
解决的两个问题,每个问题实际上要简单得多
两个子任务的训练数据都很多
机器翻译
传统上机器翻译系统也有一个很复杂的流水线,比如英语机翻得到文本,然后做文本分析,基本上要从文本中提取一些特征之类的,经过很多步骤,最后会将英文文本翻译成法文。因为对于机器翻译来说有很多(英文,法文)的数据对,端到端深度学习在机器翻译领域非常好用
2.10 是否要使用端到端的深度学习?(Whether to use end-to-end learning?)
端到端学习的优点
端到端学习只是让数据说话。如果有足够多的数据,不管从到最适合的函数映射是什么,如果训练一个足够大的神经网络,希望这个神经网络能自己搞清楚。使用纯机器学习方法,直接从到输入去训练神经网络,可能更能够捕获数据中的任何统计信息,而不是被迫引入人类的成见。例如在语音识别领域,早期的识别系统有这个音位概念,如果让学习算法学习它想学习的任意表示方式,而不是强迫使用音位作为表示方式,其整体表现可能会更好
所需手工设计的组件更少,能够简化设计工作流程,不需要花太多时间去手工设计功能,手工设计中间表示方式
端到端学习的缺点
直接学到到的映射,需要大量数据
排除了可能有用的手工设计组件。当有大量数据时,手工设计不太重要,当没有太多的数据时,构造一个精心设计的系统,可以将人类对这个问题的很多认识直接注入到问题里,对算法很有帮助
端到端深度学习的弊端之一是它把可能有用的人工设计的组件排除在外,精心设计的人工组件可能非常有用,但也可能真的影响算法表现。例如,强制算法以音位为单位思考,也许让算法自己找到更好的表示方法更好。但往往好处更多,手工设计的组件往往在训练集更小的时候帮助更大
决定是否使用端到端深度学习,关键的问题是是否有足够的数据能够直接学到从映射到足够复杂的函数。识别图中骨头位置是相对简单的问题,系统不需要那么多数据。但把手的X射线照片直接映射到孩子的年龄,直接去找这种函数,就是更为复杂的问题。如果用纯端到端方法,需要很多数据去学习
Last updated