目标检测系列:
目标检测(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(YOLO v1)的提出在R-CNN,SPP-Net,Fast R-CNN和Faster R-CNN之后,论文是《You Only Look Once: Unified, Real-Time Object Detection》,从某种意义上说,YOLO的提出,从另一各方面定义了基于CNN的目标检测任务的基本方法。
通过前面几篇文章,我们知道R-CNN,SPP-Net,Fast R-CNN和Faster R-CNN这四个方法都没有离开一个东西,那就是区域建议(Region Proposal),它们中前三个在用SS算法,Faster R-CNN在用RPN网络。不管形式怎么变,它们都需要产生若干个区域建议框,这些框中存在潜在目标,而后面的任务就是判断框中到底是什么(分类),然后修正这些框(回归)。区域建议的生成工作是第一个阶段,后面的处理是第二个阶段,所以我们把R-CNN形式的目标检测方法称为two-stage。
two-stage的方式实现上其实是有些冗余的,比如RPN做了两件事:
1.1 给出若干个区域建议框;
1.2 给出这个区域建议框内是不是有目标的二分类结果,两个类别的置信度。
RPN之后的网络,又做了两件事:
2.1 回归矫正这个框,让他更接近ground truth;
2.2 对框里的目标,具体确定其类别。
这里有一个很有意思的地方,1.1和2.1都是在做四个值的回归,而2.1和2.2都是在做分类,那么它们一定要分成两步才能完成吗?
显然不是这样,YOLO就把它们整合到了一起,一步完成了目标类别的确定和bbox框的回归任务,所以我们把YOLO称为是one-stage的方法。下面我们具体看下YOLO是如何实现的。
对于一个待检测的图像,YOLO会将其平均分成 k × k k\times k k×k个格子(grid cell),显然这些格子会铺满整个图像,如果图像某个 目标的中心落在这个格子中,则这个网格就负责预测这个目标。这样一来,目标的类别就确定了,那么对于目标检测任务,还剩下一个bbox框,所以每个格子要预测 B 个 bounding box,每个 bounding box 除了要回归自身的位置(bbox框,四个点)之外,还要附带预测一个 confidence 值。 confidence表示当前这个bounding box里的东西,是物体的置信度。
听起来可能有些混乱,我们从网络输出的角度捋一下,格子有 k × k k\times k k×k个,每个格子都要出B个 bounding box, bounding box就有 k × k × B k\times k \times B k×k×B个,每个bounding box要有4个值表示边界,还要有1个值表示confidence,所以就应该有 k × k × B × ( 4 + 1 ) k\times k \times B \times \left(4+1\right) k×k×B×(4+1)个数,但是还没有结束,对于多目标检测任务,还有一个目标的类别,假设有C类,每一个格子负责一个类别,那么输出应该是 k × k × C k\times k \times C k×k×C,我们把上面两个式子合并下,就应该是:
N o = k × k × ( B × ( 4 + 1 ) + C ) N_{o} = k\times k \times \left(B\times \left(4+1\right) + C\right) No=k×k×(B×(4+1)+C)
有了这些输出,YOLO就可以完成目标检测这件事了,当然最后它需要一个阈值,确定最后要留下来的框和目标类别。
那么YOLO具体怎么得到的这些结果呢?我们看下它的网络结构。
上面这个东西,就是YOLO的前向推理结构,首先一个尺寸为 448 × 448 × 3 448\times448\times3 448×448×3的输入图像,要经过一系列的卷积和全连接层,这个很好理解,最后一层全连接之后的输出 1470 × 1 1470\times1 1470×1,后面的东西就值得关注了,它做了个reshape,shape是 7 × 7 × 30 7\times7\times30 7×7×30,因为做的是reshape,所以显然这两个数是相等的。那么为啥偏偏是这个形状呢?
这里面的 7 × 7 7\times7 7×7,就刚好对应了上一部分中的格子(grid cell),我们一直提到的格子,其实就是特征图上的一个点,又因为平均分布的,映射到原图之后,它就是一个格子。为了后面带公式方便,这里说明下 k = 7 k=7 k=7。
剩下的30是 5 + 5 + 20 5+5+20 5+5+20的形式,也就是 5 × 2 + 20 5\times2+20 5×2+20,那么B和C自然就出来了,分别是 B = 2 B=2 B=2, C = 20 C=20 C=20。
上图中也对5这个数做了说明,1-4表征bbox框,5表示confidence,需要说明的一点是这个框的表征方式,不管是 ( l e f t , t o p , r i g h t , b o t t o m ) (left,top,right,bottom) (left,top,right,bottom)还是 ( l e f t , t o p , w i d t h , h e i g h t ) (left,top,width,height) (left,top,width,height),要表示一个矩形,总是需要四个数,但是YOLO这两种都没有用,主要是为了后面计算loss。
特别说明,上图来自《YOLO文章详细解读》
对于上图中蓝色框对应的格子(坐标为 ( x c o l = 1 , y r o w = 4 ) (x_{col}=1,y_{row}=4) (xcol=1,yrow=4)),假设它预测的输出是红色框的bbox,设bbox的中心坐标为 ( x c , y c ) (x_c,y_c) (xc,yc),那么最终预测出来的 ( x , y ) (x,y) (x,y)是经过归一化处理的,表示的是中心相对于单元格的offset,计算公式如下。其中 k k k是格子的数量, w i m g w_{img} wimg和 h i m g h_{img} himg是图片的宽高。
x = x c w i m g k − x c o l x= \frac{x_{c}}{w_{img}}k-x_{col} x=wimgxck−xcol
y = y c h i m g k − y r o w y= \frac{y_{c}}{h_{img}}k-y_{row} y=himgyck−yrow
bbox的中心坐标 ( x c , y c ) (x_c,y_c) (xc,yc),以及与格子的offsets,这些设计都在对应之前提到的“如果图像某个目标的中心落在这个格子中,则这个网格就负责预测这个目标”。也就是说YOLO涉及到类别的预测,只与格子有关,与框无关。
至此,YOLO的前向推理过程就说完了。
我们在前言中提到了RPN,这在里就会发现,YOLO和RPN其实很像。
YOLO在最后reshape出来的特征图上输出bbox,类别和confidence,RPN在最后一层卷积特征图上输出bbox和有没有物体的二分类置信度。
只不过YOLO要一次性直接输出结果,所以置信度上不仅仅是有没有物体,还要加上这个bbox与ground truth的IOU:
P c o n = P r ( O b j e c t ) × I O U p t P_{con}=P_{r}(Object) \times IOU_{p}^{t} Pcon=Pr(Object)×IOUpt
同样的,YOLO的最后一层输出也不得不加上物体的类别。
YOLO这样设计之后,速度会很快,但是同样也带来了很多问题:
YOLO的损失函数有三个,分别是bbox的误差损失,confidence损失和类别损失。
我们只关注红框的就好了,DPM现在被比较已经没什么意义了,而Fast R-CNN还带着SS算法。