专栏名称: 51CTO
51CTO官方公众号——聚焦最新最前沿最有料的IT技术资讯、IT行业精华内容、产品交流心得。本订阅号为大家提供各种技术干货,还会不定期的举办有奖活动,敬请关注。
目录
相关文章推荐
新浪科技  ·  【#DeepSeek崩溃次数变少了#?内部人 ... ·  6 小时前  
新浪科技  ·  【#小米15Ultra配色##小米15Ult ... ·  14 小时前  
亿欧网  ·  “乱拳”打死星巴克 ·  13 小时前  
新浪科技  ·  【#半导体板块拉升#】#寒武纪涨超7%# ... ·  3 天前  
51好读  ›  专栏  ›  51CTO

怎样用深度学习识别红绿灯--Nexar挑战赛冠军自述

51CTO  · 公众号  · 科技媒体  · 2017-03-07 11:43

正文


如若转载本文请在文章顶部标注“ 本文转载自51CTO(ID:weixin51cto),作者:51CTO


最近我参加了Nexar组织的交通信号灯识别挑战赛,花费了十个星期认真的学习了深度学习,最终幸运的获得了第一名,收获了5000美元的奖金。


在这篇文章中,我会把我的解决方案描述一下,分享代码,当然还有一些并不完善的地方,未来我会继续改进。


即使你不是人工智能专家也无需担心读不懂这篇文章,因为文章重点放在创作理念和实践方法上,而不是具体的技术实施。


红绿灯识别演示


我把代码放在了github上,地址是https://github.com/davidbrai/deep-learning-traffic-lights,目前我正在维护之中


挑战目标

挑战赛的目标是识别出司机们使用Nexar应用所拍摄出的图像中的交通信号灯。也就是说在任意一张给定的图像中,识别器需要判断出是否有红绿灯并且输出红灯或是绿灯。当然,它应该只识别行驶方向的信号灯。


下面这几张图可以更清楚的说明:




以上就是我需要识别的三种可能性:没有红绿灯、红灯和绿灯。


要解决这个挑战, 最合适的解决方案是基于卷积神经网络,这是目前最流行的方法,应用深度神经网络来识别图像。 最终提交的识别模型大小也是评判的依据,模型文件越小,得分越高。此外,获胜所需的精度要达到95%。


Nexar提供了18659幅标记图像作为训练数据。每幅图像都标有上面三个类别中的一个(没有红绿灯/红灯/绿灯)。


软件与硬件

我选择了Caffe来训练模型,主要原因是我对Caffe比较熟悉,而且它提供了大量的预训练模型。


用Python、NumPy和Jupyter Notebook用来进行结果分析、数据探索和脚本编写。


我购买了Amazon的GPU实例(g2.2xlarge)用来训练模型。到挑战赛结束后,AWS账单收了我263美元!这可真不便宜……


最终的识别器


最终,我的识别模型实现了对测试集合94.955%的精确度,模型大小为7.84 MB。相比较,GoogLeNet的模型占用了41 MB,VGG-16模型竟然要用到528 MB。


需要感谢Nexar,他们仁慈的允许了我的94.955%达到95%的精度要求。


总的来说,提高模型精确度的过程就是进行大量有逻辑和无逻辑的试验,以及反复纠错,下面是具体过程。


怎样建立识别模型


选择ImageNet预训练模型

开始搭建模型时,我选择了ImageNet的预训练模型,用GoogLeNet搭建架构对它进行微调,很快这就帮我达到了90%的准确性!良好的开端!


SqueezeNet

SqueezeNet达到了AlexNet同级的精确度,参数却减少了50多个,而且模型尺寸只有不到0.5MB。 此外,它与ImageNet的预训练模型和Caffe的Zoo模型配合良好,这完美的切合了我的需求。SqueezeNet在github上的地址如下:

https://github.com/DeepScale/SqueezeNet

(SqueezeNet网络架构图 )


搭配好之后,导入Nexar的图片集合,经过一些简单的训练和调整,预训练模型的精度几乎从一开始就提升到了92%!效果非常赞!


旋转图像

Nexar提供的绝大部分图像都是水平的,但有大约2.4%是垂直的,而且没有上下左右的标识,如下图:



虽然这只是数据集的很小一部分,但想要达到95%的精度,这个问题是必须考虑的。


Nexar提供的JPEG图像没有EXIF数据,所以我想到将图片随机旋转0度、90度、180度和270度并且导入训练模型,用来确定天空的位置,确实获得了精度提高: 92%→92.6%


更多的训练数据

首先,我把数据分成3组:训练(64%)、验证(16%)和测试(20%)。几天之后,我把训练组和验证组合并,使用测试组来检查训练结果。


并且在模型中加入了“图像旋转”和“低发生率额外训练”,获得了不小的精度提升: 92.6%→93.5%


手动标注训练数据错误

当分析模型识别的错误时,我注意到有些在模型中信任级别非常高的训练数据反而容易出错。

注意,在上面这张错误统计图中,最右边的栏达到了95%的信任度,这表示有大量的错误出自信任度超过95%的图像数据,这就很尴尬了。


为了解决这个问题,我不得不手动标注了709个图像,这花费了我一个小时的体力劳动,而且编写了一个Python脚本来帮助工作。当然花费的时间是值得的。


上面这张是经过重新标注和再训练的模型错误统计图,看起来好多了!


而且又一次提升了模型的精确度: 93.5%→94.1%


集成模型

将几个模型结合在一起,给予相应的权重并加权计算它们的分析结果也会提高最终的精确度。


最终的识别器

最终完成的识别器将3个单独训练的网络模型加以结合。


1号模型:过采样预训练网络

基于ImageNet的SqueezeNet预训练模型,根据手动修正后的图像集合进行训练。

训练数据增强步骤:

  • 随机水平翻转

  • 从图像中随机切割227×227像素大小的方块,喂养到训练网络


在测试时,每张图像会形成10个变体,平均计算出最终的预测结果。这10个变体为:

  • 5个227×227的随机切割图像:从中心切割1个,4个角各切割1个

  • 以及水平翻转后的5个相同位置随机切割图像


模型大小:2.6 MB

模型精度:94.21%


2号模型:添加旋转不变性

2号模型与1号模型非常相似,加上了图像旋转。在训练时间,图像会随机旋转90度、180度、270度或0度(不旋转)。在测试时,每一种情况都与模型1中创建变体做相同的分析。这样2号模型会分析40个变体,并将结果平均在一起。


模型大小:2.6 MB

模型精度:94.1%


3号模型:全新训练

3号模型不是基于SqueezeNet的微调,而是从零开始训练。背后的逻辑是即使准确率较低,但它会产生与上两个模型不同的特征,在三个模型合并之后,这会非常有用。


数据训练和测试过程与模型1基本相同:翻转和切割。


模型大小:2.6 MB

模型精度:92.92%


结合模型

每个模型都会输出三个值,表示图像属于三大类中每一类的概率(没有红绿灯/红灯/绿灯)。我根据以下的权重平均计算它们的输出值:

  • 模型1:0.28 #

  • 模型2:0.49 #

  • 模型3:0.23 #


权重的值大家可以自己定义,我是基于以前做网格搜索时获得的经验,这是一个非常简单的操作。


最终模型大小:7.84 MB

最终模型精度:94.83%

实际用于Nexar测试集的模型精度:94.955%


模型出现的一些错误


棕榈树上的绿色反光点让模型误判断为那是一个绿灯。







请到「今天看啥」查看全文