目标检测系列:
目标检测(object detection)系列(一) R-CNN:CNN目标检测的开山之作
目标检测(object detection)系列(二) SPP-Net:让卷积计算可以共享
目标检测(object detection)系列(三) Fast R-CNN:end-to-end的愉快训练
目标检测(object detection)系列(四) Faster R-CNN:有RPN的Fast R-CNN
目标检测(object detection)系列(五) YOLO:目标检测的另一种打开方式
目标检测(object detection)系列(六) SSD:兼顾效率和准确性
目标检测(object detection)系列(七) R-FCN:位置敏感的Faster R-CNN
目标检测(object detection)系列(八) YOLOv2:更好,更快,更强
目标检测(object detection)系列(九) YOLOv3:取百家所长成一家之言
目标检测(object detection)系列(十) FPN:用特征金字塔引入多尺度
目标检测(object detection)系列(十一) RetinaNet:one-stage检测器巅峰之作
目标检测(object detection)系列(十二) CornerNet:anchor free的开端
目标检测扩展系列:
目标检测(object detection)扩展系列(一) Selective Search:选择性搜索算法
目标检测(object detection)扩展系列(二) OHEM:在线难例挖掘
YOLO系列推出了它的第二代算法:YOLOv2,一个“更好,更快,更强”的检测器。╮( ̄▽  ̄)╭
YOLOv2的论文是《YOLO9000: Better, Faster, Stronger》,这里面的YOLO9000是YOLO2的基础上做了,使用检测与分类的联合训练,并根据ImageNet中的WordNet构建WordTree,达到9000类目标检测的目的,但是这部分内容在下面不做介绍了。YOLOv2同样延续了one-stage检测的思路,并在速度和准确性方面都超过了SSD。
一提到YOLOv2对YOLO的改进,一般都会有下面这个图:
但是它更多的是一种trick,比如用更大分辨率的图训练基础分类模型等等,这个东西我们后面再说,个人认为YOLOv2相比于YOLO主要在四个方面有比较大的改进:
上图是YOLOv2的主干网络结构,可以看到YOLOv2有32层。结构还是比较常规的,主要就是在用 3 × 3 3\times3 3×3的卷积, 2 × 2 2\times2 2×2的池化和 1 × 1 1\times1 1×1的卷积。除了上面三个常规操作外,还有reorg和route,其中route在25层和28层,reorg在27层。
YOLO2的主干网络的连接方式可以看下面这个图:
经过一系列的操作,YOLOv2最后输出特征图是 13 × 13 × 125 13\times13\times125 13×13×125,主干网络的部分就结束。
那么这里就有两个问题,为什么最后的输出是 13 × 13 × 125 13\times13\times125 13×13×125?为什么主干网络要做成这么个奇奇怪怪的样子,而不是顺序的一次性下来?
到这里,第一部分提到的四个点,就解释完了三个,还剩下一个archor box。
在SSD和Faster R-CNN中,要预测的边界框中心坐标 ( t x , t y ) (t_{x}, t_{y}) (tx,ty)实际上是一个offset,它表示了预设框与ground truth的偏差,ground truth的中心点是 ( x , y ) (x, y) (x,y),预设框表示为 { x a , y a , w a , h a } \left \{ x_{a}, y_{a},w_{a},h_{a} \right \} {xa,ya,wa,ha},那么 ( t x , t y ) (t_{x}, t_{y}) (tx,ty)可以被计算为:
t x = x − x a w a t_{x}= \frac {x-x_{a}}{w_{a}} tx=wax−xa t y = y − y a h a t_{y}= \frac {y-y_{a}}{h_{a}} ty=hay−ya
这个公式变换一下,当然加减符号不太重要,所以移项之后不变号了:
x = t x w a − x a x= t_{x}w_{a}-x_{a} x=txwa−xa y = t y h a − y a y=t_{y}h_{a}-y_{a} y=tyha−ya
这样来看的话,offset ( t x , t y ) (t_{x}, t_{y}) (tx,ty)有各自的系数 w a w_{a} wa和 h a h_{a} ha,又因为offset是无约束的,offset变化了一个单位,预测值值就要偏离实际值 w a w_{a} wa和 h a h_{a} ha这么多,这会造成优化的困难。为了避免这个问题,YOLOv2在边界框预测上还是沿用YOLO的策略,而没有使用SSD的。
就是预测边界框中心点相对于对应cell左上角位置的相对偏移值,为了将边界框中心点约束在当前cell中,使用sigmoid函数处理偏移值,这样预测的偏移值在(0,1)范围内(每个cell的尺度看做1)。总结来看,根据边界框预测的4个offset { t x , t y , t w , t h } \left \{ t_{x}, t_{y},t_{w},t_{h} \right \} {tx,ty,tw,th},可以按照下列公式计算出ground truth在特征图上的相对值 { b x , b y , b w , b h } \left \{ b_{x}, b_{y},b_{w},b_{h} \right \} {bx,by,bw,bh},注意这个是ground truth在特征图上的相对值,不是 ( x , y , w , h ) (x, y,w,h) (x,y,w,h)。
b x = σ ( t x ) + c x b_{x}= \sigma(t_{x})+c_{x} bx=σ(tx)+cx b y = σ ( t y ) + c y b_{y}= \sigma(t_{y})+c_{y} by=σ(ty)+cy b w = p w e t w b_{w}= p_{w}e^{t_{w}} bw=pwetw b h = p h e t h b_{h}= p_{h}e^{t_{h}} bh=pheth
具体的如下图:
c x c_{x} cx和 c y c_{y} cy是特征图中格子的左上角坐标,这样一来,要预测的 b x b_{x} bx和 b y b_{y} by就被限定到了一个格子里,而 t x t_{x} tx和 t y t_{y} ty被限定到了 ( 0 , 1 ) (0,1) (0,1),所以回归方法去处理这个问题时更加容易。然后还剩下 p w p_{w} pw和 p h p_{h} ph,这两个东西就是YOLOv2的archor。这样ground truth就又被archor重新编码了,只是编码的方式和SSD不同。
YOLOv2在决定anchor的取值的时候,是根据要预测的数据集来的,它事先统计了VOC中的boundingbox的长宽分布情况,选择了5对比较合适anchor,这种统计的方式在论文里称为Dimension Clusters(维度聚类),其实就是个K-means,以聚类个数k为anchor boxs个数,以k个聚类中心box的宽高维度为anchor box的维度。但是使用标准的K-means有一个问题,那就是大的bbox会比小的bbox产生更大的error,哪怕他们离实际的聚类中心更近,所以为了解决这个问题,维度聚类重新设计了距离评价:
d ( b o x , c e n t r o i d ) = 1 − I O U ( b o x , c e n t r o i d ) d\left(box,centroid\right)=1-IOU\left(box,centroid\right) d(box,centroid)=1−IOU(box,centroid)
经过K-means预测之后,它们分别是:
( 1.32210 , 1.73145 ) (1.32210,1.73145) (1.32210,1.73145)
( 3.19275 , 4.00944 ) (3.19275,4.00944) (3.19275,4.00944)
( 5.00587 , 8.09892 ) (5.00587,8.09892) (5.00587,8.09892)
( 9.47112 , 4.84053 ) (9.47112,4.84053) (9.47112,4.84053)
( 11.2364 , 10.0071 ) (11.2364,10.0071) (11.2364,10.0071)
最后这个在特征图上计算出来的bbox是要向原图上映射的,这就是一个对应比例的坐标变换。
YOLOv2最后会对20个class都打分,显然分值最高的那个,就是最后的这个建议框的类别,并拿出该类别的probability。
YOLOv2对于VOC的结构,最后将产生13135的目标,但是一张正常的图片中是不可能有这么多物体的,所以最后需要一个阈值限定这些输出,这个阈值论文中给出的是0.24,那么拿什么值和0.24比较呢?上面我们已经拿出了一个probability,还有一个输出是confidence,比较的就是二者的乘积。
在darknet的官网给出了一个图,说明了如果阈值取的非常小的话,就会是这样:
YOLOv2同样是一个多任务损失,在R-CNN系列中,一般是把分类的回归的加在一起作为最后的loss function的,而在YOLO2中loss function有四项,并且这四项的weight不同,他们分别是: