目标检测之YOLO V2 V3

YOLO V2

YOLO V2是在YOLO的基础上,融合了其他一些网络结构的特性(比如:Faster R-CNN的Anchor,GooLeNet的\(1\times1\)卷积核等),进行的升级。其目的是弥补YOLO的两个缺陷:

  • YOLO中的大量的定位错误
  • 和基于区域推荐的目标检测算法相比,YOLO的召回率(Recall)较低。

YOLO V2的目标是:在保持YOLO分类精度的同时,提高目标定位的精度以及召回率。其论文地址:
YOLO 9000:Better,Faster,Stronger

YOLO论文的名称总是如此的直抒胸臆,

  • Better 指的是和YOLO相比,YOLO V2有更好的精度
  • Faster 指的是修改了网络结构,其检测更快
  • Stronger 指的就是YOLO 9000,使用联合训练的方法,同时使用目标检测和图像分类的数据集,训练YOLO V2,训练出来的模型能够实时的识别多达9000种目标,所以也称为YOLO9000。

Better

这部分主要是改进YOLO的两个缺点:

  • 定位不精确
  • 召回率较低(和基于候选区域的方法相比)

YOLO V2种并没有加深或者加宽网络结构,反而简化了网络(faster)。

  • Batch Normalization
    这个是CNN网络通用的方法了,不但能够改善网络的收敛性,而且能够抑制过拟合,有正则化的作用。

  • High Resolution Classifier
    相比图像的分类任务,目标检测需要更高的图像分辨率。而为了提取图像的特征,目标检测网络的提取特征部分,通常要在ImageNet数据集上进行预训练。从AlexNet结构开始,大多数分类的网络的输入图像都小于\(256 \times 256\),在YOLO中,使用\(224 \times 224\)的图像进行预训练,但是在目标检测的网络中使用\(448 \times 448\)的图像进行训练。这样就意味着,从用于分类的特征提取模型切换到目标检测网络,还需要适应这种图像分辨率的改变。
    在YOLO V2中对此进行了改变了,使用ImageNet数据集,首先使用\(224 \times 224\)的分辨率训练160个epochs,然后调整为\(448 \times 448\)在训练10个epochs。

Convolutional With Anchor Boxes

在YOLO中在最后网络的全连接层直接预测目标边框的坐标,在YOLO V2中借鉴 Fast R-CNN中的Anchor的思想。

  • 去掉了YOLO网络的全连接层和最后的池化层,使提取特征的网络能够得到更高分辨率的特征。
  • 使用\(416 \times 416\)代替\(448 \times 448\)作为网络的输入。这是因为希望得到的特征图的尺寸为奇数。奇数大小的宽和高会使得每个特征图在划分cell的时候就只有一个center cell(比如可以划分成77或99个cell,center cell只有一个,如果划分成88或1010的,center cell就有4个)。为什么希望只有一个center cell呢?因为大的object一般会占据图像的中心,所以希望用一个center cell去预测,而不是4个center cell去预测。网络最终将416416的输入变成1313大小的feature map输出,也就是缩小比例为32。(5个池化层,每个池化层将输入的尺寸缩小1/2)。
  • Anchor Boxes 在YOLO中,每个grid cell只预测两个bbox,最终只能预测98个bbox(\(7\times 7\times 2=98\)),而在Faster RCNN在输入大小为\(1000\times 600\)时的boxes数量大概是6000,在SSD300中boxes数量是8732。显然增加box数量是为了提高object的定位准确率。 过少的bbox显然影响了YOLO的定位的精度,在YOLO V2中引入了Anchor Boxes的思想,其预测的bbox则会超过千个(以输出的feature map为\(13 \times 13\)为例,每个grid cell有9个anchor box的话,其预测的bbox数量为\(13 \times 13 \times 9 = 1521\)个)。

Dimension Clusters

