当前位置: 首页 > 编程日记 > 正文

赠书 | 图像分类问题建模方案探索实践

作者 | 中国农业银行 陆春晖

责编 | 晋兆雨

出品 | AI科技大本营

头图 | 付费下载于视觉中国

*文末有赠书福利


背景

图像分类,是计算机视觉领域的一个核心问题,顾名思义就是输入一张图像,根据内容将其划分到某一个特定的类别。与其他分类问题相比,主要的区别在于输入是图像,这就导致其特征工程方法相对单一,通过图像的像素值进行特征提取。图像分类问题可以用图1来形象的描述。

图1 图像分类之“猫狗大战”

图像分类同时是其他很多高层视觉问题的基础,例如目标检测、图像分割、目标追踪、行为分析等等。它本身也在很多领域中有广泛的应用,例如社会生活领域中的垃圾分类、安防领域的人脸识别、医学领域的病灶识别、航空遥感领域的环境污染检测等等,本文中研究的具体问题属于自动驾驶领域中的交通路况识别。

图像分类的算法研究经历了一个比较漫长的过程。早期的最近邻分类(KNN)算法,将图像的像素值用二维矩阵存储,再将二维矩阵拉伸成一维向量,通过度量向量间距的方式进行分类。该类算法操作简单易于实施,但是计算量大,并且容易受到样本不平衡问题的影响;然后是多层感知器(MLP)算法,类似于KNN的特征处理,让一维向量特征通过包含多个线性非线性函数组合的神经网络结构,通过计算各类别可能性概率的方式进行分类。这一类算法在普通图片上识别效果不错,但是由于节点间的全连接方式会导致维度灾难,因此不能扩展到更高分辨率的图像上;近些年伴随深度学习的兴起,基于卷积神经网络(CNN算法)的算法越来越受欢迎。该类算法是通过卷积网络分层提取图像特征,替代单纯的向量特征,再依次通过卷积层、池化层、激活层等神经网络结构的运算,直接进行端到端的分类。这一类算法的网络结构不再使用全连接模式,并且计算量更小,也不需要额外的特征工程,因此使用范围更广。本文中进行交通路况识别所使用的模型就是基于卷积神经网络的残差网络(ResNet)。

数据准备

本文以阿里巴巴高德地图AMAP-TECH算法大赛 - 基于车载视频图像的动态路况分析为例,探索图像分类问题的建模方案。该比赛需要通过由行车记录仪拍摄的图像序列,判断对应道路当前时刻真实的路况状态。本文中用于建立模型使用的数据集包含4200个图像序列,每一个图像序列包含(3-5)帧图像,总共有16000多张图片。一个图像序列中包含的图像如图2所示。

图2 一个图像序列里包含的多帧图像

每个图像序列中有一幅为参考帧(参考帧多为路况状态容易清晰判断的序列中间或最后一帧图像),算法需要根据整个图像序列来推断路况的状态,分为畅通、缓行、拥堵和封闭四种情况。每个状态的参考帧示例如图3所示。

图3 不同路况状态的图像

数据集整体对应的路况状态情况大致为畅通30%,缓行10%,拥堵20%,封闭40%。其分布如图4所示。

图4 不同路况状态的分布

建模流程

问题分析

在初步分析数据集后,我们对整个问题有了一个大致的了解。从表面上看来,这是一个典型的图像分类问题,需要输入一张图片,根据图片内容判断图中路况属于哪一个类型。再进一步观察数据和结合交通的基本常识可以知道,大部分场景下,前方车辆的数量和密度决定了路况状态,前方道路障碍物存在与否,决定了道路是否封闭。似乎需要先对图片进行目标检测,检测出车辆和道路障碍物,再根据检测结果进行分类。但是经过简单的实验,发现先目标检测再进行分类的效果并不理想。研究背景知识得知,实际路况上可能存在诸如行驶道路有大量路边停车,但不影响车辆行驶,状态为畅通;或者行驶在双向道路,对向车道拥堵,但行驶车道路况状态为缓行或畅通;又或者围挡、路障等障碍物是造成道路封闭的直接原因,但非道路区域存在大量噪声(如路边的围挡、锥桶等)。加之目标检测算法本身可能存在的误差,都会影响分类的效果。

