目标检测之RCNN、Yolo、SSD、RetinaNet与Anchor-Free

1、RCNN系列

1.1 从RCNN到Fast RCNN、Faster RCNN

(1)RCNN(2014)
Object Detection任务主要包含两个内容:识别物体,确定位置。在识别物体这一块,传统的做法是利用特征点来表征物体的类,例如:SIFT,SURF等;在CNN方法出现之后,普遍采用“卷积+池化+全连接”的方式来完成。而对于确定物体的位置,最流行的就是莫过于Region Proposal Regression,在图像中产生一系列的候选框,然后利用回归/分类的方式找到最合适的那个box。基于目标检测中的“识别+定位”任务,RCNN提出了下图所示的方法。目标检测之RCNN、Yolo、SSD、RetinaNet与Anchor-Free_第1张图片
总体而言,RCNN的流程分为三步:

  1. 提取候选区域:这里相当于找到可能存在目标物体的位置,但是只是候选位置,后面会通过一些手段去掉那些不正确的;
  2. 利用CNN计算特征:它的输入就是前一步中找到的候选区域图像,输出的是区域图像的特征向量;
  3. 区域分类与回归:根据区域图像特征向量来判断该候选区域属于哪一类,也有可能是属于背景。

详细来说,在第一步会产生大约2000个左右的 Region Proposal,所使用的方法是 Selective Search(SS,选择性搜索)。在第二步中对 proposal 进行 crop/warp 操作将其处理到固定大小 227*227,以此作为 CNN 的输入;CNN 模型包括5个卷积、2个全连接,由此得到每一个 proposal 的特征,其大小为 4096 维。第三步中分类采取 SVM 方法,将 proposal feature 送入每一类的 SVM 判断它是否属于该类别,它会对该区域所属类别进行打分,利用 NMS 找到那些最有可能的 proposal;起初 proposal 的位置跟 Groundtruth 会有区别,在每一次迭代学习过程中使用 Bounding Box Regression 的方法对其进行修正:构建一个线性回归器,将 region feature 作为输入,计算得到 proposal 在当前位置上的缩放和偏移尺寸,然后进行更新。

Selective Search 是产生Region Proposal的一种方法,和它相同地位的还有:穷举搜索、sliding window等。
SS方法先是通过图像分割的方法得到一个区域集R,该集合中的每一个元素都是原图像在像素级别上的一个segmentation,看起来就跟油画一样是不能够作为Regina Proposal的(有部位上的重叠、包含、遮挡等)。
SS给R的每一个元素套上一个Box,然后计算相邻区域的相似度(基于颜色、纹理、尺寸、形状)得到一个相似度集S,根据S挑选出相似度最高的两个区域 r i 、 r j r_i、r_j rirj;二者合并得到 r t r_t rt 后,将 r t r_t rt 加入集合R,然后把S中与 r i 、 r j r_i、r_j rirj 相关联的部分全部去掉,重新计算 r t r_t rt 与相邻区域的相似度、并加入S;反复迭代,直到S为空。

RCNN的问题在于:

  • Region Proposal 的选取太耗时;
  • 候选区域之间的重叠部分特征相同,但是依然会被作为不同的 proposal 送入CNN进行计算,导致特征提取存在冗余;
  • CNN中的全连接层要求输入特征尺寸相同,因此送入CNN的区域需要通过 crop/warp 操作来固定大小,而这种操作又会让图像变形,降低识别的准确性
  • SS、SVM、边框回归三个部分相互独立,每一步都需要单独训练,耗时且无法实现end-2-end。

之后的SPP-Net(Spatial Pyramid Pooling,作者:何凯明)针对RCNN的第二、三点问题进行改进,它把提取到的 Region Proposal 的位置信息放在CNN卷积之后,让CNN先针对整体图像计算特征,然后将位置信息通过比例映射到整张图的 feature map上提取出候选区域的特征图,这样就不用针对每一个候选区域计算特征图了;其次,取消对 proposal 的 crop/warp 操作,这样 proposal 的大小就各不相同,所以要在全连接之前加入 SPP 层,保证全连接层接收到的特征尺寸不变。

(1)一般我们要求输入CNN的图像尺寸保持一致,实际上这种硬性需求与卷积层无关,而是全连接层的需求。因为卷积层只要指定卷积核大小、步长后,图像多大都无所谓,但是全连接层它要把特征拼接成一个特定维度的向量,如果输入特征尺寸不同那么所需要的参数量也不相同。
(2)SPP全称是Spatial Pyramid Pooling(空间金字塔池化),它加在全连接层之前。具体来说,对于任意一个维度的特征,它将对其做三种分割:4*4、2*2、1*1,依次可以得到16、4、1个网格,然后在这21(在RCNN中,有20个目标类别,外加一个背景类)个网格中分别进行最大池化得到一个一维的值,将这21个值拼接成一个21维向量最为最终输入全连接层的特征。

