查看原文
其他

大牛秘笈!谷歌工程师是如何改进训练数据集的?

Pete Warden AI前线 2019-03-29

   
策划编辑 | Natalie
译者 | 核子可乐,王强
编辑 | Debra
AI 前线导读:近日,特斯拉 AI 总监 Andrej Karpathy 在某次会议上祭出了一张图,展示了工业界和学术界在数据和模型上的时间花费对比。从这张图中,我们可以看到业界在处理数据集上所花费的时间比学术研究多得多,几乎占据了 3/4 的时间。前几日,谷歌 TensorFlow 团队研究深度学习的工程师 Pete Warden 进一步撰文解释了为什么我们需要改进训练数据,并提供了一系列改进训练数据的实用技巧,AI 前线对这篇文章进行了编译。

更多干货内容请关注微信公众号“AI 前线”(ID:ai-front)


工业届和学术界在数据和模型上的时间花费对比

Andrej Karpathy  Train AI 演讲当中展示的这张幻灯片,可谓深得我心!它完美地体现了深度学习研究与实际生产之间的差异。学术论文几乎全部集中在新的改进模型身上,而数据集则通常选自一小部分公开归档。但在另一方面,我接触过的每一位实际用户都在努力将深度学习纳入实际应用程序当中,并把大部分时间投入到处理训练数据身上。

研究人员为什么如此关注模型架构?能够解释这个问题的理由多种多样,但其中最重要的一点在于,目前可用于帮助使用者在生产环境中部署机器学习技术的资源确实非常有限。为了解决这一切,我希望强调“训练数据在有效性方面的不合理”问题。在今天的文章中,我将进一步阐述这个观点,包括解释数据为何如此重要以及对其加以改进的相关实用技巧。

作为日常工作中的重要组成部分,我与很多研究人员及产品团队保持着密切合作,而且我个人也坚信实现数据改进的力量源自用户在成功实现模型构建时所获得的巨大收益。在大多数应用程序当中,深度学习技术的最大使用障碍在于如何立足现实场景获得足够高的准确率——在这方面,改进训练数据集是我所知晓的,最快的准确率提升途径。即使受到其它限制性条件的约束(例如延迟水平或存储容量大小),你仍然能够在较小的架构当中通过性能取舍确保特定模型迎来准确率增强。

一个语音识别的例子

受到篇幅所限,这里我无法一一尽数自己在生产系统观察当中看到的结论。但我们可以从开源示例出发,聊聊与之类似的生产模式。去年,我曾为 TensorFlow 创建一个简单的语音识别示例。事实证明,当时我并没有现成的数据集可以拿来即用于模型训练。在众多志愿者的慷慨帮助之下,我收集了 6 万条长度为 1 秒的短语语音音频片段——这里再次感谢 AIY 团队帮助我发起的 Open Speech Recording 站点。利用这些数据,我构建了一套模型。遗憾的是,这个模型虽然具备一定功能,但准确率却无法达到我的预期。为了了解自己身为模型设计师到底存在哪些局限,我开始利用相同的数据集参加 Kaggle 竞赛。竞争对手们的表现比我这套简单的模型要好得多,而且在众多不同方法当中,有数个团队将准确度提升到了 91% 以上。对我而言,这意味着数据本身存在着根本性的错误。实际上,竞争对手们确实发现了其中的不少错误,例如不正确的标签或者被截断的音频等等。这为我提供了动力,促使我专注于通过发布新的数据集与更多样本以解决他们面临的各类实际问题。

我观察了错误指标,希望了解模型最常遇到的问题,结果发现“其它”类别(即语音已经被识别完成,但相关词汇并不存在于模型的有限词汇范围之内)出现频率最高。为了解决这个难题,我增加了所捕捉词汇的数量,旨在提供更多可用训练数据。

由于 Kaggle 参赛者们上报了标签错误,我还挤出了额外的时间进行标签验证,包括邀请志愿者聆听每段音频以确保其与标签相符。此外,Kaggle 参赛者们还发现了一些几乎无声或者被截断的文件,因此我编写了一款实用工具以实现简单的音频分析,同时自动清除质量特别差的样本。最后,在更多志愿者与付费采集人群的共同支持之下,尽管删除了不少错误文件,我的这套数据集仍然顺利扩展至拥有超过 10 万条音频。

为了帮助其他用户使用这套数据集(并从我的错误当中吸取教训),我将所有相关内容编撰为一篇 Arxiv 论文,并对准确率结果加以更新。其中最重要的结论是,在不改变模型或测试数据的前提下,最高准确率提升了 4% 以上——由 85.4% 增长至 89.7%。这无疑是一种显著改进,人们在 Android 或 Raspberry Pi 上的演示应用程序中使用此模型时,反馈的满意度也确实更高。在我看来,相较于投入更多时间进行模型调整,提升数据集质量带来的效果改善无疑更为明显。

我在实际生产过程当中,见到过人们不断调整自己的生产设置以逐步提升成果水准。但如果大家也希望采取类似的方式,往往很难找到确切的实施途径。大家当然可以从之前提到的语音数据使用技术中得到一些启发,但要更明确地阐述这个议题,我们无疑应当进入下一阶段——实用方法。

首先,审视你的数据

这看似是句废话,但大家的第一步应该是以随机方式浏览自己的训练数据。将一部分文件复制到本地计算机当中,并花上几个小时查看其内容。如果你打算处理图片,请使用 MacOS 的 finder 滚动浏览各类缩略图,从而快速浏览数千幅图片。对于音频,你可以使用 finder 的播放预览功能,或者将随机片段以文本的形式显示在终端当中。我当初就没能投入足够的时间对语音数据集进行预览,因此 Kaggle 参赛者们才在处理数据时发现大量问题。

我确实觉得这个过程很愚蠢,但我倒不会为此而后悔。毕竟在完成工作时,我总会发现一些对于数据而言非常重要的结论——包括不同类别示例数量不平衡、数据损坏(被标记为 JPG 扩展名的 PNG 文件)、错误标签甚至是令人惊讶的关联组合。Tom White 在对 ImageNet 进行检测时就获得了一些惊人的发现,他意识到其中的“太阳镜”标签指的其实是“聚光镜”——一种用于汇聚阳光的古老装置 ; “垃圾车”代表着主页图片 ; 而“斗篷”则对应着女性不死族形象。Andrej 以手动方式对 ImageNet 中的图片进行了分类,这同样给我带来非常重要的启示,包括如何分辨不同类型的犬只——即使对人来讲,这仍然不是件容易的事。


你要采取的具体行动,取决于你究竟发现了什么 ; 但作为数据清理工作的第一步,你应该首先完成上述检查,这种直观了解当前数据集中内容的方法有助于我们对接下来的步骤作出正确判断。

快速选择模型

不要在选择模型方面投入太多时间。如果大家正在进行图像分类,请优先选择 AutoML;如果不然,则请优先选择 TensorFlow 的模型库或者 Fast.AI 的示例集合,它们都能提供切实解决你类似问题的模型。换言之,最重要的是尽快开始迭代,即尽早且频繁地由实际用户试用你的模型。你随时可以对模型加以改进,也能够因此获取更好的结果,但获取数据才是工作的第一步。深度学习仍然遵循着“垃圾进,垃圾出”的基本计算原则,因此即使是质量最高的模型,也将受到训练数据集质量的直接影响。通过选择模型并对其进行测试,你将能够理解这些缺陷的存在并加以改进。

为了加快迭代速度,你可以尝试首先使用已经通过现有大型数据集训练完成的模型,并利用迁移学习使用你收集到的(可能规模较小)一组数据对其进行微调。这通常能够带来超越小数据集直接训练的结果,而且执行速度更快,因此大家将能够快速了解如何调整数据收集策略。更重要的是,你可以将结果反馈纳入你的收集流程,从而在学习过程中对流程进行同步调整——而非在训练之前将收集作为孤立的事务处理。

行动之前先思考