基于以上各种因素,还是决定放弃先目标检测再进行分类的策略,直接进行图像分类。进一步分析数据集,发现每个图像序列都是多帧图像,并且标明了参考帧,参考帧是整个图像序列中最清晰或者最后一帧图像,所有分类的判断都基于参考帧。所以决定以参考帧为输入图像进行分类。

图像分类问题的基本建模流程如图5所示。

图5 图像分类问题建模流程

图像预处理

图像分类中,图像质量的好坏会直接影响模型的效果,因此需要对图像进行预处理。预处理的主要目的一方面是消除图像中的无关信息,例如归一化,另一方面是增强有用信息的可检测性,例如圈定ROI区域。

归一化

图像归一化是指对图像进行一系列标准的处理变换,使之变换为一固定标准形式的过程,与其他特征归一化的目的相同,都是为了更快地训练算法并达到更高的性能。本文中主要对图像进行形状归一化和灰度归一化,即将所有图像统一调整成512*512的大小,并将每个像素值除以255,使得所有值都在0和1之间。图像归一化效果如图6所示。

图6 图像归一化效果

圈定ROI区域

图像的ROI区域,就是 “感兴趣的区域”(region of interest),从图像中选择重点关注的区域。使用ROI区域,可以减少处理时间和增加精度。本文中使用了两种方式进行ROI区域的圈定,一种是固定区域,通过手动梯形框圈定;一种是动态跟踪,利用帧差法圈定,并将这两种方式和完全不圈定ROI区域方式的建模时间和精度进行了对比。

手动圈定ROI区域,主要是利用背景知识人工指定关注区域,即主要关注关键帧图像中摄像头所拍摄的车辆正前方的道路区域,忽视天空和两旁的区域,再结合近大远小的摄像头成像特点,直接使用梯形框进行ROI区域的圈定,其圈定效果如图7所示。由于归一化后所有图像尺寸统一,所以使用大小唯一固定的梯形框即可。

图7 手动圈定ROI区域效果

利用帧差法圈定ROI区域,顾名思义,就是通过对不同帧的图像做差来圈定感兴趣的区域。帧差法是最为常用的运动目标检测和分割方法之一,其基本原理是在图像序列的相邻两帧或三帧间采用基于像素的时间差分,再通过闭值化来提取出图像中的运动区域。结合本文中的场景,就是利用关键帧前一帧的图像,和关键帧图像做差,利用两帧图像间的差值图像,圈定汽车行驶过程中随着时间推移有明显变动的区域,也就是ROI区域。

这个过程涉及到几个关键步骤,首先是做差后的阈值化,其次是二值图像轮廓的提取,最后是目标检测框的合并,接下来分别进行阐述。

做差后的阈值化,需要提前设定一个阈值。当两帧图像做差之后,先通过形态学上的腐蚀和膨胀操作,减少空洞,然后将得到的差值图像每一个位置的像素值都和阈值比较,比阈值大的地方像素值设为255,比阈值小的地方像素值设为0,这样就得到一个二值化的运动区域图像。cv2图像库中提供了cv2.threshold()方法可以直接进行调用。

二值化的图像需要提取轮廓,也可以借助cv2图像库中的cv2.findContours()和cv2.boundingRect()方法来提取,可以得到运动区域的矩形边框。需要注意一点,由于是车载图像,摄像头本身也在运动,导致两帧图像间变动的地方可能很多,但不是所有有变动的地方都是感兴趣区域,对于提取出来区域面积过小的轮廓框可以忽略。

过滤掉面积过小的轮廓框后,需要进行目标检测框的合并。其原理是将相交面积大于一定阈值的目标检测框合并,根据各目标检测框的坐标值来计算是否相交和相交面积大小。需要注意的是由于只是想圈定ROI区域,所以本文中只是计算出所有相交目标检测框位置的中心点,再结合各目标检测框大小,合并所有的相交目标检测框作为唯一的ROI区域。帧差法圈定ROI区域的整体流程和效果如图8所示。

图8 帧差法圈定ROI区域流程和效果