(2)Fast RCNN(2015)
Fast RCNN借鉴了SPP的思想,在 RCNN 的基础上做出以下改进:

  1. 不再对每个 proposal 做单独的特征提取,而是在整张图像上提取特征,然后按照对应的位置、大小映射到不同的候选区域,避免 Region Proposal 特征的重复计算。
  2. ROI池化:ROI 在这里指的是网格,它借鉴了 SPP 的思想,取消对 proposal 的 crop/warp,直接将区域特征图划分成 H ∗ W H*W HW 个网格(例如 3 ∗ 7 = 21 3*7=21 37=21),然后对每一个网格使用最大池化,这样池化后的特征尺寸就只取决网格划分的方式,而对输入图像尺寸保持不变性。同时它可以进行反向传播,为end-2-end打下基础。
  3. softmax 替代 SVM 做 proposal 的分类,在损失函数中加入 softmax loss,将分类、回归放在一起完成。
  4. 全连接层的计算针对于所有 proposal feature,这是整个 CNN 网络中主要的计算量,为了降低计算复杂度,将全连接层中的权重矩阵进行 SVD(奇异值分解)。

Fast RCNN的整体框架如下图所示,相比较于RCNN而言它弥补了RCNN的很多缺陷,但是仍然采用 selective search 的方法来提取 Region Proposal,这也成为它在速度方面的最大限制。目标检测之RCNN、Yolo、SSD、RetinaNet与Anchor-Free_第2张图片
(3)Faster RCNN(2015)
相比于 Fast RCNN,Faster RCNN 的改变主要在以下两点:

  1. RPN:Region Proposal Network,区域生成网络,以此替代之前一直使用的 selective search 方法,使得候选框的选取速度、精度大大提升。Faster RCNN 可以看做是 RPN+Fast RCNN 的系统,它将训练好的 RPN 模型嵌入到Faster RCNN 中,实现了 RPN 与 Faster RCNN 的权值共享。
  2. Anchor:这个是 RPN 产生 proposal 时所使用的一种策略,CNN 卷积层之后会输出一个 feature map,它的大小随输入图像大小而变化,Faster RCNN 在 feature map 的每个特征点上产生9个固定大小的锚框 anchor,锚框的初始尺寸通过聚类算法从数据集中统计得到,然后让 RPN 对这些锚框进行边框回归,由此得到大量 proposal。

下图给出了 Faster RCNN 的整体框架,其主要改进点落在 RPN,而 RPN 中最富新意的就是锚框Anchor。
目标检测之RCNN、Yolo、SSD、RetinaNet与Anchor-Free_第3张图片
Faster RCNN 网络接受任意尺寸的图像作为输入,通过卷积操作计算得到该图像的feature map,随后将 feature map 输送给 RoI 的同时共享给 RPN。RPN 会先在 feature map 的每一个像素点上产生 9 个固定尺寸大小的锚框 anchor,如上图右上角所示;对于每一个锚框,RPN 会进行两个操作:(1) 利用 softmax 判断锚框所选区域是前景还是背景;(2) 对锚框所选区域内的特征进行边框回归。softmax 给出二分类概率值,边框回归对锚框进行位置偏移得到预测框 x y w h xywh xywh。接着对预测框进行筛选:先利用前景分类概率 foreground score 进行排序,根据 top-k 输出一定数量的预测框;然后将预测框对应的 anchor 在特征图中的位置映射回原始图像,剔除掉那些严重越界的预测框;最后用非极大值抑制 NMS 再次筛选,输出最终的Region Proposal。得到 proposal 以后,后续操作就跟 Fast RCNN 一样了。

RPN 在 Faster RCNN 中独立完成训练,它的训练方法、训练数据、训练过程都是独立的,训练好了之后直接把它嵌入在Faster RCNN中。
在这里插入图片描述

1.2 Mask RCNN(2017)理论基础——论文

Mask RCNN 是何凯明基于 Faster RCNN 模型提出来的一种 Instance Segmentation(实例分割)方法。

Object Detection:目标检测,输出图像中个体的bounding box。
Semantic Segmentation:语义分割,输出像素级别的类归属。
Instance Segmentation:实例分割,输出像素级别的类归属以及类的实体ID,就是给出每一个实例的轮廓。