YOLO V2中引入了Faster R-CNN思想,但是让大佬单纯的使用别人的想法而不加以改进是不可能的。在Faster R-CNN中每个Anchor box的大小以及形状是预先设定好的,然后在网络种通过边框回归来调整每个Anchor Box的边框。但是,如果开始就选择好的边框(Faster R-CNN中的边框是手工设计的,3种大小,3种形状共9种),那么网络肯定能更好的预测。
YOLO 作者使用据类的思想,对训练集能够生成的所有Anchor box做聚类,以此来找到合适的预设的Anchor box.另外作者发现如果采用标准的k-means(即用欧式距离来衡量差异),在box的尺寸比较大的时候其误差也更大,而我们希望的是误差和box的尺寸没有太大关系。所以通过IOU定义了如下的距离函数,使得误差和box的大小无关,故使用如下的距离度量

\[d ( \text { box, centroid } ) = 1 - \text { IOU } ( \text { box, centroid } ) \]

也就是针对同一个grid cell,其将IOU相近的聚到一起,如下图

左边表示选择不同聚类中心的\(K\)和平均IOU的关系,不同曲线表示两种数据集:2007 VOC 和COCO。 YOLO V2选择了\(K=2\),在模型的复杂度和召回率之间做个平衡。 右边5种紫框和黑色的边框表示两种数据集下,最终聚类选择的5中bbox的形状和大小,从图看出两种数据集的形状类似大小相近。图中也可以看出,一个的大的bbox差不多是正方形,另外3个是高瘦的形状,最后一个则是矮胖的形状,这和Faster R-CNN手动选择的9种形状还是有所不同的。

Direct location prediction

解决了每个Grid Cell生成的bounding box的个数问题,直接按照Faster R-CNN的方法,又遇到了第二个问题:模型不稳定,特别是在早期的迭代中,而这种不稳定是由于预测box的位置\((x,y)\)引起的。在区域推荐的方法中,其网络学习的结果\((tx,ty)\)bbox的中心位置相对于ground truth的中尉\((x,y)\)的平移量,如候选区域的bbox的中心为\((x_p,y_p)\),宽和高为\((w_p,h_p)\),则有如下的等式

\[x = x_p + w_p * tx \\ y = y_p + h_p * ty \]

这种位置的平移是没有任何限制的,例如,\(t_x = 1\),则将bbox在\(x\)轴向右移动\(w_p\)\(t_x = -1\)则将其向左移动\(w_p\)。也是说,不管初始的bbox在图像的什么位置,通过预测偏移量可以将bbox移动到图像的任何位置。对于YOLO V2这种随机初始化bbox的位置,需要训练很久的一段时间才能学习到平移量的合适的值。

基于候选区域的R-CNN 其初始的bbox并不是随机的,而是通过RPN网络生成的。

YOLO V2中没有使用候选区域的直接预测偏移量,而是沿用YOLO的方法,预测位置相对于当前grid cell的偏移量。YOLO V2网络最后输出的特征层为\(13 \times 13\),然后每个cell生成5个bbox,针对每个bbox得到5个值\((t_x,t_y,t_w,t_h,t_o)\)\((t_x,t_y)\)表示bbox中心相对于grid cell左上角的偏移,并且将其平移量限制在一个grid cell内,使用\(sigmoid\)函数处理处理偏移值,将其限制在\((0,1)\)范围内(每个grid cell的尺度看做1)。所以得到下面的公式

\[\begin{aligned} b _ { x } & = \sigma \left( t _ { x } \right) + c _ { x } \\ b _ { y } & = \sigma \left( t _ { y } \right) + c _ { y } \\ b _ { w } & = p _ { w } e ^ { t _ { w } } \\ b _ { h } & = p _ { h } e ^ { t _ { h } } \end{aligned} \]

其中,\((C_x,C_y)\)为当前grid cell相对于图像的左上角的距离,以grid cell的个数为单位。\(p_w,p_h\)为为先验框的宽和高。

如下图,

\((C_x,C_y)\)为当前grid cell相对于图像的左上角的距离,以grid cell为单位,则当前cell的左上角坐标为\((1,1)\);\(p_w,p_h\)为为先验框的宽和高,其值也是相对于特征图的大小,在特征都中每个cell的大小为1。这里记特征图的大小为\((W,H)\)(YOLO V2为\((13,13)\)),这样就可以将边框相对于图像的大小和位置计算出来

\[\begin{aligned} b _ { x } & = (\sigma \left( t _ { x } \right) + c _ { x })/W \\ b _ { y } & = (\sigma \left( t _ { y } \right) + c _ { y })/H \\ b _ { w } & = p _ { w } e ^ { t _ { w } } / W\\ b _ { h } & = p _ { h } e ^ { t _ { h } }/H \end{aligned} \]

