目标检测系列:
目标检测(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:在线难例挖掘
目标检测(object detection)扩展系列(三) Faster R-CNN,YOLO,SSD,YOLOv2,YOLOv3在损失函数上的区别
前言:目标检测的另一种打开方式
从时间轴上看,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实现
实现思路
对于一个待检测的图像,YOLO会将其平均分成
个格子(grid cell),显然这些格子会铺满整个图像,如果图像某个 目标的中心落在这个格子中,则这个网格就负责预测这个目标。这样一来,目标的类别就确定了,那么对于目标检测任务,还剩下一个bbox框,所以每个格子要预测 B 个 bounding box,每个 bounding box 除了要回归自身的位置(bbox框,四个点)之外,还要附带预测一个 confidence 值。 confidence表示当前这个bounding box里的东西,是物体的置信度。
听起来可能有些混乱,我们从网络输出的角度捋一下,格子有
个,每个格子都要出B个 bounding box, bounding box就有
个,每个bounding box要有4个值表示边界,还要有1个值表示confidence,所以就应该有
个数,但是还没有结束,对于多目标检测任务,还有一个目标的类别,假设有C类,每一个格子负责一个类别,那么输出应该是
,我们把上面两个式子合并下,就应该是:
有了这些输出,YOLO就可以完成目标检测这件事了,当然最后它需要一个阈值,确定最后要留下来的框和目标类别。
那么YOLO具体怎么得到的这些结果呢?我们看下它的网络结构。
YOLO网络结构
上面这个东西,就是YOLO的前向推理结构,首先一个尺寸为
的输入图像,要经过一系列的卷积和全连接层,这个很好理解,最后一层全连接之后的输出
,后面的东西就值得关注了,它做了个reshape,shape是
,因为做的是reshape,所以显然这两个数是相等的。那么为啥偏偏是这个形状呢?
这里面的
,就刚好对应了上一部分中的格子(grid cell),我们一直提到的格子,其实就是特征图上的一个点,又因为平均分布的,映射到原图之后,它就是一个格子。为了后面带公式方便,这里说明下
。
剩下的30是
的形式,也就是
,那么B和C自然就出来了,分别是
,
。
上图中也对5这个数做了说明,1-4表征bbox框,5表示confidence,需要说明的一点是这个框的表征方式,不管是
还是
,要表示一个矩形,总是需要四个数,但是YOLO这两种都没有用,主要是为了后面计算loss。
特别说明,上图来自《YOLO文章详细解读》
- 是bbox的中心相对于单元格的offset
对于上图中蓝色框对应的格子(坐标为
),假设它预测的输出是红色框的bbox,设bbox的中心坐标为
,那么最终预测出来的
是经过归一化处理的,表示的是中心相对于单元格的offset,计算公式如下。其中
是格子的数量,
和
是图片的宽高。
-
是bbox相对于整个图片的比例,做了归一化。
bbox的中心坐标
,以及与格子的offsets,这些设计都在对应之前提到的“如果图像某个目标的中心落在这个格子中,则这个网格就负责预测这个目标”。也就是说YOLO涉及到类别的预测,只与格子有关,与框无关。
至此,YOLO的前向推理过程就说完了。
YOLO与RPN
我们在前言中提到了RPN,这在里就会发现,YOLO和RPN其实很像。
YOLO在最后reshape出来的特征图上输出bbox,类别和confidence,RPN在最后一层卷积特征图上输出bbox和有没有物体的二分类置信度。
只不过YOLO要一次性直接输出结果,所以置信度上不仅仅是有没有物体,还要加上这个bbox与ground truth的IOU:
同样的,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,这样会造成损失变化过大,所以部分选择乘上了系数 ;
- 最后格子有目标时,要做类别的损失。
特别说明,上图来自《YOLO文章详细解读》
YOLO性能评价
我们只关注红框的就好了,DPM现在被比较已经没什么意义了,而Fast R-CNN还带着SS算法。
- YOLO和Faster R-CNN用同样的VGG16主干网络,FPS要快3倍,但是mAP下降了7个点
- YOLO可以做到实时检测的网络,mAP下降的更多,只有63.4,但是FPS达到了45