目标检测论文阅读:YOLOv1-YOLOv3(一)

关于YOLO(You only look once)的大名,想必搞目标检测的应该也是无人不知了。这位github画风新奇,连个人简历也少女心满满的独角兽控推出的三个版本的YOLO不仅速度快得没朋友,performance上也堪称惊艳,这两周就和大家分享下YOLOv1-v3的阅读笔记,这是第一周的部分。

YOLOv1

YOLO整个系列都属于one stages的检测方法,其整体检测框架的思路都是先generate potential bounding boxes,然后在每个proposal boxes上run a classifier……YOLOv1的整体检测步骤非常简单:
1. Resize image
2. 运行卷积神经网络
3. 对每个proposal的结果进行筛选,然后使用NMS生成结果

它的主要特点如下:
1. one stage,网络较浅,速度非常快
2. YOLO是从整个网络的特征图来进行预测的,不会出现two stages那种截取出Roi的情况,因此mistake background patches的几率会比较小
3. YOLO**学习到的是一般化的表示**,可以同时训练在自然图像上却测试在画像上,因此在面对unexpected的输入和new domains时不容易出现性能下降(这里是通过实验证明的,没有说明原因)
4. 但是相对的,YOLO在localize上准确度不好,尤其是对小目标问题

1. Box生成与检测框架

YOLO将整张图像划分为SxS的网格grid,如果某个目标的中心落在了网格内,则该目标最后由该网格预测。每个网格会预测B个Bounding Box和分数……
这里写图片描述
刚开始看这个描述有点一头雾水,后来仔细一想,这个不就是和Faster R-CNN的Anchor特别像吗?(更准确地讲,YOLO的提出应该更早,当时并没有Anchor机制)……所谓的划分成SxS网格,每个网格负责预测一定数量的Bounding Box和分数,其实就是Faster R-CNN得到SxS的feature map,然后在这上面,在map每个cell上都预测一系列的Bounding Box……
但是区别还是有的,主要两点:
1. 每个单元格虽然有多个Bounding Box,但是只预测一个类别而不是针对每个Box预测一个类别
2. 预测Box,除了x,y,w,h外,还有一个score,如果grid负责预测某个object,score就是预测出来的Box和该object的IoU,否则就是0,所以scores其实表征了grid是否含有物体和与物体的重叠度两个概念;在测试的时候,可以直接把score和class probabilities向量相乘作为class-specific confidence sores
作者选的S是7,每个grid预测2个Box,每个Box有x,y,w,h,score5个分数,再加上VOC的20个类别,所以最后是7x7x(2x5+20)大小的矩阵。

YOLO的整体框架入下图所示:
这里写图片描述
该网络受GoogleNet的启发,但是相对于inception模块,它用的是1x1卷积后跟3x3卷积来模仿该模块。输入图像统一resize到448x448,可以看到输出和我们之前的分析是吻合的。

2. Loss函数

我们知道,有了输入输出还需要有个目标loss函数才能用BP算法优化网络,YOLO的Loss函数如下所示:
这里写图片描述
一二行是Box的位置损失函数,三行是包含gt的boxes的scores误差损失,四行是不包含gt的boxes的scores误差损失,最后一行是类别的误差损失。具体符号的含义可以看论文,主要留意的是,这里的类别误差损失是不计算0~B的,也就是不考虑Bounding Box只考虑S*S个grid,因为每个grid只预测一个类别的缘故,有时候也会出现一个grid预测到了多个Box的问题,此时选择scores最大,也就是IoU最大的那个Box来负责预测该目标。
这里有很多权重项,主要是考虑到样本数量的差异等因素来进行量级上的平衡,这里的w和h取根号主要是因为虽然经过归一化,但是作者认为在相同IoU的情况下,大的object的w和h的偏差仍然会较大,因此使用了开根号的方法来进行抑制。

3. 训练与结果

