写在前面:大家好,我是小董。前段时间学业繁忙,好久没更新博客啦。今天结合自己正在做的项目,和大家聊一聊Yolov2网络,以及对我现在正在做的项目做个总结。
相信Yolo网络大家都很熟悉,从V1到V2引入了anchor(我理解中文翻译是先验框,也就是通过kmeans聚类算法,得到与数据集中bbox最接近的五个框,网络由V1的直接预测box坐标,变为预测bbox框相对于anchor的偏移量。一个cell有5个anchor)。V3自己也不是很了解,但据自己看的博客和资料来看,V3和V2实际上差不多,只不过anchor变为了9个,然后kmeans聚类的尺度变为/原图尺度。(v2的尺度为/fmap,这是个极易忽略的地方)(当然,也有很多这里没提到的改进,具体的变化,大家可以看看相关paper.)
网上有很多文章和博客介绍Yolo网络,在这里,我就不再次重述了。接下来总结下整个项目(攥写本文时,项目还没做完,所以本文的意义可能是为后面还未做的工作提供个工作思路):
项目需求:
实现对用户上传数据集的自动训练(Yolov2),并部署在AIOT芯片上。
TODO(目前实现的会画✔,未实现画X)
(✔) 0.使用微软VoTT目标检测标定软件进行数据集标定。(看了网上不少目标检测数据集标定,都是用labelimg这款开源软件进行标定,从而生成xml文件。)为什么使用VoTT进行数据集标定?经过我的使用,它有如下好处:1.可直接生成含有图像数据的TFRecord文件(对使用TF框架的我,真的是福音。同时,这样的数据集打包方式,能够大大减少后期用户上传的数据集目录结构混乱的几率)。2.支持对视频的标定。3.使用非常方便,导致标定速度要比用labelimg快很多。
——
(✔)1.数据集增强。在本项目的背景下,不可能要求用户上传很大的数据集(比如几百MB,几GB的量级),所以数据增强对于提升模型的鲁棒性很重要。这里我才用的平移,增加噪声,旋转,剪切操作。
——
(✔)2.基于K-means聚类算法的anchor(先验框)计算。v2引入了anchor后,让网络收敛得更快了。(为什么会这样?根据我的理解加上生动的例子,就比如你想去城市中的某个建筑,在指路的时候,V1这个人给你提供的帮助是,告诉你这个建筑的经纬度坐标。而V2这个人告诉你的是这个建筑相对于你现在位置的偏移量。显然,V2提供的方式,相比于V1提供的方式对于人脑的计算量更小些。[这个例子可能有些不恰当QAQ])
——
(X)3.loss函数。经过我对Yolo网络的理解,我发现,整个Yolo网络的核心就是它的loss函数,这个loss的计算无疑凝结着yolo网络最精髓的地方。(当然,它也是最需要时间去理解的地方)。相比于滑动窗口实现目标检测,相比于我之前通过opencv获取边缘形态学特征+目标分类而实现的多位手写数字识别(效果:https://www.bilibili.com/video/BV1WE411G7hx)。Yolo的处理速度是真的非常快了。而这个比较快的处理速度,来源于构建yolo的神经网络,这个网络的收敛,又来自于loss计算。所以大家在学习过程中,务必搞清楚loss函数。
——
(✔)4.部署到生产环境中(比如加errorlog,加守护进程等等)
ps:训练过程中还有很多其他操作,这个TODO主要整理比较关键的操作。
个人认为比较重要的细枝末节
1.IOU计算
在Yolov2的loss计算中,每个cell有5个anchor,那么究竟该由哪个anchor来负责预测目标信息呢?答案是采用与GT(ground truth,也就是fmap尺度的box)IOU最大的anchor进行目标信息的预测。在计算时候,不考虑box的坐标位置。将GT和anchor移到同一原点进行计算,注意,参与计算的数值都是归一化后的。
计算过程图示如下:
代码如下:
简单说一下上述代码,首先获得所有anchor的宽度和高度数据,然后根据上面的计算图示,我们要计算A1和A2的面积,假设A1是长宽都比较小的box,那么a1的w和h的值,必定等于anchor和GT中最小的W和最小的H。再把这两个最小的w,h相乘,就得到了交集面积A1。那么A2的处理也是同理了。根据IOU=交集面积/并集面积。可以得到如下公式:IOU=A1/(A1(GT面积)+A2-A1(交集面积))。
注意,如上的A1并不能约去,因为他们的数学意义是不同的。一个为交集面积,一个为GT面积。在如上的情况下,二者的值是相等的。但是在如下的情况下,二者值并不相等: