前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一文看懂如何搭建AI应用:10周学会深度学习,还赢下5千美元

一文看懂如何搭建AI应用:10周学会深度学习,还赢下5千美元

作者头像
量子位
发布2018-01-30 15:57:36
8260
发布2018-01-30 15:57:36
举报
文章被收录于专栏:量子位量子位

春节后第一个休息日,量子位给大家准备了一个不一样的故事。

在这个故事里,主人公David Brailovsky(就叫阿D吧)参加了一场计算机视觉比赛。这个挑战赛要求基于卷积神经网络(CNN),做出一个识别红绿灯的人工智能应用模型。

于是阿D花了10周的时间,从0开始,一点一滴摸索着,搭建、调试、训练和一个深度学习系统。而且还在最后的比赛中一举夺魁,赢了5000美元。

主人公把这个有点逆袭的过程,原原本本的写了下来。量子位也希望对人工智能感兴趣的朋友仔细看一看。不用担心,并不是AI专家才能理解这篇文章。因为全文重点在与搭建一个人工智能应用模型的思路和方法,而不是拘泥于技术实现。

从实践应用的角度出发,搭建一个AI模型,并不是从0开始写代码的过程。

最初,是选择一些功能近似的既有模型,然后进行微调,从而把既有模型的能力,从原来的任务“迁移”到新任务上。然后使用数据进行训练,训练过程中尝试不同的调整,以观察哪些调整可以起效,哪些调整没有效果。

这个过程中重要的一步,是把几个较低精度的模型组合在一起,反而得到了较高精度的输出结果。随后,测试并且获得较好的效果。

如前所述,下文没有过于晦涩的技术内容,量子位选择推荐这篇,是因为有助于理解如何在实践中利用人工智能解决问题。

那么,我们就跟着阿D的讲述就开始吧。

△ 一个基于深度学习的交通灯识别分类器Demo 左上角是根据图片给出的判断
△ 一个基于深度学习的交通灯识别分类器Demo 左上角是根据图片给出的判断

挑战

我最近在一个交通灯识别挑战赛中赢得了第一名,这是由一家公司组织的计算机视觉竞赛。挑战的目标是识别行车载摄像头拍下的图像中,交通灯的状态。

在任何给定的图像中,要做出这样一个人工智能应用模型(分类器):可以输出场景中是否有交通灯,以及它是红色还是绿色。 且应该仅识别行驶方向上的交通灯。

上面的三张图像,就是需要预测的三类可能的情况:没有交通灯,红色或绿色交通灯。

挑战要求解决方案基于卷积神经网络,这是一种在使用深度神经网络进行图像识别领域非常流行的方法。 参赛的算法模型,会被依照准确性以及模型的大小两个维度进行评分。 较小的模型得分更高。 此外,获胜所需的最低准确度为95%。

主办方提供了18659个经过标记的图像作为训练数据。每个图像都标记为上面提到的三个类别之一。

软件和硬件

我用Caffe深度学习框架(可以理解为一组工具包)来训练模型。主要原因是Caffe里有各种各样的预训练模型。

在分析结果、数据探索和特殊脚本的工作中,我使用了Python,NumPy以及Jupyter Notebook。

我还用了亚马逊的GPU实例(g2.2xlarge)用于训练模型。最后的费用是263美元之巨。用来训练和运行模型的代码和文件在GitHub上。

最终分类器

最终的分类器在主办方的测试集上,实现了94.955%的精度,模型大小为7.84 MB。作为比较,GoogLeNet的模型大小为41MB,VGG-16的模型大小528MB。

主办方大发慈悲同意把94.955%当作95%看待,让我通过最低要求。

追求更高精度的过程中,伴随大量的试验和错误。 其中一些我知道背后的逻辑,有些只是“碰碰运气”。我将讲述一些在模型中试图改进的事情,有的搞定了有的没搞定。

搞定的部分

迁移学习

我从尝试微调一个模型起步,这是一个在ImageNet图像数据库上用GoogLeNet架构预训练的模型。很快,这就让我得到> 90%的准确性!

不过,主办方在挑战的官方页面中提到,通过微调GoogLeNet模型应该可以达到93%的精度。我也不知道我哪里出了问题。

SqueezeNet

SqueezeNet:具有AlexNet(图像分类模型)级精度,但参数少50倍,模型尺寸小于0.5MB。

由于竞争奖励使用小模型的解决方案,早期我决定寻找一个紧凑的网络模型,尽可能少的参数,仍然可以产生良好的效果。 但大多数最近发布的网络非常深,有很多参数。

SqueezeNet似乎是一个非常好的选择,它也有一个在ImageNet上训练好的预训练模型,可用在Caffe的Model Zoo(类似手机上的应用商店)中方便取用。

△ SqueezeNet网络架构
△ SqueezeNet网络架构

网络通过以下方式保持紧凑:

  • 主要使用1x1卷积过滤,辅助一些3x3
  • 减少3x3过滤的输入通道数

