深度学习系列(五):Faster RCNN算法理论

目标检测

概念

目标检测(Object Detection)是指在给定的一张图片中找出感兴趣的目标识别出目标类别并找到它所在的位置,这个位置一般使用边缘框(Bounding Box, bbox)框选出来,边缘框的形状是矩形,一般使用 4 个数字可以描述一个边缘框在图像中的位置。例如使用边缘框左上角坐标(x1,y1)(x_1,y_1)和右下角像素坐标(x2,y2)(x_2,y_2),或者使用左上角坐标(x1,y1)(x_1,y_1)以及bbox高宽w,hw, h来表示,bbox绘制到图像中如下图所示。

目前基于深度学习的目标检测算法分为基于锚框(Anchor based)和无锚框(Anchor free)两类,其中基于锚框的目标检测算法仍然是目前的主流,也给目标检测问题提供了一个很好的思路。

目标检测算法的另一种分类是根据算法的处理流程分为两阶段(Two stage)和单阶段(One stage)算法,两阶段目标检测算法一般指经典的 RCNN 系列算法,也就是本篇博客要讲的,单阶段目标检测算法有工业界使用广泛的 YOLO 系列算法、SSD 算法等。

RCNN 系列算法

先介绍一下 RCNN 系列算法的发展改进过程。

  • 早在2013年,Ross Girshick等人就提出了RCNN 算法:Rich feature hierarchies for accurate object detection and semantic segmentation,这也是第一次将卷积神经网络引进目标检测领域,并且取得了极大的成功(效果好于当时所有的目标检测算法)。算法的基本思路如下:

    首先是使用选择性搜索(Selective Search)方法从输入图片中找出若干个(约2000个)建议区域(Region Proposals),这些区域是目标可能出现的区域;将这些区域从输入图像中抠出来统一成相同大小并使用卷积神经网络抽取特征,每个region proposal抽取得到一个4096维的特征向量,对这个特征向量使用支持向量机(SVM)进行分类。在当时支持向量机还是比较火的分类器,如今几乎被全连接神经网络代替了。

  • 在2015年,原作者对 RCNN 算法进行改进,提出了 Fast-RCNN 算法:Fast R-CNN。在 RCNN 算法中需要对每个region proposal使用卷积神经网络进行特征抽取,每张图片约有2000个region proposal,这个计算量十分庞大。Fast RCNN只对输入图像使用卷积神经网络抽取得到特征图(Feature map),然后根据region proposal在原图中的位置按照比例从特征图上提取相应的兴趣区域(ROI)。由于不同目标大小不一样,因此得到的ROI并不是同样大小,不能统一送入后面的边界框回归和分类网络中,Fast RCNN 使用ROI Pooling方法将这些ROI切成同样大小的特征图,而不是直接扭曲特征图大小,这样保留了特征图的相应空间信息。

    此外,将后面的边界框类别和位置预测改为使用全连接神经网络。Fast-RCNN让所有region proposal共用一张使用卷积神经网络获得的特征图,而不是分别进行卷积运算,大大提高的算法的实时性,虽然还是比较慢(GPU上检测速度约2~3帧)。

  • 2016年,作者再次对算法进行改进,提出了 Faster-RCNN 算法:Faster R-CNN,这也是后面要具体讲述原理细节的算法。作者发现在 Fast-RCNN 算法中使用选择性搜索寻找region proposals是算法速度的瓶颈,因此采用一个单独的网络来得到region proposals,这个单独的网络被称为Region Proposal Network,也就是RPN网络。

    实际上这个RPN网络就是一个单独的目标检测算法,只不过它只预测目标框的位置和得分,不预测类别。很多单阶段的目标检测算法和RPN网络原理类似。

经过多番改进,Faster-RCNN在目标检测领域占据了重要地位,其在标准数据集上的检测准确率表现很好,但是速度相比单阶段目标检测网络而言仍然比较慢。但无论如何,RCNN 系列算法给许多其它算法带来了启发,其设计思路也非常值得学习。

Faster-RCNN算法细节

Faster-RCNN 较为具体的结构如下所示:

Backbone

图像首先经过 Resize 和归一化处理然后使用 Backbone 抽取特征,Resize 目的是将所有图片都变换至某个大小范围之间,这个过程保持图像的宽高比例不变,归一化是图像抽取特征前基本都会使用的方法,该操作对图像中的每个像素减去像素均值并除以标准差,这里的均值和标准差常使用ImageNet图像的值。