如果使用帧差法圈定ROI区域,需要在图像归一化之前进行,避免因归一化影响帧差效果,手动圈定ROI区域则没有相关限制。

图像加载和批处理

将图像读入内存时,会遇到的最大挑战是图像太大,会导致内存溢出。所以需要对图像进行批量处理,一次只加载一个批次的图像。本文使用PyTorch里的Dataset类和DataLoader类来实现。

Dataset类主要是实现每张图片的加载,自定义数据集需要重写_init_,_len_,_getitem_三个函数。_init_函数初始化数据集路径、标志文件、等信息,_len_函数返回数据集大小,_getitem函数返回单张图片及其标志信息,包括图片的预处理也在该函数里进行。

DataLoader类主要实现批量图像的加载,自定义加载类需要指定加载的数据集、每批次加载的图片数量、是否打乱排序、以及提取数据的进程数等参数信息。每批次加载图片的数量,也会影响模型训练的收敛速度和准确性。

模型选择和迁移学习

图像分类可以用的深度学习模型很多,例如VGG、AlexNet、ResNet等等。综合流行趋势和分类效果,本文选择了ResNet网络结构进行分类。ResNet又名残差神经网络,指的是在传统卷积神经网络中加入残差学习(residual learning)的思想,解决了深层网络中梯度弥散和精度下降(训练集)的问题,使网络能够越来越深,既保证了精度,又控制了速度。简要的说,深度学习的网络,随着层次的加深,会出现退化,即在训练集上的准确率饱和或者下降。而残差网络通过残差学习和恒等映射,可以很好的避免这个问题,从而可以通过不断加深网络层数,提升模型的准确率。残差网络的具体原理,可以参考相应的论文和介绍,本文不做详细讨论。考虑到训练的效率,本文选择ResNet50展开训练。

在实际训练深度学习的模型时,可以通过迁移学习的方式进行。通俗来讲,就是运用已有的知识来学习新的知识,即可以使用其他数据集上已经训练好的分类模型,拟合我们自己的数据集,这样可以加快拟合。Pytorch中可以直接使用已经预训练好的ResNet50模型,同时为了适应自己的数据集,需要将最后一层Linear层进行替换,使其输出为4通道,对应四种路况。

结论和展望

将数据集按8:2划分成训练集和验证集,使用不圈定ROI区域、手动圈定ROI区域以及通过帧差法圈定ROI区域三种不同图像预处理方式进行模型训练的结果如表1所示。其中评测模型使用的错误率评价函数是交叉熵(Cross Entropy Loss),交叉熵描述了两个概率分布之间的距离,当交叉熵越小说明二者之间越接近。准确率评价函数使用ACC(Accuracy),指在分类中,使用测试集对模型进行分类,分类正确的记录个数占总记录个数的比例。

图像预处理方式

训练时间

错误率(交叉熵)

准确率(ACC)

不圈定ROI区域

40m 8s

0.0187

0.898483

手动圈定ROI区域

43m 15s

0.0183

0.899650

帧差法圈定ROI区域

40m 38s

0.0391

0.775963

表1不同图像预处理方式的模型训练结果

可以通过表1发现,帧差法圈定ROI区域明显在准确率上低于不圈定ROI区域和手动圈定ROI区域,这可能是因为帧差法在处理车载视频图像时,因为摄像头本身也在移动,背景和前景区分度不大,导致圈定的ROI区域有比较大的误差,损失了比较多有用的信息。不圈定ROI区域和手动圈定ROI区域准确率差别不大,但是训练时间上不圈定ROI区域明显比圈定ROI区域要快,这也符合客观认知。

训练过程中各模型随着迭代次数的增加,在训练集和验证集上的误差曲线和准确率曲线如图9所示。

图9误差曲线和准确率曲线示意图

可以发现帧差法圈定ROI的方法,在验证集上的震荡比较明显,可能是因为帧差法容易受到外在因素的影响,比如光线、清晰度、以及拍摄角度等,健壮性不强。而手工圈定ROI和不圈定ROI在训练后期都出现了比较明显的过拟合现象,但是手工圈定ROI的健壮性要比不圈定ROI的强,这大概是因为手工圈定ROI指定了只关注道路所在区域,不易受到其他区域的噪音影响。

即使分类效果最好的模型,验证集上的分类准确率也不过89.96%,在路况识别的实际应用中尚不是很理想,需要进一步优化。图像分类模型的优化可以使用光线均衡、图像增强等方式,也可以考虑使用更深的网络,或者适当结合目标检测、目标追踪等技术。图像分类技术在实际情境中的应用尚有很多困难和挑战,希望本文能对同行业者有所启发。

#欢迎留言在评论区和我们讨论#

看完本文,对于机器学习的图像分类你有什么想说的?

欢迎在评论区留言

我们将在 11 月 24 日精选出 3 条优质留言

赠送《人工智能数学基础》纸质书籍一本哦

更多精彩推荐
  • AI 隐身术,能让物体在视频中消失的魔法

  • 程序员奶爸用树莓派制作婴儿监护仪:哭声自动通知,还能分析何时喂奶

  • 强化学习:10种真实的奖励与惩罚应用

  • 全球数百万台 Mac 疑似因 Big Sur 更新险酿计算灾难,苹果官方回应来了!

  • 大神们都是如何在时间序列中进行特征提取的?看完就懂了!

相关文章:

数据库开发个人总结(ADO.NET小结)

一.用SqlConnection连接SQL Server 1..加入命名空间using System.Data.SqlClient;2.连接数据库SqlConnection myConnection new SqlConnection();myConnection.ConnectionString "user idsa;passwordsinofindb;initial catalogtest;data source127.0.0.1;Con…

PHP 调用C的代码

用php调用C函数,常通过调用系统命令函数的方式来实现,其中主要有system()和exec()两种,还有一种是passthru(),这种方法没有尝试,暂不作讨论。 system()方法输出并返回最后一行的shell结果。 exec()不输出结果,返回最后…

态势“知”多少,点开就知道

2019独角兽企业重金招聘Python工程师标准>>> 态势感知,最核心的是“知” 关于“知” 典故不少 《孙子兵法》六千多字,“知”出现了79次,只有《势篇》与《行军篇》中没有“知”字。 史称两个半完人之一的王阳明 在经过五溺三变的曲…

17 种正则表达式

作者:http://blog.csdn.net/hivak47/archive/2004/10/31/161006.aspx"^/d$" //非负整数(正整数 0) "^[0-9]*[1-9][0-9]*$" //正整数 "^((-/d)|(0))$" //非正整数(负整数 0&#xff09…

程序员如何乘风破浪?从数据库历史看技术人发展 | CSDN 高校俱乐部

2009 年我国数据库软件市场规模为 35.03 亿元,2017 年我国数据库软件市场规模增长至 120.00 亿元。8年时间内,我国数据库软件市场始终保持平稳增长,年均复合增长率为 17.5%,且增速呈现递增趋势。根据中研产业研究院估计&#xff0…

陶哲轩实分析 定理 13.3.5 :紧致度量空间上的连续函数一致连续

设 $(X,d_X)$ 和 $(Y,d_Y)$ 都是度量空间,假定 $(X,d_X)$ 是紧致的,如果 $f:X\to Y$ 是函数,那么 $f$ 是连续的当且仅当 $f$ 是一致连续的.证明:当 $f$ 是一致连续时,$f$ 显然是连续的.我们主要证明 $f$ 连续时一致连续.我们采用反证法,假若 $f$ 不是一致收敛的,意味着无论如何…

SQLServer------插入数据时出现IDENTITY_INSERT错误

详细错误信息: 当 IDENTITY_INSERT 设置为 OFF 时,不能为表 Student 中的标识列插入显式值。 原因: 表中存在某个字段是自动增长的标识符 解决方法: set IDENTITY_INSERT Student ON //设置为OFF时表示不能手动给拥有标识符的列插…

ASP.NET 制作让搜索引擎可以友好访问的链接

作者:http://www.donews.net/lealting/archive/2004/03/31/9759.aspx今天看了一篇文章,主要是讲,如何制作让搜索引擎可以友好访问的链接,大概的内容是这样的:很多的时候我们在进行查询的时候,总是会以这样的…