作者先在前20个conv层上接全局池化和fc层,在ImageNet上进行与训练,训练好后,取前20个conv层,补全所有层,新增的层都是随机初始化。除了最后一层使用线性激活函数外,其它层都使用leaky rectified linear activation。
最后的结果如下(以PASCAL VOC2007为例):
这里写图片描述
另外,由于YOLO不容易误检测背景但定位不准,而R-CNN系列恰恰相反,作者尝试着将二者进行了结合,效果很不错。作者也试着用YOLO进行artwork的person detection,效果也很好。
值得一提的是,作者认为YOLO使用整张图像生成Bounding Box并进行预测分类,可以看作也对object之间的关系和object出现位置进行了建模,这一点和R-CNN的RoI思路有很大的区别。

YOLOv2

YOLOv2也有个名字叫YOLO9000,因为作者不仅仅在在YOLOv1的基础上做出了改进,提出了一个state-of-the-art性能的框架,还提出了一种联合不同数据集检测多达9000类数据的方法。一般来说如果说YOLOv2,主要指的还是前者,整篇论文的主要贡献是如下两点;

  1. 提出了很多对YOLO的提升方法,让YOLO在performance和速度上都有了较大的提升
  2. 提出了一种将分类数据集和检测数据集联合训练的方法(例如将ImageNet和COCO联合起来,让网络能检测那些ImageNet中有而COCO中没有的类)
    其实作者起的标题也挺随意的,YOLOv2三个主要部分的标题是Better,Faster和Stronger,分别对应提升YOLO的性能,提升YOLO的速度和联合检测数据集的方法,现在就来说说主要内容,不过感觉很多地方说得都不细,这个作者本身还是太佛系了,很多细节的东西都没有细说,大家主要还是看思想,想要了解更多需要看DarkNet版本的源码。

1. Better

这部分关注的是性能的提升,考虑到之前YOLO的问题,作者的主要关注点是提高定位准确性还有召回率,也引入了一些其它的常见策略。

  1. Batch Normalization:BN层对效果提升还是比较明显的,有空的话希望能探讨一下这个问题,作者这里采用的策略是所有卷积层后面都会跟BN层
  2. High Resolution Classifier:要注意这里并不是提高YOLO网络的输入图像分辨率 ,而是用ImageNet预训练网络模型时候,提高此时的图像分辨率到448x448,然后fine-tune
  3. 网络结构与输入的更改:去掉原来YOLO的一个池化层使得net的分辨率更高,输入大小变为416x416,主要是为了让feature map最后是13x13是奇数,从而中心正好落在一个格子上……关于去掉哪个池化层其实不用太纠结,因为后面作者会提出一个更加快速有效的网络结构
  4. Anchor Boxes机制:不再是每个grid预测一个类别而是每个Box预测一个类别,实现解耦,其它的比如类别和score相乘的操作之类的还是相同的,和我们熟悉的anchor机制一样;
  5. Dimension Clusters:这个是本文比较大的一个亮点,作者认为常规的直接指定Anchor的尺度和比例的方式本质上是hand-crafted特征,于是作者用k-means来对训练集的bbox进行聚类,然后以聚类个数k为anchor boxes的个数,k个聚类的中心Box的宽高维度作为anchor box的维度。具体怎么实现可以看下这个博客:https://blog.csdn.net/hrsstudy/article/details/71173305 作者通过这种策略,用5个anchor就达到了hand-crafted特征9个anchor才能达到的效果(从平均IOU上考虑)
  6. Direct location prediction:作者在YOLO上使用anchor boxes时候,除了anchor的选择,另一个问题就是模型的不稳定性,尤其在训练开始的时候,作者认为这个主要来源是预测目标的形式,于是对预测坐标tx,ty,tw,th也做了修改,不再是直接计算x,y,w,h了,而是计算中间量,换算关系如下图所示,其中tx和ty会经过激活函数激活,被约束到0到1之间,可以看到这个坐标中心偏移是相对grid的左上角而言的;而另一方面,pw和ph是anchor的宽和高:
    这里写图片描述
  7. Fine-Grained Features:这个部分说白了其实就是特征融合,融合了低语义层的信息,来帮助检测小目标物体,融合方式很特别,不是相加,而是把不同语义化程度的层在通道上做连接,融合时候把26x26x512的特征图叠加成13x13x2048的特征图
  8. Multi-Scale Traning: YOLOv2的网络由于去掉了fc层,因此任意输入维度都可以在整个网络上运行,因此作者每经过10个batches就随机选择一个新的输入size,size在32x10,32x11一直到32x19的共10个不同size上随机选取,以增加网络对不同尺度图像的检测能力,规定输入图片的不同尺寸,得到的结果和速度会差别比较大,具体如下图:
    这里写图片描述