有关更多详细信息,我建议阅读Lab41的博客。

在一些来回调整学习率后,我能够微调预训练模型以及从零开始训练,并且准确度能够达到很好的92%!很酷!

旋转图像

大多数图像是水平横置的,如上所示,但约2.4%是垂直的,另外还有好多种不同的方向。如下所示。

虽然这些在数据集中占比不大,但我们仍希望自己的模型也能对他们进行正确分类。

不幸的是,在jpeg图像中没有指定方向的EXIF数据。起初,我考虑做一些启发式算法来识别天空和相应地翻转图像,但这似乎没那么简单。

然后我改让图像按照固定角度旋转。最开始我尝试训练网络随机以0°,90°,180°,270°进行旋转。这没什么改善。但是,当我对每个图像进行四次旋转而得的预测取平均值时,改善出现了!

92% → 92.6%。

澄清一下:上面提到的“预测取平均值”,我的意思是平均了每个类在4个图像变化中产生的模型的概率。

过采样修剪

在训练期间,SqueezeNet网络默认首先在输入图像上执行随机修剪,我没有对这个进行改动。 这种类型的数据增加使网络更好地泛化。

类似地,当生成预测时,我对输入图像进行了一些修剪以及平均结果。 我使用5个修剪:4个角和一个中心。 有现成的免费Caffe代码来完成这个任务。

92% → 92.46%

旋转图像与过采样修剪带来了非常轻微的改进。

以较低的学习率进行附加训练

所有模型在一定点后开始过拟合。我注意到这点,是看到验证集损失开始在某一点上升。

40000迭代之后验证集损失开始上升

我在那个点停止了训练,因为模型可能不再泛化了。这意味着学习率没有时间衰减到零。 我试图恢复训练过程,在模型开始过拟合时,把学习率调低10倍。 这大概提高了0-0.5%的精度。

更多的训练数据

起初,我将数据分成3组:训练集(64%),验证集(16%)和测试集(20%)。几天后,我认为放弃36%的数据可能太多了。我合并了训练和验证集,并使用测试集来检查我的结果。

我重新训练了一个模型,加入“图像旋转”和“低速率附加训练”,并得到了如下提升:

92.6% → 93.5%

在训练数据中重新标签错误

当分析分类器对验证集的错误时,我注意到一些错误的置信度非常高。 换句话说,模型确定它是一件事(例如绿灯),而训练数据说明是相反的情况(例如红灯)。

注意,在上面的图中,最右边的栏是相当高的。 这意味着有大量的错误有着> 95%的置信度。 当仔细检查这些情况时,我发现这些通常错误是源自训练集的地面实况(ground-truth),而不是训练好的模型。

我决定在训练集中修复这些错误。 应该是这些错误混淆了模型,使其更难以进行归纳。 即使最终测试集在地面实况中有错误,一个更泛化的模型在所有图像中,更有可能达到更高的精度。

我手动标记了709张图像,当时我的一个模型产生了错误。 这改变了709张图像中337张的地面实况。 这个手工活耗时一小时,我还用了python脚本来提升效率。

以上是重新标记和重新训练模型后的结果。看起来好多了!

这对模型的提升度为:

93.5% → 94.1%

组合模型

使用几个模型在一起并平均其结果也提高了精度。 我在训练过程中对参与整体的模型进行了不同类型的修改。 使用从头开始训练的模型(即使自身准确度较低),结合精细调教过的预处理模型,我们获得了显著改进的结果。可能这种方式学习到了更多的特征。

最后我们组合了3个模型,精度为94.1%,94.2%和92.9%,合在一起精度为94.8%。

没搞定的部分

没搞定的太多了!希望其中的一些想法在别处有用。

与过拟合战斗

当试图处理过度拟合时,我尝试了几个事情,没有一个产生显着的改进:

  • 增加网络中的丢失率
  • 更多数据增强(随机移位,缩放,倾斜)
  • 分配更多的训练数据:使用90/10分隔而不是80/20

平衡数据集

数据集不是非常平衡:

  • 19%的图像标有没有交通灯
  • 53%的是红灯
  • 28%的是绿灯

我试图使用过采样较不常见的类来平衡数据集,但没有发现任何改进。

区分昼夜

我的直觉是,识别交通灯在白天和夜间是非常不同的。我想也许我可以帮助这个模型,把它分成两个更简单的问题。

通过观察它们的平均像素强度,将图像分为白天和黑夜是相当容易的:

你可以看到一个非常自然的图像分离,低平均值即暗图像,在夜间拍摄,明亮的图像,在白天拍摄。

我试过两种方法,都没有改善结果:

  • 为白天图像和夜间图像训练两个单独的模型
  • 训练网络预测6种分类而不是3种,方法也是预测是白天还是晚上

使用SqueezeNet的更好的变体

