这一篇主要讲讲对整个项目的一个规划以及前期工作

1. 项目介绍

车辆检测及型号识别广泛应用于物业,交通等的管理场景中。通过在停车场出入口,路口,高速卡口等位置采集的图片数据,对车辆的数量型号等进行识别,可以以较高的效率对车型,数量信息等进行采集。通过采集的数据,在不同的场景中可以辅助不同的业务开展。如商场停车位的规划,路况规划,或者公安系统追踪肇事车辆等等。
所以,本项目利用 tensorflow 提供的 slim 图片分类框架和物体检测框架实现一个可以对任意图片进行车辆检测识别的系统。

2. 检测模型的选择

由于已有的数据只是分类数据,即对车辆型号进行分类,没有检测数据,那么检测部分职能使用已有的model zoo,检测框架使用的是官方tensorflow/research目录下的的object detection框架,并从中已有的modelzoo选择模型。目前已有的model zoo分别是从COCO, Kitti, Open Images, AVA 4个数据集训练好的。但是本项目是要做车辆检测识别,AVA数据集不太适用,所以准备从另外三个数据集中训练好的model zoo来做实际测试比较。
首先是coco数据集
coco mz.png
由图中可以看到,mAP值最高的是faster_rcnn_nas模型,但是由于训练速度太慢,于是舍弃,选择了faster_rcnn_nas_lowproposals_coco这样一个模型作为备选方案,虽然图上没说,但是感觉mAP值也不会低。
kitti mz.png
Kitti 数据集只提供了一个模型 faster_rcnn_resnet101_kitti, 因此只能选择他为备选。据说是ITTI 包含市区、乡村和高速公路等场景采集的真实图像数据,每张图像中最多达 15 辆车和30 个行人,是一个专门为了自动驾驶训练用的数据,应该和本次项目的场景匹配,但是具体效果还要看实际测试。
open images mz.png
open Images数据集,由于要和前面保持一致,考虑到速度的问题,依然选择了速度更快的faster_rcnn_inception_resnet_v2_atrous_lowproposals_oid模型作为备选。
然后接下来开始实际测试:从网上下载了几张街道汽车图片,对三个备选模型进行测试,测试结果如下:
首先是faster_rcnn_nas_lowproposals_coco:
coco1.png
coco2.png
coco3.png

其次是faster_rcnn_resnet101_kitti:
kitty1.png
kitty2.png
kitty3.png

最后是faster_rcnn_inception_resnet_v2_atrous_lowproposals_oid:
open image1.png
open image2.png
open image3.png

经过以上实际图片测试, 准确率最高的模型为: faster_rcnn_nas_lowproposals_coco。
faster_rcnn_resnet101_kitti 虽然是专门的街道和汽车数据, 但是表现也比起 coco 数据集稍差, 而faster_rcnn_inception_resnet_v2_atrous_lowproposals_oid 号称数据有 900 万张标记图片,可是基本没有把汽车给识别出来,估计是数据集中的汽车数据非常少的缘故。

本次项目检测部分拟选泽 faster_rcnn_nas_lowproposals_coco 模型的model zoo。

3. 分类部分的模型选择

我们可以先看下slim框架下的,已经提供的model zoo在 image net 2012 数据集上的表现, 最新的准确率最高的是 PNASNet-5_Large_331, 达到甚至超过了原来准确率最高的 nasnet。
slim mz.png

至于模型参数的数量,比较如下:
model params1.png
model params2.png
model params3.png

Pnasnet 的参数数量也只是和 nasnet、 resnet 在一个数量级上, 比 VGG 少, 但多于 inception,训练起来应该不会比其他网络困难。而且在本地测试的时候,pnasnet对配置的要求更低。综上,选择 PNASNet-5_Large_331 模型作为分类模型。

4. 检测模型及分类模型整合方式

刚开始我先考虑了采用 end to end 的方式来把两部分模型融合在一起。于是,我经过我查询相关资料, 对 end-to-end 的理解为:在一个多环节多步骤的任务中,在其中某些环节,比如特征提取这个阶段, 传统的方式是靠历史经验来制定规则,人的干预的因素很大,最终模型性能的好坏很不稳定,并且各个环节相对独立,各自训练产生的只是各自环节的局部最优解,而不是全局最优解,训练优化时也不能优化模块与模块之间的连接。使用 end-to-end可以把所有环节都用一个模型来处理, 只给出输入和输出 ground truth 数据, 模型会自动学会整个过程, 完全去除了人的干扰因素, 各环节之间达到最优的配合。
但是, 回到这次项目的情况,并不适合用 end-to-end 的方式的, 有以下 2 点原因:

  1. 目前项目提供的数据是车型分类数据, 输入为图片, ground truth 为车型分类,并不是end-to-end 的数据, end-to-end的数据需要 ground truth 为带 bndbox 的检测数据, 很明显就算构造了 end-to-end 模型,也无法生成对应的训练数据。
  2. 本次项目分为检测部分,分类部分 2 个部分,检测部分目前是没有自己的数据集的,需要用在 coco 训练好的 model zoo 的模型进行检测, 在图片中找到汽车的位置,而分类部分是项目提供的数据, 需要根据数据训练汽车分类模型。 由此可知, 受限于数据, 两部分相对独立的情况下, 不会产生相互间的影响, 相互独立的分别去做 finetue, 也并不需要做连接上的优化,没必要将检测和分类两个模型融合到一起形成 end-to-end一个整体。
    整个运行流程确定如下:

flow.png

  • 预测图片输入检测模型后, 输出为各类物体的 boxes 框, 经过过滤, 留下类型为汽车的boxes
  • 用汽车 boxes 框来分割输入图片, 将其分割成多个小块的图片数据
  • 将这些图片数据作为分类模型的输入
  • 分类模型输出各小块图片的分类结果
  • 最终以输入图片为底图, 叠加上 boxes 框及分类预测车型文字得到一张输出结果图片

5. 系统打包方式

当在 python tensorflow 下完成了整个功能之后,就需要对其进行打包,目前有两种方式打包,一种是打包成.exe 可执行文件,用命令行方式执行,用路径参数传入预测图片,生成的图片存在输出文件夹。一种是发布 web 服务,通过网页来上传输入预测图片,用网页显示结果图片。 考虑到目前已经是互联网时代,很多服务都是通过网络发布的,我也想将本次项目的成果通过互联网发布出去,让更多的人看到,因此我准备选择 web 服务的方式来完成本次项目。

若是发布成web服务的话方案选择就有很多,比如:Flask、Django、Tornado等等。各自特点如下
Flask:一个轻量级的基于 Python 的框架,提供最小的核心,足够的自由,但是 Flask提供了非常好的扩展系统,哪怕是一个新手,也能在文档的提示下编写一个可用的扩展。这样做唯一的缺点就是第三方扩展生态环境非常繁盛,但是质量参差不齐,考验眼力。案例:果壳网基于 Flask 开发的。
Django:是一个全能型框架,重量级的。目前 Django 的使用面还是很广的,有学习的价值,但是要学习的东西太多。Django 的目的是为了让开发者能够快速地开发一个网站,它提供了很多模块, 比如 admin 模块, http://your.site.com/admin 就进入了网站的后台, 方便地对数据进行操作,等等。 因此,如果对 Django 熟悉的话, 很快就能写好一个网站的原型。

对于一个初学者来讲的话,感觉更应该用轻量级的,而且Flask 比 Django 更加 Pythonic,更加灵活,非常适合小型网站,也适用于开发web服务的API,而且扩展性也很强,第三方库的选择面广。所以这次打算用Flask来发布web服务。