骨干网络 Backbone 用于对输入图像抽取特征,得到相应的 feature map1,原论文中使用的 Backbone 为 VGG 网络,实际上可以替换成任何经典的特征提取主干网络,如 ResNet、MobileNet等。

RPN

RPN网络用于对图像生成初步的 proposals,这是比锚框更为精确的目标框,用于作为第二次目标框调整的基准。

锚框(Anchors)生成

为了找到 proposals,需要对原图像生成锚框,生成的方法是以 feature map1 中的每个像素为中心生成一系列固定大小和比例的锚框,例如以每个像素点为中心生成以下 9 个锚框:

1
2
3
4
5
6
7
8
9
10
以(0, 0)为中心的锚框坐标:top-left, bottom-rihgt
tensor([[ -91., -45., 91., 45.],
[-181., -91., 181., 91.],
[-362., -181., 362., 181.],
[ -64., -64., 64., 64.],
[-128., -128., 128., 128.],
[-256., -256., 256., 256.],
[ -45., -91., 45., 91.],
[ -91., -181., 91., 181.],
[-181., -362., 181., 362.]])

由于 feature map1 是对原图像进行K倍下采样得到的,因此对于 feature map1 像素生成以上 anchors 相当于在原图像上每隔K个像素生成上述 9 个锚框:

为了图像清晰,这里只画了两个像素为中心的18个锚框,实际上,每张图片均会密集的生成大量锚框,这也保证对于图像中的目标“一网打尽”。例如,对于一张 800 x 600 大小的输入图片,使用 16 倍下采样的 Backbone,得到的 feature map1 大小为:50 x 38,每个像素对应原图中的 9 个锚框,那么一张图像将生成50×38×9=1710050 \times 38 \times 9 = 17100个锚框,这些锚框密密麻麻地排布在原图像上,负责预测真实目标框的位置。

RPN 网络需要对每个锚框预测 2 个目标分数,用于指示该锚框含有目标和不含目标的分数(实际上可以只使用一个分数来表示,实现上可以这样实现);此外,还要对每个锚框预测 4 个参数用于调整锚框位置,这在后面 bbox regression 中会具体介绍。

从最开始的 Faster-RCNN 算法结构图也可以看出,RPN 网络首先使用一个 3x3 卷积对特征图进行进一步处理,然后分为两个分支分别使用 1x1 卷积进行锚框分数预测以及目标框回归参数预测。假如每个feature map1中的像素产生m个锚框,且 feature map1 的形状为 [C, H, W],那么 class_logits 的形状为 [2m, H, W], 如果使用一个目标框分数的话,其形状为[m, H, W];box_pred 的形状为[4m, H, W]

bbox regression

为了找到目标,我们在原图上生成了许多锚框,但这些锚框基本不可能和真实目标框(Ground truth bbox)重合,因此,为每个锚框预测了 4 个参数用于调整锚框的大小和位置。

为了便于解释原理,使用中心点坐标和高宽来表示目标框位置,假设生成的 anchor 坐标为:[xa,ya,ha,wa][x_a, y_a, h_a, w_a],真实目标框 gt box 坐标为:[x,y,h,w][x, y, h, w],为了将 anchor 向真实目标框调整,可以先将其进行平移,然后对宽高进行缩放:

tx=(xxa)/waty=(yya)/hatw=log(w/wa)th=log(h/ha)t_x = (x - x_a) / w_a \\ t_y = (y - y_a) / h_a \\ t_w = log(w/w_a) \\ t_h = log(h/h_a)

反过来,只要学习到[tx,ty,tw,th][t_x, t_y, t_w, t_h] 4 个参数,就能够对锚框位置和大小进行调整,得到最终的预测目标框。训练的时候,根据锚框和真实目标框的匹配情况(通常使用IOU来判断),可以计算得到真实目标框和锚框之间的变换参数,只需要通过这个参数和当前网络预测出的参数计算损失即可用于优化网络参数。

RPN 网络为每个锚框预测出了回归参数,以及它们是否含有目标的一个得分,根据这些 proposals 得分排序,取得分高的部分,并通过去除过小的 proposals、使用非极大值抑制进行部分框的消除等得到最终的 proposals, 这些 proposals 用于进一步的目标检测(这些 proposals 相当于后面算法部分的锚框,但是这个数量就远小于逐个像素生成的锚框数量了,而且由于是训练出来的,这些 proposals 将会更加精确)。