目标检测之RCNN、Yolo、SSD、RetinaNet与Anchor-Free_第4张图片
上图左边给出了 Mask RCNN 的模型结构,大体上沿袭了 Faster RCNN 的框架思路,不同之处在于:
(1)RoI Align 代替 ROI Pooling
之前 Fast/Faster RCNN 在全连接层之前都采用 RoI Pooling,这可以使得模型能够接受任意尺寸大小的图像作为输入。但是,该方法有两个量化问题:(1) RPN 方法得到的锚框 anchor 需要进行边框回归,回归结果是一个浮点数,在映射到 feature map 上时需要做舍入;(2) 网格的划分直接采用 w / W 、 h / H w/W、h/H w/Wh/H,也需要进行舍入。
这两次量化会直接影响 proposal 的准确性。RoI Align的做法是:回归和网格划分还是照做,但是不再进行舍入,而是在网格(位置大小均是浮点数)内找四个位置固定的虚拟坐标点,这四个点的特征值由网格内的真实特征点根据双线性插值计算得到,然后对这四个虚拟特征点做 max pooling 操作。当然了,不一定非要是4个虚拟特征点,实际上只用网格中心点的双线性插值也可以达到相类似的效果。
目标检测之RCNN、Yolo、SSD、RetinaNet与Anchor-Free_第5张图片
(2)加入 mask 分支
Faster RCNN 在全连接之后通过两个分支分别输出 proposal 的类别和预测位置,Mask RCNN 在此基础上增加一个 mask 分支,该分支利用 FCN 对 proposal 特征图中的每一个像素进行分类。原始的 FCN 中用的是 softmax 和交叉熵,Mask RCNN 为了避免同类间的竞争,采用了 sigmoid,并对每个 proposal 区域输出 k ∗ m ∗ m k*m*m kmm 维度的mask, k k k 是类别数量, m m m 就是 proposal 经过 RoI Align 得到的特征图的尺寸,将特征图的点映射回原始图像,就能得到原始图每个像素点的类别。因为该分支输出了针对每一类的 mask,这样就不涉及像素之间的类别竞争。要注意的是, L m a s k L_{mask} Lmask 在计算时只针对 proposal 所属的第 k k k 类,其他类 mask 不参与损失函数计算。

关于FCN:
(1)FCN是Semantic Segmentation的里程碑之作,它对图像进行像素级的分类,解决了语义级别的图像分割。
(2)FCN不包含全连接层,只有卷积层,在最后一个卷积层的后面接一个反卷积层,将feature map还原到原始图像尺寸大小,对每一个像素进行预测,最后逐像素求softmax损失,这就相当于每一个像素就是一个样本。

Mask RCNN 的特征提取网络使用的是 ResNet101,同时文章也给出 FPN 的同等对比方案,因为 FPN 能融合不同尺度上的特征,所以它能提炼更加丰富的上下文信息。

关于FPN:
一般的特征预测可以有三种形式:(1)采用网络最后一层的特征预测,典型的有SPP、Fast/er RCNN;(2)图像金字塔,每一种图像尺寸进行一次特征预测;(3)多尺度融合,每一层特征进行一次预测,不同层之间没有联系,典型的有SSD。
FPN(Feature Pyramid Network),特征金字塔网络,顶层特征通过上采样和底层特征进行融合,层与层之间有相互联系。

1.3 Mask RCNN的实现与效果

Mask RCNN的Tensorflow版本开源下载地址。
代码写的很清晰、很整洁,不管能不能理解原理,先让它跑起来再说,看一下结果。目标检测之RCNN、Yolo、SSD、RetinaNet与Anchor-Free_第6张图片
此项目依赖于COCO,其配置方式为:

  1. 下载COCO项目:git clone https://github.com/pdollar/coco
  2. 编译Python API:cd coco/PythonAPI >>> make -j8
  3. 复制coco/PythonAPI/pycocotools文件夹到samples/coco中(和coco.py同级目录)

Mask RCNN的官方源码在Detectron,Detectron是Facebook的开源物体检测平台,它基于Caffe2、用Python写成。除了Mask RCNN的实现之外,Detectron还包含了ICCV 2017最佳学生论文RetinaNet,Ross Girshick 此前的研究Faster R-CNN和RPN、Fast R-CNN、以及R-FCN的实现。

1.4 Mask RCNN的后续进展