对于面向研究与生产场景的模型构建工作,二者之间的本质区别在于研究通常会在起步时就对问题陈述作出明确定义 ; 但在另一方面,实际应用的需求则仅存在于用户的头脑当中,并随时间推移逐渐显现在开发者面前。举例来说,对于 Jetpac,我们希望能够在每座城市的自动旅行指南中尽量展示一些好照片。于是,我们开始要求评分者上传一些他们认为“好”的照片。然而,最终我们得到了很多面带笑容的人像照片,而这就是他们对于“好”的理解。我们将这些内容放入产品模型当中,并测试用户的反应如何——结果表明,他们没能留下任何深刻的印象,对此也没有什么共鸣。为了解决这个问题,我们将问题调整为“这张照片是否令人想要前往其中展示的地方?”这让我们的内容质量变得更好,但不同的群体对此的理解还是存在巨大差异。东南亚的工作人员们明显更喜爱一些会议类型的照片——人们身处大型酒店当中,穿着正装手持酒杯。这显然是一种可以理解的误解,而且美国的目标受众在看到这些图片后只会感到压抑且不想前往。最后,Jetpac 团队中的六位成员手动为超过 200 万张图片进行了评分,因为我们比任何人都更清楚其中的标准所在。

没错,这是个有点极端的例子,但却表明标记过程在很大程度上依赖于应用的具体需求。对于大多数生产用例而言,我们需要投入相当长的一段时间用于帮助模型找到正确问题的正确答案——这将直接决定模型解决问题的能力。如果我们使用模型来回答错误的问题,那么将永远无法在这样糟糕的基础之上建立可靠的用户体验。

我发现,保障问题正确性的惟一方法就是对应用程序进行模拟——而不可能单靠机器学习模型进行自我循环。有时候,我们会将这种方法称为“奥兹精灵”,因为幕后还存在着指导者。仍然以 Jetpac 为例,我们让人们为旅行指南手动选择照片(而非训练模型),并通过用户测试反馈来调整我们用于挑选图片的标准。一旦我们能够以可靠方式从测试当中获得正面反馈,即可将由此制定出的照片选择规则转换为标签脚本,进而处理数百万张来自训练集的图像。在此之后,这些素材又训练出能够预测数十亿张照片质量的模型——但归根结底,这套最终模型的 DNA 早在我们开发初始手动规则时就已经确立。

利用真实数据进行训练

在 Jetpac 当中,我们用于训练模型的图像与我们在模型中应用的图像拥有相同的来源(大部分来自 Facebook 与 Instagram),但我发现的一大常见问题在于,训练数据集在很大程度上与生产场景下的实际输入数据集存在差异。举例来说,我经常看到那些希望利用 ImageNet 图像进行模型训练的团队,最终发现自己的模型成果根本无法解决无人机或机器人在实际场景中遇到的问题。之所以发生这种情况,是因为 ImageNet 中大多是人类拍摄的照片,而这些照片往往具有很多共通特性。举例来说,人们使用手机或照相机进行拍摄、使用中景镜头、取景位置大致在头部高度、一般在白天或人为照明环境下拍摄,且指向的物体居中并位于前景之内。相比之下,机器人与无人机则使用视频摄像机进行取景,其通常采用高视野镜头,拍摄位置可能是地面或者空中,照明条件一般较差,无法智能地框选任何物体等等。这些差异意味着,如果只是利用来自 ImageNet 的图片对模型进行训练,再将成果部署到无人机或者机器人当中,那么其带来的分析准确率绝对不可能达到你的预期水平。

训练数据还可能在一些细微的方面与实际应用所看到的内容存在差异。比如说,你正在设计识别野生动物的相机,并使用世界各地的动物数据集进行训练;如果你只打算在婆罗洲的丛林使用相机,那么数据集中的企鹅类图片基本没机会和现实图像对应;那么如果训练数据中包括南极的照片,模型就可能将其他动物误认为企鹅。要想降低这类错误的几率,就要提前从数据集中删掉这类图片。

有许多方法可以根据已有的的先验标准(例如,在丛林环境中大幅降低企鹅出现的概率)来校准结果,但更方便有效的方法是使用反映产品实际遇到的情况的训练集。我发现最好的方法是始终使用从现实应用中直接捕获的数据,与我上面提到的“绿野仙踪”方法可以很好地匹配。应该让项目参与者为初始数据集设计标签,即使一开始的标签数量不多,它们也起码会反映现实状况,一般来说也足够进行初始实验的迁移学习了。

