老司机用神经网络带您安全驾驶

作者:刘畅

前言

随着今年深度学习的热潮的来临,神经网络已经被应用在越来越多的应用中。而在印象中对于神经网络进行训练的往往需要借助大量的计算资源与数据。其实通过一定的方法,配合预训练好的网络,我们完全可以在自己的PC上训练出一个准确率较高、实用性也非常不错的网络。下面我就以Kaggle上的一个竞赛为例,带领各位司机训练一个对驾驶行为进行分类的网络。

首先我们了解一下需要解决的问题: 我们有一位老司机,可惜开车时不太专心,一会儿喝饮料一会儿打电话又或是在玩手机, 并在驾驶过程中不断的变化着自己的姿势。碰到这样的老司机,我们有没有办法提醒他安全驾驶呢?

设想如果我们能在他的汽车上装上一枚摄像头,并通过实时图片采集他的行为。最终通过神经网络分析他的动作行为,善意的提醒他安全驾驶的姿势。

这看起来是不是很酷~~ 装上摄像头的汽车采集到的数据,就像下图这样:

接着这一问题转换成了神经网络,即对10种类型的图片进行分类预测的问题,这10种行为分别是:

  1. 正常开车
  2. 右手玩手机
  3. 右手打电话
  4. 左手玩手机
  5. 左手打电话
  6. 操作收音机
  7. 喝东西
  8. 向后伸手
  9. 化妆
  10. 说话

而训练数据所需要用的数据库,大家可以在Kaggle网页上自行下载,这里是网址Kaggle StateFarm

1. 训练准备

1.1 下载训练数据

了解了问题之后,我们开始准备我们的训练数据。 第一份数据可以在Kaggle网站上下载到。在下面图中的这个页面中,我们只需要下载Images.zip这个4GB的文件即可。

下载完成之后,我们将这个Zip包解开,将看到下面这样的目录结构:


└── train
    ├──c0
    │   ├── img_1.jpg
    │   ├── img_2.jpg
    │   ├── ...
    ├──c1
    ├──...
    ├──c9    
└── valid
    ├──c0
    ├──c1
    ├──...
    ├──c9

稍微解释一下,train目录是给我们训练用的目录,里面一共有c0到c9十个分类,对应我们刚刚列出的 0.正常开车 1.右手玩手机 2.右手打电话 等十种行为。在这个训练集中一共包含22,286张图片。

而valid目录是给我们校验的目录,也同样是c0到c9十个分类,但它只有115张图片,主要的作用是用对训练好的神经网络进行校验,稍后我们也会用到它。

1.2 自己拍摄数据

由于训练数据比较少,加上 死磕自己,娱乐大家 的的精神,作为老司机我也上“车”试上一把。:)

纯手工打造一台“汽车”并参与到训练中去并不难,而所需要的东西如下:

就这样不停的变换姿势,一共拍摄了200张不同姿势的开车照片,并依照不同的类别放置在刚刚的的train目录对应的分类中。同时也放少量的照片到valid目录中,注意要保证train和valid目录中的照片不重复。

1.3 产生更多数据

最后,如果数据还觉得不够的话,我们可以对数据再做一次Data Augmentation,这样可以产生更多的训练数据。

比如对同一张照片做颜色和角度偏移就可以得到多张不同的照片,如下图所示,这些照片对训练也是相当有帮助的。

好啦~万事俱备,各位老司机坐好了,我们马上准备开车了~

2. 开始训练

2.1. 迁移学习

终于到了训练的步骤,问题是我们手头上只有一台普通的开发机器:Corei7, 8G内存,gtx660。比起各大云服务器上动辄几百G+几十个核心的服务器,需要通过这样一台机器训练一个稍显复杂的网络真的是有点难堪。

所以这里向各位老司机推荐迁移学习中的一个小tricky,名曰 Fine-tune。关于Fine-tune的更详细的步骤大家可以在这里得到(配有源码):Finetuning AlexNet with TensorFlow

而这里提到的fine-tune如果总结一下的话,主要原理可以理解成如下三步骤:

STEP1: 首先我们需要获得一个预先训练好的网络,如下图中的VGG16网络。

STEP2: 我们将网络中的后三个全连接层去掉,只留下前面的卷基层和Pooling层。

STEP3: 加入新的全连接层, 冻结之前所有层,仅仅训练新加入的全链接层。

了解了基本原理之后,我们开始根据自己的实际做 Fine-tune。注意,这里我们要处理的是一个十分类问题,也就是说,我们的网络最后要有10个输出。所以我大概做了这样一个包含一个隐藏层的全连接网络,附加到VGG16的末端:

(full) (None, 256)   # 上接VGG16  
(full) (None, 256)   # 一个隐藏层
(full) (None, 10)    # 输出10个分类

2.2. 训练网络

之后我们将VGG16的前面14层冻结,开始训练后面的三层。冻结网络层,其权重值在训练过程中不会发生任何变化。

有了之前的工作,这个训练就变得和普通全连接网络的训练过程完全一样了。

在我的NVIDIA GeForce GTX660 上用了12个小时, 一共跑了30个epoch,每个epoch将我们准备好的2400张照片作为输入。学习速率我这里设置到0.0001这样一个数值,

最终Loss函数值稳定在0.0262。看到Loss函数呈现如下图中基本上不下降了之后,即可以结束训练了。

3 检验结果

3.1 简单预测

OK~ ,进过漫长的等待。我们终于可以使用这个网络了~ 现在开始使用刚刚数据库中的校验集,也就是valid目录中的图片。先简单的传入10张图片看看网络的预测结果呗。这10张图片的正确类型的动作行为编号分别是[1 1 1 2 0 3 3 0 3 2]。而网络输出的结果是[1 1 1 2 0 3 4 0 3 2]。貌似还不错,只是有点小错误。如下是正确结果和预测结果的比较:

[1 1 1 2 0 3 4 0 3 2] # predict
[1 1 1 2 0 3 3 0 3 2] # correct

如果将结果用matpilot输出出来的话会更加直观。如下图是输入网络的10个照片,每张图片的标题是预测结果,发现只有红框中的那一张出现了预测错误的问题。

我们再尝试对state farm数据库中的照片做一下分类,10张照片中同样发生了一个错误的预测(红框内为错误的预测):

3.2 结果分析

那是不是我们可以认为网络的准确率在90%呢?网络最容易出现错误的预测是哪几类图片呢?

对于这两个问题,尝试对所有的校验集数据做一个预测,并将最终的结果打印成一个confusion_matrix就会有答案了。在这个矩阵中,用每一行表示神经网络预测的结果,每一列表示正确的结果。输出以后它是这个样子的:

#confusion_matrix
     ([[ 49,   0,   0,   0,   0,   0,   0,   0,   0,   0],
       [  0,  76,   0,   0,   0,   0,   0,   0,   0,   0],
       [  0,   0, 106,   0,   0,   0,   0,   0,   0,   0],
       [  1,   0,   0, 114,   0,   0,   0,   0,   0,   0],
       [  0,   0,   0,   5,  93,   0,   0,   0,   0,   0],
       [ 16,   0,   5,   1,   0,  73,   0,   0,   0,   0],
       [  5,  13,  11,   6,   1,   0,  72,   0,   0,   0],
       [  2,   0,   0,   0,   0,   0,   0, 105,   0,   1],
       [ 13,   1,   5,   0,   1,   0,   0,   0,  84,   6],
       [ 38,   0,   2,   0,   0,   0,   0,   0,   0,  65]])

分析一下, 我们可以将对角线上的所有数据加起来,得到网络的准确率是86.3%。

再具体一点,可以看出最难区分清楚的是3.左手玩手机4.左手打电话 ,后续如果增加3、4这两个分类的话,那么网络的准确率还有更大的提升。

4 结语

通过整个实验过程,我们发现通过神经网络解决复杂图片的分类问题并不复杂,只需要通过一些小的技巧,训练网络的计算资源也并非很大。86.3%的正确率这一结果也还比较理想~

最后我把本文中用到的一些重要的资料再列举一下,原文、源码、数据都在了,各位老司是不是跃跃欲试了~ :)

Finetuning AlexNet with TensorFlow blog

Finetuning AlexNet with TensorFlow code

Kaggle State Farm

本文发表于MelonTeam,转载请联系作者获得授权。

原创声明,本文系作者授权云+社区-专栏发表,未经许可,不得转载。

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

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏量子位

OpenAI发布可扩展的元学习算法Reptile | 论文+代码+Demo

昨天,OpenAI发布了一种新型的可扩展元学习算法Reptile,还能在线试玩。 何为Reptile?难道是—— ? 咳咳严肃一点。 据OpenAI官方博客显示...

3295
来自专栏CreateAMind

Keras和DDPG玩赛车游戏(自动驾驶)

这里,s是状态,a是行为/动作,θ是策略网络的模型参数,π是常见的表示策略的符号。我们可以设想策略是我们行为的代理人,即一个从状态到动作的映射函数。

972
来自专栏AI研习社

野外动物监测图像挑战赛:预测捕捉到的野外图像是否包含动物

野外相机能够自动收集大量的图像信息,不过不幸的是,收集到的大量图片都是误报,这些错误大多是由非动物引起的,比如草木的晃动。 本次比赛旨在预测白天和晚上从各个地点...

3189
来自专栏量子位

Tensorflow官方语音识别入门教程 | 附Google新语音指令数据集

李林 编译整理 量子位 报道 | 公众号 QbitAI Google今天推出了一个语音指令数据集,其中包含30个词的65000条语音,wav格式,每条长度为一秒...

4678
来自专栏机器之心

资源 | 可视化工具Yellowbrick:超参与行为的可视化带来更优秀的实现

1343
来自专栏CDA数据分析师

我的R语言数据挖掘基础入门学习笔记(二)

选择的数据集是NBA2013-2014赛季球员数据,该数据集来自网络并用于其所在文章(详见:https://www.dataquest.io/blog/pyth...

1875
来自专栏计算机视觉战队

稀疏&集成的卷积神经网络学习(续)

昨天跟大家详细的说了分类,定位的一些相关知识,今天把剩下的最后一点知识给大家补充完整,也感谢大家一直的支持,谢谢! 昨天的推送告诉大家了分类方案,我们再温习一...

2746
来自专栏郭佳伦的专栏

web 前端入门神经网络(一)

在神经网络中,激活函数和损失函数是决定 网络模型是否有效和学习速率的关键部分,这次没有展开说,我觉得对于刚接触的同学先不要纠结于此,自己把程序先跑起来,识别几种...

4310
来自专栏新智元

深度学习应用系统分析:应用组合和形态矩阵找到正确路径

【新智元导读】本文收录了arXiv.org上关于深度学习的一些最新的研究论文,列出了这些文章的内容,包括“深度学习八大灵感应用”、“深度学习用例”、“科学与工程...

40910
来自专栏应兆康的专栏

5. 开发集和测试集

让我们回到之前关于猫咪图片的例子: 你开发了一个移动APP, 用户可以上传许多不同的图片到你的APP上,你想识别出用户上传的图片中所有包含猫咪的图片。 你的团队...

2916

扫码关注云+社区