Mask RCNN的出世时间是2017年,到目前为止它依然是相当强悍的目标检测方法之一,当然也不乏超越它的作品。

  1. 2017年,旷视提出Light-head RCNN,它在性能上超越了Mask RCNN,在模型使用更小的网络时其效率更是超过Yolo和SSD。它这里的“head”指的是Fast RCNN进行RoI Pooling之后的分类/回归网络部分,文章旨在对这一部分进行优化,针对该部分提出了性能更好的RCNN-subnet,优化了计算、降低了复杂度。
  2. Reasoning-RCNN:Faster RCNN是一种常用的物体检测模型,然而,当检测类的数量小于100时,物体检测是最成功的。Reasoning-RCNN 针对具有数千个类别的大规模物体检测问题,提出了一种基于长尾数据分布、重遮挡和类模糊的目标检测方法。该模型在3个主要数据集上进行训练和评估——Visual Gnome(3000个类别)、ADE(445个类别)和COCO(80个类别)。该模型能够在Visual Gnome上获得16%的提升,在ADE上获得37%的提升,在COCO上获得15%的提升。

2、Yolo系列

RCNN 系列属于目标检测中 2-stage 方法的代表作品,之所以称为 2-stage 是因为它们需要先通过一类算法找到图像中的候选区域 Region Proposal,然后再利用另外一类算法对这些区域进行分类、回归,完成目标检测问题中的识别与定位。该方法的 pipeline 需要多个独立的部分,每一部分需要单独数据集、单独训练,过程较为繁琐且无法实现端到端的训练。
针对 2-stage 的问题,YOLO 提出 1-stage 的目标检测方法:Fast RCNN 主要的改进不是将 proposal 进行网格划分嘛,YOLO 将这种思想直接应用到原始图像上,那就不需要做生成 proposal 的工作了呀!所以,YOLO 将 proposal生成、分类、回归放到一个模型中统一完成,在速度上有相当的优势,虽然精度有所降低,但是随着版本的进化也相应的有所改善。

2.1 从Yolo v1到Yolo v2

(1)Yolo(2015)
Yolo使用最直观的求解思路,对于输入的完整图像,经过一个网络直接给出每一个目标物体的位置bbox、所属类别,它的思路设计可以概括为以下几步:

  1. 将图像分割成一个 S ∗ S S*S SS 的网格:;
  2. 每一个网格给出 B B B 个 bbox,每个 bbox 包含五个输出值:中心点坐标+尺寸 ( x , y , w , h ) (x,y,w,h) (x,y,w,h) ,置信度 c o n f i d e n c e confidence confidence
  3. 每一个网格还给出它属于每一类的概率 P r ( C l a s s i ∣ O b j e c t ) Pr(Class_i|Object) Pr(ClassiObject)
  4. 对 2、3 的输出结果进行 NMS 处理,依此给出整张图的目标物体的位置、类别。