非极大值抑制(NMS)

由于生成的锚框众多,因此会存在同一个目标产生若干个相互重叠的 proposal 的现象,以及最终预测的目标边界框也有可能产生这种重叠的情况。非极大值抑制(Non-Maximum Suppression, NMS)会去除这些多余的目标框,NMS 基本上是基于锚框的目标检测算法都需要进行的步骤。

如上图,如果不适用 NMS,可能对于同一个目标会有多个重叠度很高的预测框。NMS的步骤如下:

  1. 对于同一个类别的预测框根据置信度分数排序。
  2. 选取置信度分数最高的预测框作为最终的输出,入图中的dog=0.9的框和cat=0.9的框,并从预测框列表中删除上述预测框。
  3. 计算上述预测框和其它同类预测框之间的 iou,将 iou 高于阈值的预测框从列表中删除(也就是抑制具有非极大值的预测框),图中的dog=0.8dog=0.7的框均被删除。
  4. 然后重复上述过程,直到预测框列表中所有的预测框均是输出框。

ROI pooling

由于 RPN 得到的一系列 proposals 的大小不一样,其对应在 feature map1 上的区域大小也不一样,因此这些 proposals 对应的 feature map1 区域不能够送到同一个后续网络中进行计算。虽然可以使用裁剪或 resize 的方法解决这个问题,但是这样会使得丢失信息或者图像宽高比例发生变化。一个更好的解决办法是使用 ROI pooling 将这些区域变成相同大小的区域。

如图,ROI pooling 将 proposals 对应的区域使用固定网格均分成若干块,对每一块区域计算像素最大值,如上图中使用 7x7 大小的网格,这样一来经过 ROI pooling 层之后得到的 feature map2 大小都是 7x7 的固定大小,便于后面送入同一个网络中处理。

最终目标框预测

通过 ROI pooling 层之后得到每个 proposals 特征图组成的 feature map2, 其形状为:[N, 7, 7],其中N为 RPN 提供的 proposal 的个数。后续通过两个全连接层,再分成两条通路,首先是预测 proposal 对应不同目标类别的分数 class_logits,对于 pascal VOC 数据集而言有 20 个目标类别,这里加上背景类需要预测 21 类,因此 class_logits 形状为[N, 21],然后是预测用于 proposal 调整的 4 个参数 box_pred,形状为[N, 21 * 4],这里对每个类别的 proposal 均预测 4 个参数,其中背景类的这 4 个参数需要丢弃。

得到上述参数之后,从所有 proposals 预测得到的目标框中通过得分阈值进行筛选,并去除过小的预测框、对每个类别分别执行非极大值抑制,得到最终的检测结果框。

网络训练

整个网络的损失由两部分组成,第一部分是 RPN 预测 class_logits 产生的损失和预测 box_pred 产生的损失;第二部分是最终预测这两个结果产生的损失。其中类别预测损失和bbox回归损失计算如下:

L({pi},{ti})=1NclsiLcls(pi,pi)+λ1Nreg ipiLreg (ti,ti)\begin{array}{r} L\left(\left\{p_i\right\},\left\{t_i\right\}\right)=\frac{1}{N_{c l s}} \sum_i L_{c l s}\left(p_i, p_i^*\right) +\lambda \frac{1}{N_{\text {reg }}} \sum_i p_i^* L_{\text {reg }}\left(t_i, t_i^*\right) \end{array}

式中 ii 为锚框在一个 batch 中的下标,pip_i 表示第 ii 个 anchor 对应一个目标的预测分数,pip_i^* 是真实目标框标签,当该 anchor 对应一个真实 ground-truth box 的时候,pi=1p_i^*=1, 否则取pi=0p_i^*=0,判断 anchor 是否对应一个 gt box 的方法是若它们之间的 iou 大于 0.7 则该 anchor 是正例, 当 iou 小于 0.3 则是 负例, 处于两者之间的 anchor 不参与训练。tit_i表示预测的目标框回归参数,tit_i^*表示 gt box 对应的参数。因此,式子第一项为类别预测的损失,第二项为目标边界框预测参数的损失。

有了两部分共四项损失进行加和即可对网络进行训练。

参考文献

  1. Rich feature hierarchies for accurate object detection and semantic segmentation
  2. Fast R-CNN
  3. Faster R-CNN
  4. 一文读懂Faster RCNN
  5. https://zh-v2.d2l.ai/chapter_computer-vision/index.html