用深度学习识别交通信号

推荐会员: zhouyf 所属分类: 技术教程,行业精选 发布时间: 2017-02-07 11:06

挑战:

首先,我的目标是要司机用 Nexar 应用识别不同图片中的交通灯信号状态。在一个给定的图片中,分类处理系统应该能识别图片中有没有交通灯,以及交通灯是红色还是绿色。更重要的是,它应该在行车方向辨认交通灯。

以上三张图片是我应该需要预判的三种情况:没有交通灯(左),红灯(中),绿灯(右)

这里需要的挑战在于,解决方案需要基于卷积神经网络,一种用深度神经网络进行图像识别的流行方法。 最终的评分体系基于模型的精确度和模型大小(MB )。越小的模型可获得越高的评分,另外,模型最低精确度需要达到 95%。

Nexar 提供了 18,659 张标记过的图片作为训练数据,每张图片都标记成以上三种类型中的一种(无灯、红灯、绿灯)。

软件和硬件

我用的是 Caffe 来训练这些模型。之所以选择它是因为 Caffe 用了大量多样的预训练模型

Python,NumPy & Jupyter 笔记本都被用来进行结果分析,数据探索和做专门的脚本。

训练模型用的是亚马逊 GPU 实例((g2.2xlarge)。这个不便宜。

我用来训练和跑模型的代码、文件放在 GitHub 供大家参考。

最终的分类识别系统

最终我的识别系统用 Nexar 网站监测出来准确性达到了 94.955%,模型大小~7.84 MB。为了给大家一个概念,GoogLeNet 的模型大小是 41MB,VGG-16 模型大小是 528 MB。

Nexar 很宽容地将我的 94.955% 作为达到了 95% 的最低要求。

让模型达到更高的精确度花费了大量的精力。有些方案是有其背后的逻辑的,有些则只是「也许这个会有用吧 」。接下来我会讲讲我做的这些成功 & 不成功的各种尝试。模型细节会在这之后讲解。

有用的方案:

迁移学习

我先是尝试了微调一个在 imageNet (用的是 GoogLeNet 的结构)上进行过预训练的模型。这迅速让我的模型达到了 > 90% 的精确度。

Nexar 在它的挑战页面提到了如果用 GoogLeNet 进行微调,应该可以使精确度达到 93% 以上。不知道我是哪里出了问题,我会再看看的。

SqueezeNet

SqueezeNet: AlexNet-level accuracy with 50x fewer parameters and <0.5MB model size.

因为这个比赛会奖励使用小模型的方案,我一开始就打算利用紧凑型网络,用尽可能少的参数产生出最好的结果。目前大部分公布的网络都是深度且有很多参数的。SqueezeNet 看起来挺合适,同时它也拥有在 Caffe 的模型园区里面基于 ImageNet 预训练的模型,非常方便。

这个网络能保持紧凑的原因在于

  • 主要用 1×1的滤镜,偶尔用 3×3 的
  • 输入渠道的数量减少到 3×3

想了解更多细节,建议阅读这篇博客,或直接看原始论文。

经过一系列的挫折和成就之后,我终于成功地把模型的准确性从零开始训练到了 92%,给自己点个赞。

旋转图片

大部分的图片跟上图一样是横着的,但也有约 2.4% 是竖直的,而且每个方向都不一样。如下图

尽管这并不是数据套的主要部分,但我们还是希望模型可以尽可能地把这个分类修正。

不幸的是,JPEG 图片并没有 EXIF 数据* 来标注方向。一开始我想用启发式算法来自动识别天空从而辨认图片方向,然而发现这还是不够直接。

于是,我就试着设定了图片旋转的不变量,我本来是打算让图片做随机的 0°, 90°, 180°, 270° 旋转,然而没有效果。但是在我把每张图的四种旋转角度的预测进行平均之后,效果就好多啦。

92% → 92.6% 的增长。

说得更清楚一点:「对预测进行平均」是指,对模型产生的、基于每种类型的图片的四个变量的预测进行平均计算。(后面会有权重细节)

过采样裁剪 (Oversampling crops

在训练 SqueezeNet 网络的过程中,起初产生了一些对输入图片的随机默认裁剪,我并没有对此插手。这种数据增量让网络更加一般化了。

同样的,为了生成预测,我对输入图片的集中裁剪进行了平均。我用了五个变量:四个边角的裁剪和中央区的裁剪。利用 Caffe 的已有代码,可以免费植入这一功能。

92% → 92.46%

图片旋转和裁剪一起产生的精确度提升微乎其微。

更低学习速率的附加训练

所有的模型到了某个点都会变得过度拟合。我开始注意到这点的时候,验证套已经开始大量丢失了。

在这个点,我中止了对模型的训练,因为这个时候的网络应该已经不是一般化的了。这也就意味着学习比率无论如何也无法衰退到 0 了。在这个点,模型的学习比率成为了原始比率的 1/10,已经开始过度拟合了,所以我尝试着对这个训练过程进行一个总结。这通常会把精确度提高 0-0.5%。

更多的训练数据

一开始,我把训练数据分成了三个部分:训练 (64%), 验证 (16%) 和测试 (20%)。但几天之后,我感觉放弃36% 的数据实在太多了,所以我把训练套和验证套融合在了一起,只用测试数据套来进行结果检查。

我重新训练出了一个新的基于「图像旋转」和「更低速率的附加训练」的模型:

92.6% → 93.5%

给训练数据中的错误重贴标签

在分析识别系统对验证套找出的错误的时候,我发现有些错误具有非常高的自信。也就是说,模型非常确定这是一个东西(比如绿灯),而训练数据却非常肯定地说是另一个(比如红灯)。

注意上图最右边的柱形条,非常之高。这说明有很大一部分数据的错误自信率大于 95% 。在仔细研究了这些情况之后我发现,这些一般都是训练套中、而非训练模型中的的参考标准(ground-truth)错误。

我决定在训练套中修正这些错误。因为基本的想法是,这些错误迷惑了模型,所以让模型更难进行一般化。然而即使最终的训练套在参考标准上犯了错,一个更加一般化的模型也更可能拥有更高的图片精确度。

我手动标注了出错的模型之一中的 709 张图片。 这就修改了 709 张图片中337 张的参考标准。我用了 Python 脚本来提高我的效率。

上图是经过重新标记和重新训练后的同一张图。看起来好多了!

现在的精确度

93.5% → 94.1% ✌️

所有的模型一起

把所有在不同训练过程中参与的模型汇集到一起也提高了模型的精确度。其中有一个最显著的提升来自于一个从零开始训练的模型。其实这个模型独立的精确度很低,但和其他放在一起反而比那些精心微调过的模型效果更好。这可能是因为这个精确度低的模型比其他精心调整过的模型更能适应学会各种不同模型的特点。

总共汇集了三个模型,精确度分别是 94.1%, 94.2% 和 92.9% ,放在一起精确度达到了 94.8%.

哪些尝试没有成功?

太多了!把这些经验分享给你们,希望在别的地方能派上用场。

紧凑过度拟合

  • 增加网络中的 dropout* 比例
  • 更多的数据增量 (随机移位, zooms, 偏度)
  • 训练更多的数据: 用 90/10 的分割代替 80/20

平衡数据套

数据套并不是很平衡

  • 19% 的图片被标注为无交通灯
  • 53% 的红灯
  • 28% 的绿灯

我对不太寻常的分类进行过采样,但没看见任何效果

分离白天 & 黑夜

通过分析图片的像素密度很容易就能识别白天黑夜

可以从图中看到,平均值低的图片(也就是黑夜)和平均值高的图片(也就是白天)之间有一条自然的分界线。

我用了以下两种方法

  • 对白天黑夜用两种模型分开训练
  • 增加白天黑夜把图片种类变成六种来训练模型

然而并没有什么用。

用更好的 SqueezeNet 变量

开始用的 residual connections 后来用 强——分散——强 模式训练。 没用

对交通灯定位

sloth 标注了2,000 张图片。但训练模型的时候,它很快就开始过度拟合了。也许是因为标注图片不够多的缘故。

训练识别系统进行更难的辨认

我选了 30% 「更难」的图片,训练模型对这些图片的自信率低于 97%。我训练他们只辨认这些图片。没什么改进。

不同的优化算法

我试着用 Caffe’s Adam solver 代替线性增加学习速率的SGD,没用。

增加更多的模型

由于汇集所有模型被证实有用,我又增加了一倍的不同模型,用了很多不同的参数;但没看到显著效果。

最终的识别系统细节

识别系统用了三种独立训练的网络,把这些网络对每一类图片给出的可能性的加权平均作为输出。 这三种网络都用了 SqueezeNet 网络,都进行了不同训练。

一号模型——过采样的预训练网络

在预标记训练套上进行训练(已修改参考标准之后). 该模型在基于 ImageNet 的 SqueezeNet 的预训练模型上进行了微调。
训练过程中的数据增量:

  • 随机水平镜像
  • 在投给训练网络之前随机裁剪补丁到 227 x 227

在测试时,图片的十种变量预测进行了平均来计算最终预测。十个变量包括:

  • 五个裁剪为大小 227 x 227的 : 四个边角各一个,图片中央一个
  • 每个裁剪的版本都有一个水平镜像

基于验证套的模型精确度: 94.21%
模型大小: ~2.6 MB

二号模型— 增加旋转不变量

跟一号模型相似,需要平均四个角度的不变量,90°, 180° ,270°和不旋转。在测试的时候,一号模型的十种变量给出了四种旋转角度,总共产生 40 个变量。

基于验证套的模型精确度: 94.1%
模型大小: ~2.6 MB

三号模型——从零开始训练

这个模型没有进行精确微调,精确度低。但放在一起可以学习其他模型的特点。

数据增量跟前两个一样:镜像和裁剪。

基于验证套的模型精确度: 92.92%
模型大小: ~2.6 MB

所有模型一起

每种模型都会产出三个结果,代表它们对图片属于哪种类型的判断。我们把这个结果按以下权重进行平均:

  • Model #1: 0.28
  • Model #2: 0.49
  • Model #3: 0.23

每种模型的权重是通过格点搜索法做出来的。可能会有过度拟合的情况,但因为这个操作比较简单,所以也还好。

基于验证套的模型精确度: 94.83%

模型大小: ~7.84 MB

Nexar 测试出来的模型精确度: 94.955%

模型错误样例

棕榈树上绿色炫光会被模型错误当成是绿灯
模型把红灯认成了绿灯。当图片中有不止一个交通灯的时候,情况就比较棘手。
有绿灯的时候,模型以为没有灯。

感谢阅读。

Nexar 交通灯识别挑战赛*:由在开发 AI 训练营应用的公司举办的电脑视觉比赛

EXIF 数据*:可交换图像文件格式常被简称为Exif(Exchangeable image file format),是专门为数码相机的照片设定的,可以记录数码照片的属性信息和拍摄数据

* dropout: 指在模型训练时随机让网络某些隐含层节点的权重不工作,不工作的那些节点可以暂时认为不是网络结构的一部分,但是它的权重得保留下来(只是暂时不更新而已),因为下次样本输入时它可能又得工作了

原文:Recognizing Traffic Lights With Deep Learning
参考:Deep learning:四十一(Dropout简单理解)

来源:https://zhuanlan.zhihu.com/p/24955921

关键词:

版权声明:本站原创和会员推荐转载文章,仅供学习交流使用,不会用于任何商业用途,转载本站文章请注明来源、原文链接和作者,否则产生的任何版权纠纷与本站无关,如果有文章侵犯到原作者的权益,请您与我们联系删除或者进行授权,联系邮箱:service@datagold.com.cn。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据