下图是Yolo的流程图:目标检测之RCNN、Yolo、SSD、RetinaNet与Anchor-Free_第7张图片
为什么可以直接在原始图像上划分网格?Faster RCNN 在特征图的每个特征点上生成 anchor,如果把这些特征点映射回原始图像其实也就是一个个的网格,YOLO 相当于直接把特征点映射回去了,希望通过原始图像上的网格直接产生对目标物体的预测。
在开始训练之前,要为图像的每个网格打上标签,生成标签的做法是:根据真实的目标框所在位置,判断它落在哪个网格内,包含目标框中心点的网格会被赋予有效的 label(真实类别,真实边框)。 对于需要网络预测的 bbox,它的表达形式为 ( x , y , w , h ) (x,y,w,h) (x,y,w,h),前两个参数给出 bbox 的中心相对于该网格左上角的所在位置,后两个参数给出了 bbox 相对于全图的大小尺寸,它们的值都被归一化到 0~1。网络最终的输出形式是 ( 7 , 7 , 30 ) (7,7,30) (7,7,30),因为原始图像被划分成 S ∗ S = 7 ∗ 7 S*S=7*7 SS=77 个网格,每一个网格有 B = 2 B=2 B=2 个 bbox 预测,每个预测框有5个位置参数 、 C = 20 C=20 C=20 个类别参数,所以最终特征正尺寸是 7*7,通道数量是 5*2+20=30。根据此输出值,计算 bbox 的所属类概率 c o n f i d e n c e ∗ P r ( C l a s s i ∣ O b j e c t ) confidence * Pr(Class_i|Object) confidencePr(ClassiObject) 也就是 bbox 的置信度乘以它所在网格类概率。虽然每个网格都能计算这样一个值,但是只有在前面的 label 标签中包含目标框中心点的网格才有资格作为预测值,参与到后续loss计算。具体来看看损失函数: λ  coord  ∑ i = 0 S 2 ∑ j = 0 B I i j  obj  [ ( x i − x ^ i ) 2 + ( y i − y ^ i ) 2 ] + λ  coord  ∑ i = 0 S 2 ∑ j = 0 B I i j obj [ ( w i − w ^ i ) 2 + ( h i − h ^ i ) 2 ] + ∑ i = 0 S 2 ∑ j = 0 B I i j o b j ( C i − C ^ i ) 2 + λ n o o b j ∑ i = 0 S 2 ∑ j = 0 B I i j n o o b j ( C i − C ^ i ) 2 + ∑ i = 0 S 2 I i o b j ∑ c ∈ classes ( p i ( c ) − p ^ i ( c ) ) 2 \begin{array}{l} {\lambda_{\text { coord }} \displaystyle\sum_{i=0}^{S^{2}} \sum_{j=0}^{B} \mathbb{I}_{i j}^{\text { obj }}\left[\left(x_{i}-\hat{x}_{i}\right)^{2}+\left(y_{i}-\hat{y}_{i}\right)^{2}\right]} \\ +\lambda_{\text { coord }} \displaystyle\sum_{i=0}^{S^{2}} \sum_{j=0}^{B} \mathbb{I}_{i j}^{\text {obj}} \left[\left(\sqrt{w_i}-\sqrt{\hat{w}_{i}}\right)^{2}+ \left(\sqrt{h_i}-\sqrt{\hat{h}_{i}}\right)^{2} \right]\\ +\displaystyle\sum_{i=0}^{S^{2}} \sum_{j=0}^{B} \mathbb{I}_{i j}^{\mathrm{obj}}\left(C_{i}-\hat{C}_{i}\right)^{2} \\ +\lambda_{\mathrm{noob} j} \displaystyle \sum_{i=0}^{S^{2}} \sum_{j=0}^{B} \mathbb{I}_{i j}^{\mathrm{noobj}}\left(C_{i}-\hat{C}_{i}\right)^{2} \\ +\displaystyle\sum_{i=0}^{S^{2}} \mathbb{I}_{i}^{\mathrm{obj}} \sum_{c\in\text {classes}}\left({p_{i}(c)-\hat{p}_{i}(c)}\right)^{2} \end{array} λ coord i=0S2j=0BIij obj [(xix^i)2+(yiy^i)2]+λ coord i=0S2j=0BIijobj[(wi w^i )2+(hi h^i )2]+i=0S2j=0BIijobj(CiC^i)2+λnoobji=0S2j=0BIijnoobj(CiC^i)2+i=0S2Iiobjcclasses(pi(c)p^i(c))2第一部分计算的是包含物体中心的网格的 bbox 中心位置损失,这里只会计算与 GroundTruth 交并比最大的那个 bbox,虽然给的 j j j 值是0~B,但是后面的计算只与 i i i 有关,说明只有一个bbox参与计算。具体是哪一个 bbox,由 I i j obj \mathbb{I}_{i j}^{\text {obj}} Iijobj 计算得到,它给出了根据 I O U IOU IOU 选择 bbox 的数学表示。
第二部分计算的是尺寸损失,大物体与小物体同时偏离一个尺寸带来的误差是不同的,这里为了减小这种尺度大小带来的影响,将 w / h w/h w/h 进行开方然后计算损失。
第三部分计算的是置信度损失,与前两部分相比这一部分没有系数 λ coord \lambda_{\text {coord}} λcoord,原因是 bbox 位置信息与置信度信息维度不同、重要性不同,如果将它们同等对待处理显然不合理,为了突出 bbox 损失故在其前面加入系数 λ coord = 5 {\lambda_{\text{coord}}}=5 λcoord=5
第四部分计算的是不包含物体中心的网格置信度损失 I i j noobj \mathbb{I}_{i j}^{\text {noobj}} Iijnoobj 负责教会模型判断哪些网格不包含物体中心,系数 λ noobj = 0.5 {\lambda_{\text{noobj}}}=0.5 λnoobj=0.5 弱化这类网格的影响。
第五部分计算的是分类损失,它与bbox是无关的,所以判别参数是 I i obj \mathbb{I}_{i}^{\text {obj}} Iiobj,且与置信度同等重要。