机器学习中的7种数据偏见

作者 | Hengtee Lim翻译 | Katie,责编 | 晋兆雨出品 | AI科技大本营头图 | 付费下载于视觉中国机器学习中的数据偏差是一种错误,其中数据集的某些元素比其他元素具有更大的权重和或表示。有偏见的数据集不能准确地表示模型的用例,从而导致结果…

windows7 下arp 绑定的实现

局域网的arp***常常让人头痛,绑定IP/MAC地址是解决方式之一; 在xp下面绑定mac地址很简单,只需“arp -s IP地址 MAC地址 ”就ok, 在win7下的命令有所不同; 首先,需要查看可用网卡的id,使用命令n…

Asp.net(c#)实现多线程断点续传

http://www.cnblogs.com/bestcomy/archive/2004/08/10/31950.html以前一直错误的认为在ASP.NET中无法通过编程方式实现多线程断点续传,今天终于获得了这样一个解决方案,让我明白要学习的东西还很多。此解决方案基于其它解决方案及相关资料,根…

0.7秒完成动漫线稿上色,爱奇艺发布AI上色引擎

出品 | AI科技大本营(ID:rgznai100)中国漫画的需求量在不断增加,而动漫制作成本一直居高不下。究其原因为动漫制作是一个复杂且耗时的过程,需要大量工作人员在不同阶段进行协作。动漫制作过程中,需先创作关键帧草图&am…

Java Web整合开发读书笔记

下载JDK:http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html 下载Eclipse: http://www.eclipse.org/downloads/ 下载Tomcat: http://tomcat.apache.org/download-70.cgi 正则表达式:http://www.cnblogs.com/deerchao…

ListView中CheckBox使用问题

因为CheckBox的点击事件优先级比ListView的高,所以当ListView中使用CheckBox会导致ListView的setOnItemClickListener失去响应。 解决的方法:在CheckBox中加入android:focusable"false"。使得CheckBox初始的时候没有获取焦点。 假设想在单击C…

网页播放的视频代码

网页播放的视频代码 第一种是通过调用window media player进行播放诸如&#xff1a;wmv,asf等格式文件: <object alignmiddle classOBJECT classidCLSID:22d6f312-b0f6-11d0-94ab-0080c74c7e95 height320 idMediaPlayer width356> <param name"ShowStatusBar…

[Ruby] 模块

1. 命名空间模块定义了一个命名空间&#xff0c;方法和常量可以在其中任意使用而不必担心被其他方法或常量干扰&#xff0c;例如&#xff1a;module Testdef Test.method()end end模块常量的命名和类常量一样&#xff0c;都以大写字母开头&#xff0c;方法定义类似于类方法的定…

10个工程师,9个不合格!

如果你想问最近这些年什么编程语言最值得学习&#xff0c;我会毫不犹豫的告诉你是Python。无论是刚入门的程序员&#xff0c;还是年薪BATJ的技术大牛&#xff0c;都无可否认现在Python对于一个程序员职业发展的重要性。所以不仅是开发小白&#xff0c;甚至很多开发老手&#xf…

云计算(2)it 是什么

2015年&#xff0c;全世界在it上面的花费达到3亿8千亿美金之多。 云数据中心&#xff1a;核心基础架构&#xff0c;云计算的物理载体&#xff0c;提供数据处理、存储和高性能计算支撑&#xff0c;包括服务器、存储、冷却、机房空间和能耗管理等。 超大规模的云数据中心&#xf…

大批量生成假数据,faker.js获得近28k个Star

整理 | 夕颜图源 | 视觉中国来源 | CSDN&#xff08;ID:CSDNnews&#xff09;近日&#xff0c;GitHub上一个生成假数据的项目faker.js火了&#xff0c;攀升Trendinging榜单第二&#xff0c;标星目前已超过27.1k。只需要简单几步操作&#xff0c;就可以在浏览器和node.js中生成大…

C++代理类,句柄(智能指针)_C++沉思录笔记

代理类 首先定义三个类: class Animal{ public:virtual void getName()0;virtual void clone()0; };class Cat:public Animal{ public:void getName(){cout<<"this is Cat"<<endl;}Animal* clone(){return new Cat;} };class Dog:public Animal{ public:…

浅析C语言的一个关键字——register

1、register修饰符暗示编译程序相应的变量将被频繁地使用&#xff0c;如果可能的话&#xff0c;应将其保存在CPU的寄存器中&#xff0c;以加快其存储速度。例如下面的内存块拷贝代码&#xff0c; /* Procedure for the assignment of structures, */ /* if the C compiler doe…

《Haskell趣学指南》—— 第1章,第1.2节小朋友的第一个函数

本节书摘来自异步社区《Haskell趣学指南》一书中的第1章&#xff0c;第1.2节小朋友的第一个函数&#xff0c;作者 【斯洛文尼亚】Miran Lipovaca&#xff0c;更多章节内容可以访问云栖社区“异步社区”公众号查看 1.2 小朋友的第一个函数函数的声明与它的调用形式大体相同&…

ASP.NET中利用DataGrid的自定义分页功能和存储过程结合实现高效分页

关键字&#xff1a;DataGrid、存储过程、分页出自&#xff1a; http://blog.csdn.net/yzx110/archive/2004/08/18/78525.aspx摘要&#xff1a;在最进的一个项目中因为一个管理页面要管理的数据量非常大,所以必须分页显示,并且不能用DataGrid的内置分页功能,于是自己实现分页. 下…

看清头秃元凶,腾讯AI首度揭示真相

出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;11月17日&#xff0c;腾讯公布了一项人工智能助力药物发现的新进展。通过腾讯自研的提升蛋白质结构预测精度的新方法&#xff0c;联合研究团队首次解析了II型5a还原酶&#xff08;SRD5A2&#xff09;的三维结构&#x…

UNIX--stat、fstat和lstat函数

2019独角兽企业重金招聘Python工程师标准>>> stat、fstat和lstat函数(UNIX) #include #include int stat(const char *restrict pathname, struct stat *restrict buf); 供给文件姓名&#xff0c;获取文件对应特点。感受通常是文件没有翻开的时分这样操作。 int fst…

UVA 1482 - Playing With Stones(SG打表规律)

UVA 1482 - Playing With Stones 题目链接 题意&#xff1a;给定n堆石头&#xff0c;每次选一堆取至少一个。不超过一半的石子&#xff0c;最后不能取的输&#xff0c;问是否先手必胜 思路&#xff1a;数值非常大。无法直接递推sg函数。打出前30项的sg函数找规律 代码&#xff…

Google和网易有道合作开课了

11月16日&#xff0c;2020年Google开发者大会正式开幕。受疫情影响&#xff0c;本次大会首次以线上形式举办&#xff0c;这也是Google首次以全线上形式与中国开发者相聚。本届大会主题聚焦“代码不止”&#xff0c;其中“学习”成为本次大会重要板块之一。在该主题下&#xff0…

Node.js v0.10版本发布

Node.js研发团队发布了node.js v0.10版本&#xff0c;它是个基于Javascript、用于构建高性能异步服务器的平台。该版本主要更新如下&#xff1a;更易于使用的数据流处理模块&#xff0c;通过域更好地处理错误&#xff0c;此外还带来了性能方面的提升。该团队还宣布在v0.10之后、…

动手扩充FreeTextBox的功能

作者&#xff1a;朱俊代码&#xff1a;C#关键字&#xff1a;FreeTextBox、流媒体出自&#xff1a;http://blog.csdn.net/foxmail/archive/2004/08/21/81096.aspx摘要&#xff1a;最近一个项目要求可以在发表文章的时候能发布电影&#xff0c;当然不可能叫用户去写HTML代码了&am…

《防患未然:实施情报先导的信息安全方法与实践》——3.3 攻击剖析

本节书摘来自华章计算机《防患未然&#xff1a;实施情报先导的信息安全方法与实践》一书中的第3章&#xff0c;第3.3节,作者&#xff1a;[美] 艾伦利斯卡&#xff08;Allan Liska&#xff09; 更多章节内容可以访问云栖社区“华章计算机”公众号查看。 3.3 攻击剖析 为了开发更…