在将上面得到的\(b_x,b_y,b_w,b_H\)乘以图像的宽和高(像素为单位)就可以求得边框在图像的位置。

例如,假如预测输出的值\((t_x,t_y,t_w,t_h) = (0.2,0.1,0.2,0.32)\);当前cell的相对于特征图左上角的坐标为\((1,1)\),Anchor box预设的宽和高为\(p_w = 3.19275,p_h = 4.00944\),则有

\[\begin{align*} b_x &= 0.2 + 1 = 1.2 \\ b_y &= 0.1 + 1 = 1.1 \\ b_w &= 3.19275 * e ^ {0.2} = 3.89963 \\ b_h &= 4.00944 * e ^ {0.32} = 5.52151 \end{align*} \]

上面的计算的距离都是相对于\(13 \times 13\)的特征图而言的,其单位为grid cell的边长。 YOLO V2输入的图像尺寸为\(416 \times 416\),则每个grid cell的边长为\(416 / 13 = 32\),将上述位置换算到以像素为单位

\[\begin{align*} b_x &= 1.2 * 32 = 38.4 \\ b_y &= 1.1 * 32 = 35.2 \\ b_w &= 3.89963 * 32 = 124.78 \\ b_h &= 5.52151 * 32 = 176.68 \end{align*} \]

这样就得到了一个在原图上以\((38.4,35.2)\)为中心,宽高为\((124.78,176.68)\)的边框。

Fine-Grained Features