2. Faster

这个部分相对来说内容很少,主要内容就一点,网络的改良,一些具体的训练流程不再详细提及。当时VGG-16还是很主流的网络,但是一张224x224分辨率的图像送入该网络,会产生30.69 billion次的浮点数计算。YOLO的网络很简单,也仍然有8.52 billion次操作,而作者提出了一种叫做Darknet-19的网络,大概只有5.58 billion次操作。这个网络每次pooling后都会double卷积的通道数,提取特征后仍然后大量1x1和3x3交替的卷积,最后仍然使用avgpool做预测:
这里写图片描述
至此,YOLOv2的主要内容介绍完毕了,下面介绍作者的将其拓展到9000多个类的方法。

3. Stronger

这个方法其实也适用其它检测框架,但是速度和性能方面有很多要考量的地方,它的作用主要是检测一些没有label的物体类。打个比方,用ImageNet和COCO来训练,COCO数据集中有若干种动物,但是远没有ImageNet的多,比方说现在有个Norfolk terrier的类别,在COCO中没有,在ImageNet中只有分类标签,那么我就可以根据网络在两个数据集中学到的东西,来检测新图像中的Norfolk terrier,虽然我并没有它的检测标签。
但是这种拓展也有局限性,例如检测上文的类别可能是因为COCO中有很多类似的动物,如果是完全没有的衣服帽子这类的,就没办法好好工作了。
这个部分的思路比较简单,如果遇到的是检测标签的图像,就同时反向传播位置和类别损失;如果遇到的是分类标签图像,就只反向传播类别损失。要解决的问题只有一个,标签之间的复杂关系。比如综合后的数据可能同时包含dog和Bedlington terrier种种具有包含与被包含关系的标签。而我们知道,传统的分类使用softmax损失函数,一个重要假设是各个类别是互斥的,即是A类就不能是B类,这种模式显然没办法满足我们目前的需要。作者的思路,是构造一个树,大致结构如下图:
这里写图片描述
主要依据还是不同类别之间的从属关系。例如我们可以看到,cat,dog和fish这些都是animal的类同在animal的结点下。那么,这个树是怎么生成的呢?
首先,对任何一个类别,都有一条到根结点的途径,比如,Persian属于cat,cat属于animal,animal又属于physical object……这样构造了一条树的路径。作者首先是把COCO和ImageNet中的类别都看作互斥的,然后检查每个类别,如果某个类别只有一条路径到根结点,那么就直接添上去;所有添完后,检查那些到根节点有多个路径的类别,为它们每个选择最短的那条路径,最后构成这样一个树。
对于每个结点来说,可以预测条件概率,比如terrier结点,就预测在terrier条件下,分别是Norfolk terrier,Yorkshire terrier和Bedlington terrier等等的概率,如下图所示:
这里写图片描述
很明显,这个时候它们就是各自互斥的关系,可以用softmax了,所以这种树状结构图的损失函数其实是有多个不同节点各自的softmax构成的:
这里写图片描述
要计算某个特定类别的概率只需要从根节点一路乘下来或者看作从该结点一路找到根节点,如图所示:
这里写图片描述
最后一个Pr(physical object)对于包含object的图片来说是1,实际上对于检测任务来说也是需要预测的。这种方法不仅解决了之前说的问题,还有个比较好的地方就是对于一些类别不明的object效果很好,比如一个种类不明的狗,判断成dog的概率很大,不会因为它不是terrier等子类而直接忽略它。沿着根节点向下走置信度最高的分支达到某个阈值,最终预测物体的类别为最后的结点类别(这里没太看明白,是直接达到某个阈值再往下就过了的时候停下,还是一直到最后得到阈值)。
实际使用要根据两个数据集样本量的不同做一下平衡,让它们保持特定的比例,作者还特别减少了anchor的默认数量到3以减少计算量。
最终结果是在ImageNet detection task上取得了19.7的mAP,其中没见过的156个物体的精度是16mAP,笔者也不太清楚这个结果要如何评价,应该还是不错的。以上就是YOLOv2的全部内容了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值