目标检测(object detection)系列(五)YOLO:目标检测的另一种打开方式

目标检测(object detection)系列(五)YOLO:目标检测的另一种打开方式_第1张图片
目标检测系列:
目标检测(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实现

实现思路

目标检测(object detection)系列(五)YOLO:目标检测的另一种打开方式_第2张图片
对于一个待检测的图像,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网络结构

目标检测(object detection)系列(五)YOLO:目标检测的另一种打开方式_第3张图片
上面这个东西,就是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。
目标检测(object detection)系列(五)YOLO:目标检测的另一种打开方式_第4张图片
特别说明,上图来自《YOLO文章详细解读》

  • ( x , y ) (x,y) (x,y)是bbox的中心相对于单元格的offset

对于上图中蓝色框对应的格子(坐标为 ( 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=wimgxckxcol
y = y c h i m g k − y r o w y= \frac{y_{c}}{h_{img}}k-y_{row} y=himgyckyrow

  • ( w , h ) (w,h) (w,h)是bbox相对于整个图片的比例,做了归一化。
    w = w b w i m g w= \frac{w_{b}}{w_{img}} w=wimgwb
    h = h b h i m g h= \frac{h_{b}}{h_{img}} h=himghb

bbox的中心坐标 ( x c , y c ) (x_c,y_c) (xc,yc),以及与格子的offsets,这些设计都在对应之前提到的“如果图像某个目标的中心落在这个格子中,则这个网格就负责预测这个目标”。也就是说YOLO涉及到类别的预测,只与格子有关,与框无关。
至此,YOLO的前向推理过程就说完了。

YOLO与RPN

我们在前言中提到了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这样设计之后,速度会很快,但是同样也带来了很多问题:

  • RPN生成1000多个区域建议,哪怕择优选择之后还能剩下300多个,这些区域建议经过ROIPooling之后都会去做“类别”的判断,而YOLO只在每个格子上做类别的判断,只有49个,即便算上每个格子输出2个bbox,一张图也仅仅98个预测,如果图中的物体多了,这显然是不够的,很容易造成误检。
  • YOLO的bbox都在同一层上输出,它们的感受野是相同的,所以YOLO很难去适应各种目标的尺度变化。
  • 小目标经过多次下采样之后,在最后的特征图上就会变得很小,所以YOLO的小目标的检测效果很不好(当然这是个通病)。
  • YOLO的bbox是没有二次矫正的,所以IOU效果也会变成。
    由于上面几个原因,YOLO的效果在比当时的state-of-the-art差很多,但是这不重要,因为YOLO用另一种方式,打开了目标检测。

YOLO损失函数

YOLO的损失函数有三个,分别是bbox的误差损失,confidence损失和类别损失。

  • bbox损失中,如果确定了一个bbox要负责预测,那么要分别计算中心点、宽高与ground truth的L2距离,由于小目标的小偏差造成的损失可能会比大目标的大偏差还要打,所以宽高分别加了根号。
  • confidence损失也由两部分组成,因为如果格子中没有目标,那么这部分会变成0,这样会造成损失变化过大,所以部分选择乘上了系数 λ n o o b j \lambda_{noobj} λnoobj
  • 最后格子有目标时,要做类别的损失。
    目标检测(object detection)系列(五)YOLO:目标检测的另一种打开方式_第5张图片
    特别说明,上图来自《YOLO文章详细解读》

YOLO性能评价

目标检测(object detection)系列(五)YOLO:目标检测的另一种打开方式_第6张图片
我们只关注红框的就好了,DPM现在被比较已经没什么意义了,而Fast R-CNN还带着SS算法。

  • YOLO和Faster R-CNN用同样的VGG16主干网络,FPS要快3倍,但是mAP下降了7个点
  • YOLO可以做到实时检测的网络,mAP下降的更多,只有63.4,但是FPS达到了45

你可能感兴趣的:(deep,learning,#,object,detection)