YOLO V2是在YOLO的基础上,融合了其他一些网络结构的特性(比如:Faster R-CNN的Anchor,GooLeNet的 1 × 1 1\times1 1×1卷积核等),进行的升级。其目的是弥补YOLO的两个缺陷:
YOLO V2的目标是:在保持YOLO分类精度的同时,提高目标定位的精度以及召回率。其论文地址:
YOLO 9000:Better,Faster,Stronger。
YOLO论文的名称总是如此的直抒胸臆,
这部分主要是改进YOLO的两个缺点:
YOLO V2种并没有加深或者加宽网络结构,反而简化了网络(faster)。
Batch Normalization
这个是CNN网络通用的方法了,不但能够改善网络的收敛性,而且能够抑制过拟合,有正则化的作用。
High Resolution Classifier
相比图像的分类任务,目标检测需要更高的图像分辨率。而为了提取图像的特征,目标检测网络的提取特征部分,通常要在ImageNet数据集上进行预训练。从AlexNet结构开始,大多数分类的网络的输入图像都小于 256 × 256 256 \times 256 256×256,在YOLO中,使用 224 × 224 224 \times 224 224×224的图像进行预训练,但是在目标检测的网络中使用 448 × 448 448 \times 448 448×448的图像进行训练。这样就意味着,从用于分类的特征提取模型切换到目标检测网络,还需要适应这种图像分辨率的改变。
在YOLO V2中对此进行了改变了,使用ImageNet数据集,首先使用 224 × 224 224 \times 224 224×224的分辨率训练160个epochs,然后调整为 448 × 448 448 \times 448 448×448在训练10个epochs。
在YOLO中在最后网络的全连接层直接预测目标边框的坐标,在YOLO V2中借鉴 Fast R-CNN中的Anchor的思想。
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 ( box, centroid ) = 1 − IOU ( box, centroid ) d ( \text { box, centroid } ) = 1 - \text { IOU } ( \text { box, centroid } ) d( box, centroid )=1− IOU ( box, centroid )
也就是针对同一个grid cell,其将IOU相近的聚到一起,如下图
左边表示选择不同聚类中心的 K K K和平均IOU的关系,不同曲线表示两种数据集:2007 VOC 和COCO。 YOLO V2选择了 K = 2 K=2 K=2,在模型的复杂度和召回率之间做个平衡。 右边5种紫框和黑色的边框表示两种数据集下,最终聚类选择的5中bbox的形状和大小,从图看出两种数据集的形状类似大小相近。图中也可以看出,一个的大的bbox差不多是正方形,另外3个是高瘦的形状,最后一个则是矮胖的形状,这和Faster R-CNN手动选择的9种形状还是有所不同的。
解决了每个Grid Cell生成的bounding box的个数问题,直接按照Faster R-CNN的方法,又遇到了第二个问题:模型不稳定,特别是在早期的迭代中,而这种不稳定是由于预测box的位置 ( x , y ) (x,y) (x,y)引起的。在区域推荐的方法中,其网络学习的结果 ( t x , t y ) (tx,ty) (tx,ty)bbox的中心位置相对于ground truth的中尉 ( x , y ) (x,y) (x,y)的平移量,如候选区域的bbox的中心为 ( x p , y p ) (x_p,y_p) (xp,yp),宽和高为 ( w p , h p ) (w_p,h_p) (wp,hp),则有如下的等式
x = x p + w p ∗ t x y = y p + h p ∗ t y x = x_p + w_p * tx \\ y = y_p + h_p * ty x=xp+wp∗txy=yp+hp∗ty
这种位置的平移是没有任何限制的,例如, t x = 1 t_x = 1 tx=1,则将bbox在 x x x轴向右移动 w p w_p wp; t x = − 1 t_x = -1 tx=−1则将其向左移动 w p w_p wp。也是说,不管初始的bbox在图像的什么位置,通过预测偏移量可以将bbox移动到图像的任何位置。对于YOLO V2这种随机初始化bbox的位置,需要训练很久的一段时间才能学习到平移量的合适的值。
基于候选区域的R-CNN 其初始的bbox并不是随机的,而是通过RPN网络生成的。
YOLO V2中没有使用候选区域的直接预测偏移量,而是沿用YOLO的方法,预测位置相对于当前grid cell的偏移量。YOLO V2网络最后输出的特征层为 13 × 13 13 \times 13 13×13,然后每个cell生成5个bbox,针对每个bbox得到5个值 ( t x , t y , t w , t h , t o ) (t_x,t_y,t_w,t_h,t_o) (tx,ty,tw,th,to), ( t x , t y ) (t_x,t_y) (tx,ty)表示bbox中心相对于grid cell左上角的偏移,并且将其平移量限制在一个grid cell内,使用 s i g m o i d sigmoid sigmoid函数处理处理偏移值,将其限制在 ( 0 , 1 ) (0,1) (0,1)范围内(每个grid cell的尺度看做1)。所以得到下面的公式
b x = σ ( t x ) + c x b y = σ ( t y ) + c y b w = p w e t w b h = p h e t h \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} bxbybwbh=σ(tx)+cx=σ(ty)+cy=pwetw=pheth
其中, ( C x , C y ) (C_x,C_y) (Cx,Cy)为当前grid cell相对于图像的左上角的距离,以grid cell的个数为单位。 p w , p h p_w,p_h pw,ph为为先验框的宽和高。
如下图,
( C x , C y ) (C_x,C_y) (Cx,Cy)为当前grid cell相对于图像的左上角的距离,以grid cell为单位,则当前cell的左上角坐标为 ( 1 , 1 ) (1,1) (1,1); p w , p h p_w,p_h pw,ph为为先验框的宽和高,其值也是相对于特征图的大小,在特征都中每个cell的大小为1。这里记特征图的大小为 ( W , H ) (W,H) (W,H)(YOLO V2为 ( 13 , 13 ) (13,13) (13,13)),这样就可以将边框相对于图像的大小和位置计算出来
b x = ( σ ( t x ) + c x ) / W b y = ( σ ( t y ) + c y ) / H b w = p w e t w / W b h = p h e t h / H \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} bxbybwbh=(σ(tx)+cx)/W=(σ(ty)+cy)/H=pwetw/W=pheth/H
在将上面得到的 b x , b y , b w , b H b_x,b_y,b_w,b_H bx,by,bw,bH乘以图像的宽和高(像素为单位)就可以求得边框在图像的位置。
例如,假如预测输出的值 ( t x , t y , t w , t h ) = ( 0.2 , 0.1 , 0.2 , 0.32 ) (t_x,t_y,t_w,t_h) = (0.2,0.1,0.2,0.32) (tx,ty,tw,th)=(0.2,0.1,0.2,0.32);当前cell的相对于特征图左上角的坐标为 ( 1 , 1 ) (1,1) (1,1),Anchor box预设的宽和高为 p w = 3.19275 , p h = 4.00944 p_w = 3.19275,p_h = 4.00944 pw=3.19275,ph=4.00944,则有
KaTeX parse error: No such environment: align* at position 8: \begin{̲a̲l̲i̲g̲n̲*̲}̲ b_x &= 0.2 + 1…
上面的计算的距离都是相对于 13 × 13 13 \times 13 13×13的特征图而言的,其单位为grid cell的边长。 YOLO V2输入的图像尺寸为 416 × 416 416 \times 416 416×416,则每个grid cell的边长为 416 / 13 = 32 416 / 13 = 32 416/13=32,将上述位置换算到以像素为单位
KaTeX parse error: No such environment: align* at position 8: \begin{̲a̲l̲i̲g̲n̲*̲}̲ b_x &= 1.2 * 3…
这样就得到了一个在原图上以 ( 38.4 , 35.2 ) (38.4,35.2) (38.4,35.2)为中心,宽高为 ( 124.78 , 176.68 ) (124.78,176.68) (124.78,176.68)的边框。
YOLO V2是在 13 × 13 13 \times 13 13×13的特征图上做检测,这对于一些大的目标是足够了,但是对于小目标则需要更写细粒度的特征。 Faser R-CNN和SSD都在不同层次的特征图上产生区域建议(SSD直接就可看得出来这一点),获得了多尺度的适应性,YOLO V2则使用了一种不同的方法,添加要给转移层(passthrough layer),该层将浅层的特征图( 26 × 26 26 \times 26 26×26)连接到最终使用的深层特征度(#13 \times 13$)。
这个转移层有点类似ResNet的dentity mappings结构,将浅层和深层两种不同尺寸的特征连接起来,将 26 × 26 × 512 26 \times 26 \times 512 26×26×512的特征图和 13 × 13 × 1024 13 \times 13 \times 1024 13×13×1024的特征图连接起来。passthrough layer,具体来说就是特征重排(不涉及到参数学习), 26 × 26 × 512 26 \times 26 \times 512 26×26×512的特征使用按行和按列隔行采样的方法,就可以得到4个新的特征图,维度都是 13 × 13 × 512 13 \times 13 \times 512 13×13×512的特征,然后做concat操作,得到 13 × 13 × 2048 13 \times 13 \times 2048 13×13×2048的特征图,将其拼接到后面 13 × 13 × 1024 13 \times 13 \times1024 13×13×1024得到 13 × 13 × 3072 13 \times 13 \times 3072 13×13×3072的特征图,相当于做了一次特征融合,有利于检测小目标。下图是passthrough layer的一个实例
YOLO中使用 448 × 448 448\times448 448×448作为输入,而且由于使用了全连接层,无法改变输入的图像的大小;在 YOLO V2中将全连接层替换为了卷积层,也就是说只有卷积层和池化层,这样就可以处理任意尺寸的图像。为了应对不同尺寸的图像,YOLO V2中在训练的时候使用不同的尺寸图像。
YOLO V2在训练的时候每经过几轮(每经过10epochs)迭代后就会微调网络,随机选择新的图片尺寸。YOLO网络使用的降采样参数为32,那么就使用32的倍数进行尺度 { 320 , 352 , ⋯ , 608 } \{320,352,\cdots,608\} {320,352,⋯,608}。最终最小的尺寸为 320 × 320 320 \times 320 320×320,最大的尺寸为 608 × 608 608 \times 608 608×608。
YOLO V2针对YOLO定位不准确以及召回率低的问题,进行一些改变。 主要是借鉴Faster R-CNN的思想,引入了Anchor box。并且使用k-means的方法,通过聚类得到每个Anchor应该生成的Anchor box的的大小和形状。为了是提取到的特征有更细的粒度,其网络中借鉴ResNet的思想,将浅层的高分辨率特征和深层的特征进行了融合,这样能够更好的检测小的目标。 最后,由于YOLO V2的网络是全卷积网络,能够处理任意尺寸的图像,在训练的时候使用不同尺度的图像,以应对图像尺寸的变换。
大多数检测网络有赖于VGG-16作为特征提取部分,VGG-16的确是一个强大而准确的分类网络,相应的其计算量也是巨大的。 YOLO V2中使用基于GoogLeNet的网络结构Darknet-19,在损失一些精度的情况下,大大的提高运算速度。
Darknet-19作为YOLO V2的特征提取网络,参考了一些其他的网络结构的经验
最终得出的基础模型就是Darknet-19,如下图,其包含19个卷积层、5个最大值池化层(maxpooling layers ),下图展示网络具体结构。Darknet-19在ImageNet图片分类top-1准确率72.9%,top-5准确率91.2%
上述的网络结构是用于ImageNet的预训练网络,其输入的是 224 × 224 224\times224 224×224(最后几轮调整为 448 × 448 448 \times 448 448×448)。在ImageNet预训练完成后,需要调整上面的网络结构:去掉最后的卷积层,添加三个 3 × 3 × 1024 3 \times 3 \times 1024 3×3×1024的卷积层,且在这三个卷积层的每个后面添加 1 × 1 1 \times 1 1×1的卷积层。 在检测的时,输入的是 416 × 416 416 \times 416 416×416,通过了5个池化层的降维,在最后的卷积层 输出的特征为 13 × 13 × 1024 13 \times 13 \times 1024 13×13×1024。 前面提到,为了得到更细粒度的特征,添加了passthrough layer,将浅层的 26 × 26 × 512 26 \times 26 \times 512 26×26×512(是输入到最后一个池化层前的特征)融合到最终输出的 13 × 13 × 1024 13 \times 13 \times 1024 13×13×1024,作为最终用于检测的特征KaTeX parse error: Expected 'EOF', got '\3' at position 14: 13 \times 13 \̲3̲072。
用于的检测的cell有$13 \times 13 , 每 个 c e l l 要 生 成 的 5 个 b b o x , 每 个 b b o x 需 要 预 测 其 位 置 和 置 信 度 ,每个cell要生成的5个bbox,每个bbox需要预测其位置和置信度 ,每个cell要生成的5个bbox,每个bbox需要预测其位置和置信度(t_x,t_y,t_w,t_h,t_0)$以及其每个类别的概率20个,所以最终输出为 13 × 13 × 5 × ( 5 + 20 ) = 13 × 13 × 125 13 \times 13 \times 5 \times (5 + 20) = 13 \times 13 \times 125 13×13×5×(5+20)=13×13×125.
YOLO9000是在YOLOv2的基础上提出的一种可以检测超过9000个类别的模型,其主要贡献点在于提出了一种分类和检测的联合训练策略。众多周知,检测数据集的标注要比分类数据集打标签繁琐的多,所以ImageNet分类数据集比VOC等检测数据集高出几个数量级。在YOLO中,边界框的预测其实并不依赖于物体的标签,所以YOLO可以实现在分类和检测数据集上的联合训练。对于检测数据集,可以用来学习预测物体的边界框、置信度以及为物体分类,而对于分类数据集可以仅用来学习分类,但是其可以大大扩充模型所能检测的物体种类。
YOLO V2在YOLO主要的改动就是,引入了Anchor box以及修改了其用于特征提取的网络,在检测时去掉了全连接层,整个网络全部使用卷积层。
YOLO作者对 YOLO V2做了一些小的改动。主要以下两个方面:
YOLO V3特征提取网络使用了残差模型,相比YOLO V2使用的Darknet-19,其包含53个卷积层所以称为Darknet-53.其网络结构如下图
和ResNet相比,其速度快了很多,精度却相差不大。
采用FPN架构(Feature Pyramid Networks for Object Detection)来实现多尺度检测,如下图
YOLOv3采用了3个尺度的特征图(当输入为 416 × 416 416 \times 416 416×416时): ( 13 × 13 ) , ( 26 × 26 ) , ( 52 × 52 ) (13\times 13),(26\times 26),(52\times 52) (13×13),(26×26),(52×52),YOLOv3每个位置使用3个先验框,所以使用k-means得到9个先验框,并将其划分到3个尺度特征图上,尺度更大的特征图使用更小的先验框。
大体学习了下YOLO系列的目标检测,但是其中的一些细节还不是很明了,需要结合代码实现了。