遵循指标

当我研究语音指令的案例时,我看的最多的报告就是训练中产生的混淆矩阵。它们在控制台中是这样显示的:


这可能看起来很吓人,但它实际上只是一个显示网络错误的详细信息的表格。下图则是标签化的版本,看起来更美观:



此表中的每一行代表一组实际真实标签都相同的样本,每列显示预测标签的编号。例如,高亮显示的行代表所有无声的音频样本,从左向右看,则可以看到预测的标签都是正确的,每个标签都落在无声这个预测列中。由此可知,该模型非常适合判断真正的无声状态,不会出现错误的反例。如果我们看整栏,显示有多少样本被预测为无声,可以发现一些实际上是语句的样本被误认为是无声的,并且误报很多。这些结果是很有用的,它们会让我仔细研究被误报为无声的样本,然后发现这些样本大都是音量很低的录音。于是我就可以排除掉音量较低的样本来提升数据质量,这都要归功于混淆矩阵提供的线索。

几乎所有的结果分析都可能是有用的,但是我发现混淆矩阵是一个很好的折衷方案,它提供的信息比单个精确的数字更多,但不会产生太多难以分析的细节内容。在训练过程中观察数字变化也很有用,从中可以得知模型正在学习哪些类别,并在清理、扩展数据集时告诉你该专注于哪个层面。

巧用聚类

用可视化聚类来观察网络如何分析训练数据是我最喜欢的方式之一。 TensorBoard 为这种分析方法提供了很好的支持;虽然可视化聚类经常用于查看单词嵌入,但我发现它几乎适用于任何嵌入式运作的层级。例如,图像分类网络通常在最后的完全连接或 softmax 单元之前有一个倒数第二层,可用作嵌入(像是 TensorFlow For Poets 这样的简单迁移学习案例就是这样工作的)。这些并不是严格的嵌入,因为在训练过程中没有流程来确保产生真正的嵌入层中可预期的理想空间属性,但对它们的向量进行聚类确实会产生有趣的结果。

一个实际案例中,与我合作的一个团队对图像分类模型中某些动物的高错误率感到困惑。他们使用聚类可视化来查看训练数据是如何分布到各种类别的。当看到“猎豹”时,他们清楚地看到数据被分成两个不同的组,组之间相距一定距离。


上图就是他们发现的情况示意。看到各个集群中的照片后就能一目了然:很多捷豹牌汽车被错误地标记为动物猎豹。于是,团队就可以检查标签注释流程,并意识到相关人员的工作方向和工作界面存在问题。有了这些信息,他们就能够改善标签标记人员的训练流程并修复相应的工具,从而将所有汽车图像从猎豹类别中剔除,使这一类别的精确度显著提升。

聚类可以让你深入了解训练集中的内容,从而提供与单纯查看数据类似的好处。但神经网络实际上是根据自己的学习理解将输入数据归类,以此来引导你探索分析。作为人类来说,我们非常善于用肉眼发现异常情况,所以我们的直觉和计算机处理大量输入的能力相结合,为发现数据集的质量问题提供了一个可扩展性良好的解决方案。这里塞不下使用 Tensorboard 完成此类任务的完整教程了(本文已经够长了,感谢坚持到现在的读者!),但如果你真心想要改善输出指标,我强烈建议你熟悉这个工具。

数据收集是持久战

我还没听说过收集更多数据却没有提升模型精度的情况,事实上有很多研究支持我的经验判断。



该图来自“重新审视数据的不合理有效性”,证明即使训练数据集的规模增长到数亿之巨,图像分类的模型精度仍然在随之提升。 Facebook 最近更进一步,使用几十亿张带标签的 Instagram 图像做训练,从而在 ImagNet 测试中创下了新的精度纪录。这表明,即使任务使用大型、高质量的数据集,增加训练集的大小仍可以提高模型精度。