(1)包含物体中心的网格:需要计算分类loss,两个predictor都要计算置信度loss(系数不同),预测的bbox与ground truth IOU比较大的那个predictor需要计算位置、尺寸loss。
(2)不包含物体中心的网格:只需要计算置信度loss。

目标检测之RCNN、Yolo、SSD、RetinaNet与Anchor-Free_第8张图片
上图是Yolo的网络结构,对于卷积层的参数先用 ImageNet 做分类预训练,预训练输入图像尺寸为 224*224,之后进行检测训练时将输入图像尺寸改为 448*448(为什么要这样做?)。
RCNN 系列的边框回归是在 proposal/anchor 上进行的,而 YOLO 没有做边框回归,它直接输出 bbox 的中心位置、尺寸大小,中心点针对网格左上角,尺寸大小是相对于全图而言,如果要类比的话可以认为这里的网格就相当于 RCNN 系列中 的 anchor,不准确哈!YOLO 的不足在于:一个网格最终只有一个目标物体的输出,这导致它对那些尺寸较小或者比较拥挤的目标的检测不是很准确。

(2)Yolo v2(2017)
Yolo-v2对Yolo进行了多方面的改进。

  1. BatchNormal的使用:BN 首次出现是在2015年的Inception v2,但是在2016年的 Yolo 中并未使用,Yolo-v2 加入此部分,使得mAP获得了2%的提升,同时去掉了 dropout 也不会产生过拟合;
  2. 高分辨率分类器:Yolo 在预训练分类器时使用 224*224 图像,在检测时使用448*448图像,这使得网络需要重新适应新的输入图像尺寸,Yolo-v2 则直接采用448*448 分辨率图像(还是ImageNet数据库)来做预训练,将mAP提高4%;
  3. 卷积联合Anchor:Yolo-v2 借鉴Faster-RCNN 的 Anchor 方法,在 Yolo 中是通过两个全连接层得到 7*7*30 的输出,这里直接将全连接层去掉,然后调整卷积网络的池化层,将输入图像改为 416*416,确保卷积网络的最终输出是一个13*13 的 feature map,然后在每一个特征点上产生 Anchors;Yolo 一个网格只会预测一个物体,而 Yolo-v2 每一个 Anchor 都可能检测到一个物体。这样的操作会稍微降低mAP(69.5%→69.2%),但是 Recall 从81%上升到88%,说明可检测到的内容大大提升了(漏检率降低)。
  4. 维度聚类:这里指的是调整对 Anchor 尺寸的选择,Faster-RCNN 中Anchor 是人为指定的(具体为什么是这个尺寸全来自于经验),Yolo-v2 采用K-means 聚类的方法对训练集进行分析,为的就是找到最优的 k k k 值以及最适合的Anchors。最终确定下来 k = 5 k=5 k=5 是比较合适的,这样 bbox 的数量由 Yolo 的 7*7*2=98 上升到 13*13*5=845。
    对于两个数据集,5个先验框的width和height如下:
    COCO: (0.57273, 0.677385), (1.87446, 2.06253), (3.33843, 5.47434), (7.88282, 3.52778), (9.77052, 9.16828)
    VOC: (1.3221, 1.73145), (3.19275, 4.00944), (5.05587, 8.09892), (9.47112, 4.84053), (11.2364, 10.0071)
    
  5. 直接位置预测:Yolo 中模型直接给出 bbox 的中心坐标位置、尺寸,这在一定程度上会导致模型的不稳定(具体原因可以对比一下RCNN的边框回归,为什么RCNN边框回归的时候不是直接输出坐标值而要进行转换?)。Yolo-v2 效仿 RPN 网络中对 bbox 回归的形式,从网络输出到最终真实bbox的映射定义为 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 Pr ⁡ (  Object  ) ∗ I O U ( b ,  Object  ) = σ ( t o ) \begin{aligned}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}} \\ \operatorname{Pr}(\text { Object }) * I O U(b, \text { Object }) &=\sigma\left(t_{o}\right) \end{aligned} bxbybwbhPr( Object )IOU(b, Object )=σ(tx)+cx=σ(ty)+cy=pwetw=pheth=σ(to)这里, t x 、 t y t_x、t_y txty 是相对于 c x 、 c y c_x、c_y cxcy 的offset, c x 、 c y c_x、c_y cxcy 是anchor所在网格相对于图像左上角的位置; t w 、 t h t_w、t_h twth 是相对于 p w 、 p h p_w、p_h pwph 的offset, p w 、 p h p_w、p_h pwph 是先验 anchor 的尺寸(这就体现了先验 anchor 的作用); σ \sigma σ 指的就是激活函数,模型通过学习得到 t x 、 t y 、 t w 、 t h 、 t o t_x、t_y、t_w、t_h、t_o txtytwthto。也就是说,在人工标记 label 的时候需要按照 13*13 网格的方式把 GroundTruth 转化成这种形式。激活函数将位置和置信度参数限定在0~1之间,也就是只在网格附近做预测。维度聚类和直接位置预测使得 Yolo-v2 的mAP值上升了5%。
  6. 细粒度特征:Faster-RCNN 和 SSD 中将不同层次上的特征图进行融合,使得模型可以适应对小物体的检测;Yolo-v2 照此添加一个“透层”,类似于 ResNet 的操作,将 26*26*516 的上层特征变为 13*13*2048(特征大小变为1/4,通道数变为4倍),然后与最后的卷积输出 13*13*1024 特征连接,得到 13*13*3072 特征图。如此一来,大尺度特征图连接到小尺度,在进行池化操作的时候,一些细节特征、小目标物体就不会被轻易丢掉,这对于小目标物体的检测是有积极效果的,最终该操作可以使mAP提升1%。
  7. 多尺度训练:Yolo-v2 可以适应不同分辨率的输入图像,其做法是:在训练的时候每迭代一定次数(10个epoch),就换不同的输入尺寸(320~608,以32为等差)。网络进行了5次 max pooling,当输入图片大小为320*320时,最终特征图大小就是10*10;当输入图片大小为608*608时,最终特征图大小就是19*19。

