YOLO v1请戳博客。
YOLOv2的论文全名为YOLO9000: Better, Faster, Stronger,它斩获了CVPR 2017 Best Paper Honorable Mention。
在这篇文章中,作者首先在YOLOv1的基础上提出了改进的YOLOv2,然后提出了一种检测与分类联合训练方法,使用这种联合训练方法在COCO检测数据集和ImageNet分类数据集上训练出了YOLO9000模型,其可以检测超过9000多类物体。所以,这篇文章其实包含两个模型:YOLOv2和YOLO 9000,不过后者是在前者基础上提出的,两者模型主体结构是一致的。YOLOv2相比YOLOv1做了很多方面的改进,本文我们将主要介绍YOLOv2的改进。
YOLOv2始终是在v1版本上作出的改进,我们先简单回顾YOLOv1的检测步骤:
YOLOv1使用了end-to-end的回归方法,没有region proposal步骤,直接回归便完成了位置和类别的判定(一步到位)。种种原因使得YOLOv1在目标定位上不那么精准,直接导致YOLO的检测精度并不是很高。
先来一个总览图,看看它到底用了多少技巧,以及这些技巧起了多少作用:
CNN在训练过程中网络每层输入的分布一直在改变, 会使训练过程难度加大,但可以通过normalize每层的输入解决这个问题。新的YOLO网络在每一个卷积层后添加batch normalization,通过这一方法,mAP获得了2%的提升。batch normalization 也有助于规范化模型,可以在舍弃dropout优化后依然不会过拟合。
目前大部分的检测模型都会在先在ImageNet分类数据集上预训练模型的主体部分(CNN特征提取器),由于历史原因,ImageNet分类模型基本采用大小为 224 × 224 224 \times 224 224×224的图片作为输入,分辨率相对较低,不利于检测模型。所以YOLOv1在采用 224 × 224 224 \times 224 224×224分类模型预训练后,将分辨率增加至 448 × 448 448 \times 448 448×448,并使用这个高分辨率在检测数据集上finetune。但是直接切换分辨率,检测模型可能难以快速适应高分辨率。所以YOLOv2增加了在ImageNet数据集上使用 448 × 448 448 \times 448 448×448输入来finetune分类网络这一中间过程(10 epochs),这可以使得模型在检测数据集上finetune之前已经适用高分辨率输入。使用高分辨率分类器后,YOLOv2的mAP提升了约4%。
之前的YOLO利用全连接层的数据完成边框的预测,导致丢失较多的空间信息,定位不准。作者在这一版本中借鉴了Faster R-CNN中的anchor思想,回顾一下,anchor是RPN网络中的一个关键步骤,说的是在卷积特征图上进行滑窗操作,每一个中心点都可以预测9种不同大小的anchor。看到YOLOv2的这一借鉴,我只能说SSD的作者是有先见之明的。RPN部分如下图:
为了引入anchor boxes来预测bounding boxes,作者在网络中果断去掉了全连接层。剩下的具体怎么操作呢?首先,作者去掉了后面的一个池化层以确保输出的卷积特征图有更高的分辨率。然后,通过缩减网络,让图片输入分辨率为416 * 416,这一步的目的是为了让后面产生的卷积特征图宽高都为奇数,这样就可以产生一个center cell。作者观察到,大物体通常占据了图像的中间位置, 就可以只用中心的一个cell来预测这些物体的位置,否则就要用中间的4个cell来进行预测,这个技巧可稍稍提升效率。最后,YOLOv2使用了卷积层降采样(factor为32),使得输入卷积网络的416 * 416图片最终得到13 * 13的卷积特征图(416/32=13)。
加入了anchor boxes后,可以预料到的结果是召回率上升,准确率下降。我们来计算一下,假设每个cell预测9个建议框,那么总共会预测13 * 13 * 9 = 1521个boxes,而之前的网络仅仅预测7 * 7 * 2 = 98个boxes。具体数据为:没有anchor boxes,模型recall为81%,mAP为69.5%;加入anchor boxes,模型recall为88%,mAP为69.2%。这样看来,准确率只有小幅度的下降,而召回率则提升了7%,说明可以通过进一步的工作来加强准确率,的确有改进空间。
对于YOLOv1,每个cell都预测2个boxes,每个boxes包含5个值: ( x , y , w , h , c ) (x, y, w, h, c) (x,y,w,h,c) ,前4个值是边界框位置与大小,最后一个值是置信度(confidence scores,包含两部分:含有物体的概率以及预测框与ground truth的IOU)。但是每个cell只预测一套分类概率值(class predictions,其实是置信度下的条件概率值),供2个boxes共享。YOLOv2使用了anchor boxes之后,每个位置的各个anchor box都单独预测一套分类概率值,这和SSD比较类似(但SSD没有预测置信度,而是把background作为一个类别来处理)。
在Faster R-CNN和SSD中,先验框的维度(长和宽)都是手动设定的,带有一定的主观性。如果选取的先验框维度比较合适,那么模型更容易学习,从而做出更好的预测。因此,YOLOv2采用k-means聚类方法对训练集中的边界框做了聚类分析。传统的K-means聚类方法使用的是欧氏距离函数,也就意味着较大的boxes会比较小的boxes产生更多的error,聚类结果可能会偏离。为此,作者采用的评判标准是IOU得分(因为设置先验框的主要目的是为了使得预测框与ground truth的IOU更好),这样的话,error就和box的尺度无关了,最终的距离函数为:
d ( box, centroid ) = 1 − I O U ( box, centroid ) d(\text {box, centroid})=1-I O U(\text {box, centroid}) d(box, centroid)=1−IOU(box, centroid)
作者通过改进的K-means对训练集中的boxes进行了聚类,判别标准是平均IOU得分,聚类结果如下图:
可以看到,平衡复杂度和IOU之后,最终得到k值为5,意味着作者选择了5种大小的box维度来进行定位预测,这与手动精选的box维度不同。结果中扁长的框较少,而瘦高的框更多(这符合行人的特征),这种结论如不通过聚类实验恐怕是发现不了的。
当然,作者也做了实验来对比两种策略的优劣,如下图,使用聚类方法,仅仅5种boxes的召回率就和Faster R-CNN的9种相当。说明K-means方法的引入使得生成的boxes更具有代表性,为后面的检测任务提供了便利。
YOLOv2采用了一个新的基础模型(特征提取器),称为Darknet-19,包括19个卷积层和5个maxpooling层,如下图所示。(其实这个没什么好说的,使用Darknet-19精度没提升,但是计算量下降了1/3)
前面讲到,YOLOv2借鉴RPN网络使用anchor boxes来预测边界框相对先验框的offsets(其实应该叫transformation)。边界框的实际中心位置 ( x , y ) (x, y) (x,y),需要根据预测的坐标偏移值 ( t x , t y ) (t_x, t_y) (tx,ty) ,先验框的尺度 ( w a , h a ) (w_a, h_a) (wa,ha)以及中心坐标 ( x a , y a ) (x_a, y_a) (xa,ya) (特征图每个位置的中心点)来计算:
x = ( t x × w a ) + x a y = ( t y × h a ) + y a \begin{array}{l}{x=\left(t_{x} \times w_{a}\right)+x_{a}} \\ {y=\left(t_{y} \times h_{a}\right)+y_{a}}\end{array} x=(tx×wa)+xay=(ty×ha)+ya
但是上面的公式是无约束的,预测的边界框很容易向任何方向偏移,如当 t x = 1 t_x = 1 tx=1时边界框将向右偏移先验框的一个宽度大小,而当 [公式] 时边界框将向左偏移先验框的一个宽度大小,因此每个位置预测的边界框可以落在图片任何位置,这导致模型的不稳定性,在训练时需要很长时间来预测出正确的offsets。所以,YOLOv2弃用了这种预测方式,而是沿用YOLOv1的方法,就是预测边界框中心点相对于对应cell左上角位置的相对偏移值,为了将边界框中心点约束在当前cell中,使用sigmoid函数处理偏移值,这样预测的偏移值在(0,1)范围内(每个cell的尺度看做1)。总结来看,根据边界框预测的4个offset t x , t y , t w , t h t_x,t_y,t_w,t_h tx,ty,tw,th,可以按如下公式计算出边界框实际位置和大小:
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{array}{c}{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{array} bx=σ(tx)+cxby=σ(ty)+cybw=pwetwbh=pheth
其中 ( c x , c y ) (c_x,c_y) (cx,cy)为cell的左上角坐标,如上图所示,在计算时每个cell的尺度为1,所以当前cell的左上角坐标为 ( 1 , 1 ) (1,1) (1,1)。由于sigmoid函数的处理,边界框的中心位置会约束在当前cell内部,防止偏移过多(及防止某个先验框检测很远的目标box的情况)。而 p w p_w pw和 p h p_h ph是先验框的宽度与长度,前面说过它们的值也是相对于特征图大小的,在特征图中每个cell的长和宽均为1。这里记特征图的大小为 ( W , H ) (W,H) (W,H)(在文中是 ( 13 , 13 ) (13,13) (13,13)),这样我们可以将边界框相对于整张图片的位置和大小计算出来(4个值均在0和1之间):
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{array}{c}{b_{x}=\left(\sigma\left(t_{x}\right)+c_{x}\right) / W} \\ {b_{y}=\left(\sigma\left(t_{y}\right)+c_{y}\right) / H} \\ {b_{w}=p_{w} e^{t_{w}} / W} \\ {b_{h}=p_{h} e^{t_{h}} / H}\end{array} bx=(σ(tx)+cx)/Wby=(σ(ty)+cy)/Hbw=pwetw/Wbh=pheth/H
如果再将上面的4个值分别乘以图片的宽度和长度(像素点值)就可以得到边界框的最终位置和大小了。这就是YOLOv2边界框的整个解码过程。约束了边界框的位置预测值使得模型更容易稳定训练,结合聚类分析得到先验框与这种预测方法,YOLOv2的mAP值提升了约5%。
YOLOv2的输入图片大小为 416 × 416 416 \times 416 416×416 ,经过5次maxpooling之后得到 13 × 13 13 \times 13 13×13大小的特征图,并以此特征图采用卷积做预测。 13 × 13 13 \times 13 13×13大小的特征图对检测大物体是足够了,但是对于小物体还需要更精细的特征图(Fine-Grained Features)。因此SSD使用了多尺度的特征图来分别检测不同大小的物体,前面更精细的特征图可以用来预测小物体。YOLOv2提出了一种passthrough层来利用更精细的特征图。YOLOv2所利用的Fine-Grained Features是 26 × 26 26 \times 26 26×26大小的特征图(最后一个maxpooling层的输入),对于Darknet-19模型来说就是大小为 26 × 26 × 512 26 \times 26 \times 512 26×26×512的特征图。passthrough层与ResNet网络的shortcut类似,以前面更高分辨率的特征图为输入,然后将其连接到后面的低分辨率特征图上。前面的特征图维度是后面的特征图的2倍,passthrough层抽取前面层的每个 2 × 2 2 \times 2 2×2的局部区域,然后将其转化为channel维度,对于 26 × 26 × 512 26 \times 26 \times 512 26×26×512的特征图,经passthrough层处理之后就变成了 13 × 13 × 2048 13 \times 13 \times 2048 13×13×2048的新特征图(特征图大小降低4倍,而channles增加4倍,下图为一个实例),这样就可以与后面的 13 × 13 × 1024 13 \times 13 \times 1024 13×13×1024特征图连接在一起形成 13 × 13 × 3072 13 \times 13 \times 3072 13×13×3072大小的特征图,然后在此特征图基础上卷积做预测。
补充:关于passthrough layer,具体来说就是特征重排(不涉及到参数学习),前面26 * 26 * 512的特征图使用按行和按列隔行采样的方法,就可以得到4个新的特征图,维度都是13 * 13 * 512,然后做concat操作,得到13 * 13 * 2048的特征图,将其拼接到后面的层,相当于做了一次特征融合,有利于检测小目标。
使用Fine-Grained Features之后YOLOv2的性能有1%的提升。
由于YOLOv2模型中只有卷积层和池化层,所以YOLOv2的输入可以不限于 416 × 416 416 \times 416 416×416大小的图片。为了增强模型的鲁棒性,YOLOv2采用了多尺度输入训练策略,具体来说就是在训练过程中每间隔一定的iterations之后改变模型的输入图片大小。由于YOLOv2的下采样总步长为32,输入图片大小选择一系列为32倍数的值: { 320 , 352 , … , 608 } \{320,352, \ldots, 608\} {320,352,…,608},输入图片最小为 320 × 320 320 \times 320 320×320 ,此时对应的特征图大小为 10 × 10 10 \times 10 10×10 (不是奇数了,确实有点尴尬),而输入图片最大为 608 × 608 608 \times 608 608×608 ,对应的特征图大小为 19 × 19 19 \times 19 19×19。在训练过程,每隔10个iterations随机选择一种输入图片大小,然后只需要修改对最后检测层的处理就可以重新训练
采用Multi-Scale Training策略,YOLOv2可以适应不同大小的图片,并且预测出很好的结果。在测试时,YOLOv2可以采用不同大小的图片作为输入,在VOC 2007数据集上的效果如下图所示。可以看到采用较小分辨率时,YOLOv2的mAP值略低,但是速度更快,而采用高分辨输入时,mAP值更高,但是速度略有下降,对于 544 × 544 544 \times 544 544×544 ,mAP高达78.6%。注意,这只是测试时输入图片大小不同,而实际上用的是同一个模型(采用Multi-Scale Training训练)。
总结来看,虽然YOLOv2做了很多改进,但是大部分都是借鉴其它论文的一些技巧,如Faster R-CNN的anchor boxes,YOLOv2采用anchor boxes和卷积做预测,这基本上与SSD模型(单尺度特征图的SSD)非常类似了,而且SSD也是借鉴了Faster R-CNN的RPN网络。从某种意义上来说,YOLOv2和SSD这两个one-stage模型与RPN网络本质上无异,只不过RPN不做类别的预测,只是简单地区分物体与背景。在two-stage方法中,RPN起到的作用是给出region proposals,其实就是作出粗糙的检测,所以另外增加了一个stage,即采用R-CNN网络来进一步提升检测的准确度(包括给出类别预测)。而对于one-stage方法,它们想要一步到位,直接采用“RPN”网络作出精确的预测,要因此要在网络设计上做很多的tricks。YOLOv2的一大创新是采用Multi-Scale Training策略,这样同一个模型其实就可以适应多种大小的图片了。
和YOLOv1一样,对于训练图片中的ground truth,若其中心点落在某个cell内,那么该cell内的5个先验框所对应的边界框负责预测它,具体是哪个边界框预测它,需要在训练中确定,即由那个与ground truth的IOU最大的边界框预测它,而剩余的4个边界框不与该ground truth匹配。YOLOv2同样需要假定每个cell至多含有一个grounth truth,而在实际上基本不会出现多于1个的情况。与ground truth匹配的先验框计算坐标误差、置信度误差(此时target为1)以及分类误差,而其它的边界框只计算置信度误差(此时target为0)。YOLOv2和YOLOv1的损失函数一样,为均方差函数。
损失函数原论文没给,这部分请参考博客。
注:YOLO中一个ground truth只会与一个先验框匹配(IOU值最好的),对于那些IOU值超过一定阈值的先验框,其预测结果就忽略了。这和SSD与RPN网络的处理方式有很大不同,因为它们可以将一个ground truth分配给多个先验框。
YOLO9000是在YOLOv2的基础上提出的一种可以检测超过9000个类别的模型,其主要贡献点在于提出了一种分类和检测的联合训练策略。众多周知,检测数据集的标注要比分类数据集打标签繁琐的多,所以ImageNet分类数据集比VOC等检测数据集高出几个数量级。在YOLO中,边界框的预测其实并不依赖于物体的标签,所以YOLO可以实现在分类和检测数据集上的联合训练。对于检测数据集,可以用来学习预测物体的边界框、置信度以及为物体分类,而对于分类数据集可以仅用来学习分类,但是其可以大大扩充模型所能检测的物体种类。
作者选择在COCO和ImageNet数据集上进行联合训练,但是遇到的第一问题是两者的类别并不是完全互斥的,比如"Norfolk terrier"明显属于"dog",所以作者提出了一种层级分类方法(Hierarchical classification),主要思路是根据各个类别之间的从属关系(根据WordNet)建立一种树结构WordTree,结合COCO和ImageNet建立的WordTree如下图所示:
WordTree中的根节点为"physical object",每个节点的子节点都属于同一子类,可以对它们进行softmax处理。在给出某个类别的预测概率时,需要找到其所在的位置,遍历这个path,然后计算path上各个节点的概率之积。
在训练时,如果是检测样本,按照YOLOv2的loss计算误差,而对于分类样本,只计算分类误差。在预测时,YOLOv2给出的置信度就是 [公式] ,同时会给出边界框位置以及一个树状概率图。在这个概率图中找到概率最高的路径,当达到某一个阈值时停止,就用当前节点表示预测的类别。
过联合训练策略,YOLO9000可以快速检测出超过9000个类别的物体,总体mAP值为19,7%。我觉得这是作者在这篇论文作出的最大的贡献,因为YOLOv2的改进策略亮点并不是很突出,但是YOLO9000算是开创之举。