我用两个改进的SqueezeNet变体进行了一点尝试。第一次使用残留连接和第二次训练与密集→稀疏→密集训练。没什么用。

交通灯定位

在阅读deepsense.io的一篇关于他们如何赢得鲸鱼识别挑战的文章后,我试图训练一个定位器,即首先识别交通灯在图像中的位置,然后在一个小区域识别交通灯状态。

我花费数小时用sloth来注释约2000张图片。当试图训练一个模型,它过拟合得非常快,可能是因为没有足够的标签数据。 也许这个方法可行,如果我能标注更多的图像。

在困难案例上训练分类器

通过挑选分类器置信度小于97%的数据,我跳出30%“难度更高”的图片。然后我试图只用这些图片训练分类器。没什么改善。

不同的优化算法

我短暂的使用Caffe的Adam结算期,取代线性降低学习率的SGD,但是没有看到任何改进。

向组合中添加更多模型

由于组合的方法证明有效,我曾尝试把规模扩大一倍。我试着改变不同的参数来产生不同的模型,并将它们添加到组合中:初始种子,dropout rate,不同的训练数据(分组方法不同),训练中不同的检查点。这些都没有带来显著的改善。

最终分类器细节

我的分类器,最后由三个单独训练的网络组合而成。它们给每个类的概率,进行加权后的平均值作为输出。所有这三个网络都基于SqueezeNet,但各自经过了不同的训练。

一号模型 - 以过采样进行预训练的网络

训练基于重新打标签的训练集(修复地面实况错误之后)。这个微调过的模型,基于ImageNet上一个预训练的SqueezeNet模型。

训练期间的数据增强:

  • 随机水平镜像
  • 送入网络之前随机裁剪227×227大小的补丁

测试时,对每个图像进行10各不同的变体预测,然后取计算平均值作为最终预测。这10种不同的变体预测是:

  • 5次227×227大小的裁剪:四个角各一次,图片中央一次
  • 对每一个裁剪,都生成一个水平镜像

验证集的模型精度:94.21%

模型大小:~2.6 MB

二号模型 - 增加旋转不变性

和一号模型非常类似,只不过增加的是图像旋转。在训练时间期间,图像随机旋转90°,180°,270°或根本不旋转。 在测试时,一号模型中描述的10个变体中的每一个通过旋转90°,180°和270°而产生三个变体。 共有40个变量被我们的模型分类和平均在一起。

验证集的模型精度:94.1%

模型大小:~2.6 MB

三号模型 - 从头开始训练

这个模型不是微调得来,而是从零开始训练。即便他的准确性低一些,但是从训练集上学到了不同的特性。用在一个组合里面时,这可能是有用的。

训练和测试期间的数据增强与一号模型相同:镜像和裁剪。

验证集的模型精度:92.92%

模型大小:~2.6 MB

把模型组合在一起

每个模型输出三个值,表示图像属于三个类中的每一个的概率。我们用以下权重平均它们的输出:

  • 一号模型:0.28
  • 二号模型:0.49
  • 三号模型:0.23

我通过对可能的值进行网格搜索并在验证集上测试来找到权重的值。它们对验证集,可能有点过度拟合,但也许不是太多,因为这是一个非常简单的操作。

验证集的模型精度:94.83%

模型大小:~7.84 MB

在Nexar测试集上的精度:94.955% [撒花]

模型错误示例

棕榈树上因为眩光产生的绿点,让模型错误的判断这是一个绿灯信号。

模型把直行的红灯判断成绿灯。这种路口不止一个交通灯的情况有点棘手。

图中右侧有一个亮起绿灯的信号灯,但是模型认为没有交通信号灯。

结语

这是我第一次在一个实际案例中应用深度学习!效果这么好让我很高兴。在这个过程中我学到了很多很多。以后有机会再跟大家交流更多。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-02-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 量子位 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 挑战
  • 软件和硬件
  • 最终分类器
  • 搞定的部分
    • 迁移学习
      • SqueezeNet
        • 旋转图像
          • 过采样修剪
            • 以较低的学习率进行附加训练
              • 更多的训练数据
                • 在训练数据中重新标签错误
                  • 组合模型
                  • 没搞定的部分
                    • 与过拟合战斗
                      • 平衡数据集
                        • 区分昼夜
                          • 使用SqueezeNet的更好的变体
                            • 交通灯定位
                              • 在困难案例上训练分类器
                                • 不同的优化算法
                                  • 向组合中添加更多模型
                                  • 最终分类器细节
                                    • 一号模型 - 以过采样进行预训练的网络
                                      • 二号模型 - 增加旋转不变性
                                        • 三号模型 - 从头开始训练
                                          • 把模型组合在一起
                                            • 模型错误示例
                                            • 结语
                                            相关产品与服务
                                            图像处理
                                            图像处理基于腾讯云深度学习等人工智能技术,提供综合性的图像优化处理服务,包括图像质量评估、图像清晰度增强、图像智能裁剪等。
                                            领券
                                            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档