YOLO V2是在\(13 \times 13\)的特征图上做检测,这对于一些大的目标是足够了,但是对于小目标则需要更写细粒度的特征。 Faser R-CNN和SSD都在不同层次的特征图上产生区域建议(SSD直接就可看得出来这一点),获得了多尺度的适应性,YOLO V2则使用了一种不同的方法,添加要给转移层(passthrough layer),该层将浅层的特征图(\(26 \times 26\))连接到最终使用的深层特征度(#13 \times 13$)。

这个转移层有点类似ResNet的dentity mappings结构,将浅层和深层两种不同尺寸的特征连接起来,将\(26 \times 26 \times 512\)的特征图和\(13 \times 13 \times 1024\)的特征图连接起来。passthrough layer,具体来说就是特征重排(不涉及到参数学习),\(26 \times 26 \times 512\)的特征使用按行和按列隔行采样的方法,就可以得到4个新的特征图,维度都是\(13 \times 13 \times 512\)的特征,然后做concat操作,得到\(13 \times 13 \times 2048\)的特征图,将其拼接到后面\(13 \times 13 \times1024\)得到\(13 \times 13 \times 3072\)的特征图,相当于做了一次特征融合,有利于检测小目标。下图是passthrough layer的一个实例

Multi-Scale Training

YOLO中使用\(448\times448\)作为输入,而且由于使用了全连接层,无法改变输入的图像的大小;在 YOLO V2中将全连接层替换为了卷积层,也就是说只有卷积层和池化层,这样就可以处理任意尺寸的图像。为了应对不同尺寸的图像,YOLO V2中在训练的时候使用不同的尺寸图像。

YOLO V2在训练的时候每经过几轮(每经过10epochs)迭代后就会微调网络,随机选择新的图片尺寸。YOLO网络使用的降采样参数为32,那么就使用32的倍数进行尺度\(\{320,352,\cdots,608\}\)。最终最小的尺寸为\(320 \times 320\),最大的尺寸为\(608 \times 608\)

Summary

YOLO V2针对YOLO定位不准确以及召回率低的问题,进行一些改变。 主要是借鉴Faster R-CNN的思想,引入了Anchor box。并且使用k-means的方法,通过聚类得到每个Anchor应该生成的Anchor box的的大小和形状。为了是提取到的特征有更细的粒度,其网络中借鉴ResNet的思想,将浅层的高分辨率特征和深层的特征进行了融合,这样能够更好的检测小的目标。 最后,由于YOLO V2的网络是全卷积网络,能够处理任意尺寸的图像,在训练的时候使用不同尺度的图像,以应对图像尺寸的变换。

Faster

大多数检测网络有赖于VGG-16作为特征提取部分,VGG-16的确是一个强大而准确的分类网络,相应的其计算量也是巨大的。 YOLO V2中使用基于GoogLeNet的网络结构Darknet-19,在损失一些精度的情况下,大大的提高运算速度。

Darknet-19作为YOLO V2的特征提取网络,参考了一些其他的网络结构的经验

  • VGG,使用了较多的\(3\times3\)卷积核,在每一次池化操作后把通道数翻倍。
  • GoogLeNet的network in network的思想,网络使用了全局平均池化(global average pooling),把\(1\times1\)的卷积核置于\(3\times3\)的卷积核之间,用来压缩特征。
  • 使用batch normalization稳定模型训练,抑制过拟合

最终得出的基础模型就是Darknet-19,如下图,其包含19个卷积层、5个最大值池化层(maxpooling layers ),下图展示网络具体结构。Darknet-19在ImageNet图片分类top-1准确率72.9%,top-5准确率91.2%

上述的网络结构是用于ImageNet的预训练网络,其输入的是\(224\times224\)(最后几轮调整为\(448 \times 448\))。在ImageNet预训练完成后,需要调整上面的网络结构:去掉最后的卷积层,添加三个\(3 \times 3 \times 1024\)的卷积层,且在这三个卷积层的每个后面添加\(1 \times 1\)的卷积层。 在检测的时,输入的是\(416 \times 416\),通过了5个池化层的降维,在最后的卷积层 输出的特征为\(13 \times 13 \times 1024\)。 前面提到,为了得到更细粒度的特征,添加了passthrough layer,将浅层的\(26 \times 26 \times 512\)(是输入到最后一个池化层前的特征)融合到最终输出的\(13 \times 13 \times 1024\),作为最终用于检测的特征\(13 \times 13 \3072\)

用于的检测的cell有$13 \times 13 \(,每个cell要生成的5个bbox,每个bbox需要预测其位置和置信度\)(t_x,t_y,t_w,t_h,t_0)$以及其每个类别的概率20个,所以最终输出为\(13 \times 13 \times 5 \times (5 + 20) = 13 \times 13 \times 125\).

Stroner YOLO9000

YOLO9000是在YOLOv2的基础上提出的一种可以检测超过9000个类别的模型,其主要贡献点在于提出了一种分类和检测的联合训练策略。众多周知,检测数据集的标注要比分类数据集打标签繁琐的多,所以ImageNet分类数据集比VOC等检测数据集高出几个数量级。在YOLO中,边界框的预测其实并不依赖于物体的标签,所以YOLO可以实现在分类和检测数据集上的联合训练。对于检测数据集,可以用来学习预测物体的边界框、置信度以及为物体分类,而对于分类数据集可以仅用来学习分类,但是其可以大大扩充模型所能检测的物体种类。

summary

YOLO V2在YOLO主要的改动就是,引入了Anchor box以及修改了其用于特征提取的网络,在检测时去掉了全连接层,整个网络全部使用卷积层。

YOLO V3

YOLO作者对 YOLO V2做了一些小的改动。主要以下两个方面:

  • 使用残差模型,构建更深的特征提取网络
  • 使用FPN架构(Feature Pyramid Networks for Object Detection)来实现多尺度检测

Darkent-53

YOLO V3特征提取网络使用了残差模型,相比YOLO V2使用的Darknet-19,其包含53个卷积层所以称为Darknet-53.其网络结构如下图

Darknet-53在ImageNet数据集上的性能

和ResNet相比,其速度快了很多,精度却相差不大。

多尺度预测

采用FPN架构(Feature Pyramid Networks for Object Detection)来实现多尺度检测,如下图

YOLOv3采用了3个尺度的特征图(当输入为\(416 \times 416\)时):\((13\times 13),(26\times 26),(52\times 52)\),YOLOv3每个位置使用3个先验框,所以使用k-means得到9个先验框,并将其划分到3个尺度特征图上,尺度更大的特征图使用更小的先验框。

summary

大体学习了下YOLO系列的目标检测,但是其中的一些细节还不是很明了,需要结合代码实现了。

posted @ 2019-03-06 02:00  Brook_icv  阅读(4942)  评论(2编辑  收藏  举报