Yolo 使用 GoogLeNet 作为basebone,Yolo-v2 则提出自己的网络结构Darknet-19:
目标检测之RCNN、Yolo、SSD、RetinaNet与Anchor-Free_第9张图片
为什么第一层卷积的输出是224*224?实际上,这并不是最终的检测模型的输入尺寸,整个Yolo-v2的训练分三个阶段:

  1. 预训练阶段:在 ImageNet 分类数据集上从头训练 Darknet-19,图像大小是224*224,总共160个 epoch。
  2. fine-tuning 阶段:在第一阶段的基础上将输入图像调整为448*448,训练10个epoch,这里除了 epoch 和学习率进行调整以外其他参数均不变。
  3. 检测训练阶段:将 Darknet-19 分类模型修改为检测模型(去掉最后一个1000通道的1*1卷积层以及 Avgpool、Softmax层,添加3个 1024 通道的 3*3 卷积层,每个卷积后面接上一个1*1卷积),检测数据集用的是VOC和COCO。

前两个阶段其实都是分类预训练,为的是让 Darknet-19 拥有较好的分辨能力;第三阶段才是目标检测,使用的数据集也改成了COCO、VOC-2007。
Yolo-v2 中每个网格有5个 bbox,每个 bbox 有4个坐标值、1个置信度值、20个类别概率值,因此一个网格需要5*(4+1+20)=125个 filters。Yolo中一个网格有2个bbox,这两个bbox共享一个类别概率,Yolo-v2中则是每一个bbox都有一个属于自己的类别概率。
Yolo-v2的细节很多,论文中只给了最为突出的部分,要了解所有的细节还是需要对源码进行剖析。Yolo-v2的损失函数可以参考这里。

这里所说的网格其实是最后特征图上的一个点,但是映射回原图可以看做是一个网格

(Yolo9000的部分有待补充!)

2.2 Yolo v3(2018)

Yolo-v3 论文比 Yolo-v2 还要随意,具体优化内容主要有:

  1. bbox的预测:基本上还是沿用 Yolo-v2 那一套(对 anchor 的offset),但是 Yolo-v3 使用逻辑回归对每一个框打分,该分数用于选取与 GroundTruth 最为契合的 bbox(之前使用 IOU 最大的bbox),被舍弃掉的 bbox 将只会参与置信度损失的计算。
  2. 分类预测:Yolo-v2 对于分类使用的是softmax,得到一个20维的向量;Yolo-v3 改变这一做法,它使用多个逻辑分类器,每一个分类器用来判断 bbox 是否属于一个类,然后用二元交叉熵计算损失。这样做的好处是,可以应对 Open Images Dataset 这样的一个物体同时属于多个类的情况。
  3. 多尺度预测:Yolo-v3 效仿 FPN 的多级特征金字塔,通过上采样和 concat 大尺度特征,可以生成除 13*13 以外的 26*26、52*52 特征图,特征图的每一个特征点拥有3个 anchor,每一个 anchor 拥有4个 offset 数据、1个置信度、80个类别信息。这些 anchor 同样通过 K-means 来获得,只是 k = 9 k=9 k=9,然后均分给多尺度的每一层。文章给出 416*416 尺度下图像的 anchor 尺寸:
    (10×13)、(16×30)、(33×23)、(30×61)、(62×45)、(59×119)、(116 × 90)、(156 × 198)、(373 × 326)
    
  4. 特征提取:Yolo-v2 中使用了一个“透层”将 26*26 的特征图连接到 13*13 的特征图上,这有点类似于ResNet的残差思想;Yolo-v3 直接加入残差块,去掉池化的同时增加卷积的步长,保证输入图像经过5次下采样,由此诞生了Darknet-53。目标检测之RCNN、Yolo、SSD、RetinaNet与Anchor-Free_第10张图片