这意味着,只要更高的模型精度可以改善用户体验,你就需要策略来持续扩充数据集。你可以尝试用创新手段来利用相对微弱的信号来获取更大的数据集,Facebook 使用 Instagram 标签就是一个很好的例子。另一种方法是提高标签流程的效率,例如用模型早期版本生成的预测标签进行辅助判断,以提升贴标人员的效率。这会带来先入为主印象的风险,但在实践中,收益往往超过这种风险。聘请更多人力来标记更多训练数据也往往是有意义的投资,虽说有些组织并没有为此类投入安排预算。对于非营利性组织而言,可以设法提供一些公开的工具,让支持者方便地自发贡献数据,这是低成本提升数据规模的一个很好的方法。

当然,所有组织的终极梦想都是获得一种在使用过程中自然生成更多标记数据的产品。我个人对这种想法没那么大兴趣,实际上它也不是万能的解决方案,因为现实有很多情况是人们就想尽快解决问题,不想费时费力去标记数据。对初创公司来说这是一个很好的投资热点,因为它就像是一个用于模型改进的永动机;但是在清理或聚合收集到的数据时总会产生一些单位成本,所以往往一个便宜的商业众包方案会比完全免费的方案更经济一些。向险峰一路前行

总有一些模型错误给用户带来的影响超过损失函数的计算结果。你应该提前考虑最糟糕的后果,并设计一个模型后盾来避免此类事故。后盾可以是一个黑名单,里面是预测错误代价太高的那些分类;或者是一套简单的算法规则集,以确保行动不会超过某些预设的边界参数。例如,你可以制作一个骂人词汇表,以防文本输出应用通过学习训练集中的数据产生这些词汇,因为这类输出对你的产品会有负面影响。

在事前预测所有的负面输出结果往往很困难,所以从现实世界中的错误中吸取教训非常重要。最简单的方法之一就是在产品刚进入市场时使用错误报告。人们使用你的应用,感到模型输出的结果不甚满意时,要让他们很容易向你反馈意见。可以的话获取模型的完整输入数据,但如果涉及敏感数据,只要知道低质量的输出是哪些就可以帮助你做调查。这些类别可以用来确定收集更多数据的位置,并定位用来研究现有标签质量的类。一旦对模型做了新的调整,跑正常数据集之外还要跑一遍之前产生低质量输出的数据集,并对后者的输出结果进行单独分析。这个流程有点像回归测试,并提供了一种方法来评估用户体验改善的程度,因为单个模型精度指标并不能完全覆盖人们所关心的所有层面。在检查以往产生强烈反响的一小部分案例时你就能获得一些独立的证据,证明你的确是在改善用户体验。如果输入模型的一些数据过于敏感,无法收集过来进行分析,就要使用 dogfood 测试或内部实验来确定手头的哪些数据可以产生这类错误结果,并在回归测试集中使用这些数据取代用户输入。

未来会更好吗?

我希望本文成功说服你花更多时间来研究数据,关于如何改善数据我也提供了一些建议。这个领域得到的关注是远远不够的,我为了找到一点帮助和建议都要大费周章。所以我感谢所有与我分享过自己的方法的从业者,并希望能从更多的人那里听取你们获得成功的方法。我认为会有越来越多的组织安排工程师团队专门用于数据集的改进,而不是让 ML 研究人员来推动进展。我希望能看到整个领域的发展。我时常惊叹于模型在质量非常糟糕的数据集训练后还能产生优质的输出结果,所以我迫不及待地想看看当数据集改进后,我们的模型能带来怎样的惊喜!

原文链接:

https://petewarden.com/2018/05/28/why-you-need-to-improve-your-training-data-and-how-to-do-it/

活动推荐

AI 风口已来,人工智能全面爆发,资本大量涌入,政策不断加持,各企业趋之若鹜。我们看到,AI 技术通过各种智能终端离我们越来越近了。在此时刻,中国完全掌握着弯道超车的良机。

GMTC2018 全球大前端技术大会上我们特设“终端 AI”专场,邀请国内外顶尖人工智能技术团队来分享他们是如何把 AI 技术赋能终端设备的。欢迎各位技术人莅临现场与大咖面对面交流。扫描下方二维码或点击“阅读原文”解锁更多大会详情!



AI前线紧跟前沿的AI技术社群

如果你希望看到更多类似优质报道,记得点个赞再走!

┏(^0^)┛明天见!

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存