2.3 Yolo v3的实现与效果

作为工程项目来说,Yolo-v3的检测效果应该是相当不错的,这里我们不去讨论mAP、COCO数据集上的表现等刷分用的参数,就仅仅看它在实际应用中的performance,速度、精度都很令人满意。重要的是,Yolo-v3开源代码的使用极其简单,即便是看源码、根据自己的需求修改源码都很方便(主要是代码写得很清晰)。参考Tensorflow版本的项目,得到下图结果。

2.4 Yolo v3的后续进展

Tiny Yolo
Yolo Nano
Gaussian YOLOv3
YOLO-v4

3、SSD

3.1 SSD的理论基础——论文

SSD(Single Shot MultiBox Detector)发表于2015年,Faster RCNN 和 Yolo 之后的作品,它也属于目标检测的 1-stage 范畴,同时借鉴了OverFeat、SPP、Fast RCNN、Yolo、Faster RCNN 的一些思想。SSD 由一个 base network 和6个卷积特征层构成,base network 是自VGG-16改造来的,6个卷积特征层分别输出不同尺寸的特征。
目标检测之RCNN、Yolo、SSD、RetinaNet与Anchor-Free_第11张图片
SSD 的网络结构图还是很清晰的,它和 YOLO 的区别就在于:YOLO 只利用到最后一层特征层的信息,而 SSD 则利用了不同尺度上的特征信息,其精度可想而知比 YOLO 要好。在卷积神经网络中,低层卷积更关心特征在哪里,它更多的是提取一些具体的细节信息,其分类准确性并不高;而高层卷积则更关心特征是什么,它提取的是与整体相关的抽象信息,可能丢失了类似物体在哪里的位置信息。SSD 将二者结合,在不同尺度的特征图上设置初始框,对于那些和真实目标交并比较大的初始框,网络对它做分类预测和位置偏移,并从中产生预测值。
SSD 的三个创新点:

  1. 用于检测的多尺度特征图:相比于 Yolo 而言,SSD 添加了多个卷积特征层用于最终的目标检测(不再是最后一层预测结果),它使得 SSD 可以适应不同尺寸目标物体的检测。(当时 Yolo 的缺陷就是对小目标物体检测不准)
  2. 用于检测的卷积预测器:SSD的每一个卷积特征层,可以通过一系列的过滤器(1*1、3*3)输出大量预测结果(维度为(Classes+4)的向量),在不同尺度特征图上输出的预测 bbox 数量不同,具体如下表所示,最终得到的检测数量是8732。目标检测之RCNN、Yolo、SSD、RetinaNet与Anchor-Free_第12张图片
  3. Default Box和长宽比:default box 是SSD中一个很重要的内容,它指代的就是上面生成的8732个预测框,这就类似于 RCNN 系列中的 anchor,它也是在特征图的每一个特征点上产生一系列边框,只不过 default box 在不同尺度上的尺寸大小是不一样的,同真实框之间的转换关系与 Faster RCNN、Yolo-v2 中类似,也就是 offset。还有一个概念就是 prior box,这个是从 default box 中筛选出来的,选取标准是与真实框的 IOU 超过一定阈值,它的数量远小于 default box 数量,最后 prior box 作为正样本,其它 default box 作为负样本。
3.2 SSD的实现与效果

TODO

3.3 SSD的后续进展

TODO

4、RetinaNet

参考

5、Anchor-Free目标检测

anchor的前世今生(上)
anchor的前世今生(下)
知乎1:物体检测的轮回: anchor-based 与 anchor-free
知乎2:目标检测:Anchor-Free时代
anchor based与anchor free对比
anchor free相关论文解析
Anchor-free之SAPD

你可能感兴趣的:(目标检测)