1、R-FCN 设计的目的
虽然Faster R-CNN把整个的检测过程集成到了一个可以end-to-end训练的网络,实现了大部分计算的共享,也极大的提高了检测速度。但是整个检测过程还是不够快,因为Faster R-CNN虽然使用了conv layers来共享特征提取,但是在RoI pooling提取每个RoI的feature map之后,要使用FC layer单独对每个RoI进行分类和回归,所以假设提取了128个RoI,那么就要使用FC layer进行128次的回归和分类,而且大家也都知道FC layer的计算量是非常大的,所以这部分的计算就拖慢了Faster R-CNN的检测速度。所以还需要更充分的共享计算才能再提高速度,因此文章中提出了使用全卷积网络(FCN, Fully Convolutional Network)来实现计算共享,提高速度。具体使用的是ResNet-101的conv layers。
但是使用这样比较深的网络也存在一个问题,那就是平移不变性和平移可变性的问题。因为使用ResNet-101分类的时候,无论物体怎么翻转、平移、扭曲,分类结果还是相同的,这就是平移不变性。但是对于目标检测,当物体发生平移时,检测结果也应该随着物体的变化而变化,这就是平移可变性。但是当卷积网络变深后,输出的feature map就变小,所以在原图上的一些物体的偏移,在经过N层pooling后得到的小feature map上会感知不到,所以网络变深使得平移可变性变差。所以为了解决这个问题,首先想到的是将RoI pooling层往前移动,因为在浅层的feature map上进行RoI pooling更能提取一些位置比较精确的proposal,然后这些proposal再进行卷积就能给深层的conv来平移可变性。对于这个改进,作者也给出了试验结果来证明:RoI放在ResNet-101的conv5后,mAP是68.9%;RoI放到conv4和conv5之间的mAP是76.4%,所以证明RoI能够给深层网络带来平移可变性,同时平移可变性对于目标检测也相当重要。但是实验结果也表明,在conv5之后放RoI还是没有很好的效果,因此需要其他的方法来使得网络对于位置比较敏感,因此就提出了position-sensitive score map来达到这个目的,使得网络变深的同时,准确率也能和Faster R-CNN相媲美。
Position-sensitive score map的概念最早来自另一篇实例分割的论文Instance-sensitive Fully Convolutional Networks (https://arxiv.org/pdf/1603.08678.pdf)。
2、 R-FCN 的贡献
-
将FCN(Fully Convolutional Network)应用于Faster R-CNN,使得整个网络的计算可以共享,从而极大的提高了检测速度,同时检测的精度和性能(mAP)也可以和Faster R-CNN相媲美。
-
提出了position sensitive score map来平衡平移不变性(translation-invariance)和平移可变性(translation-variance)之间的矛盾。
3、 模型结构
所示为R-FCN的结构图,从图中我们可以看出R-FCN主要包括4个部分:Conv layers (ResNet)、Region Proposal Network(RPN)、Classification、Regression。而整个R-FCN的流程如下:
-
首先输入一张图片,图片要经过resize使得图片的短边的长度为600。
-
然后图片先经过ResNet-101来提取特征,ResNet-101主要包括5个卷积网络块。
-
其中conv4的输出作为RPN的输入,和Faster R-CNN相同,这个RPN是用来提取proposal的,即提取出RoIs。
-
同时,ResNet-101的conv5输出因为是2048-d的,所以又加了一个新的new conv来降低channel的维度,输出的维度为1024-d。
-
然后这个1024-d的feature map再输入两个平行的conv layer中,一个用来classification,另一个用来regression。
-
对于classification的conv layer会产生一个k^2(c+1)维的position-sensitive score map,然后再结合RPN提取的RoIs进行pooling,之后再为每个RoI得到分类结果。
-
而对于regression的conv layer则会产生一个4k^2 维的position sensitive score map,然后也同样结合RPN提取的RoIs进行pooling,之后再为每个RoI得到回归结果。
上述过程是R-FCN进行目标检测的一个流程,接下来给大家详细讲解R-FCN中的各个部分。
ResNet卷积层
在R-FCN中采用的是ResNet-101的网络结构,ResNet-101主要包括5个conv块,其中包括100个的conv layer和1个FC layer,在文中去掉了最后一层FC layer,只使用了前5个conv块,共100层卷积。
Region Proposal Network(RPN)
R-FCN中的RPN和Faster R-CNN中的PRN相同,并没有进行改进。
分类
在分类模块中,new conv层输出的1024-d的feature map输入到一个 1 ∗ 1的卷积层中,然后得到一个k^2(c+1)维的position sensitive score map。k^2(c+1) 表示有k^2个score map,每个score map是c+1维的,代表着(c+1)类。这个k^2 score map都对应着k∗k 的网格的空间位置,第一个score map对应的是网格的top-left,第二个score map对应的是网格的top-center,依次类推。
得到这个position-sensitive score maps之后,就要结合RoIs来进行RoI pooling了,和Faster R-CNN相同的是,都会将RoI对应的feature map分成 k ∗ k k*kk∗k 个bin,然后在每个bin内进行pooling,然而不同的是R-FCN使用的是selective pooling。整个pooling过程可以用以下公式表示:
其中,(x0,y0) 表示的是RoI的左上点的坐标,(x,y) 表示的是bin(i,j) 中的点的坐标,所以(x+x0,y+y0)就是bin(i,j) 中的点在feature map上的坐标,然后z i,j,c(x+x0,y+y0∣Θ) 就是坐标对应的像素点的值,所以公式右侧的意思是bin(i,j) 中所有的像素点的值加和然后求平均,这就是说在bin(i,j)中采用的是average pooling。这也就是说每个最后得到的rc(i,j∣Θ) 是用第(i,j) 个score map上的第(i,j) 个bin中进行average pooling得到。这个公式很绕,不懂也没关系,我们用图来说明。
如上图所示,对于一个RoI,首先将其分为 k∗k 个bin,在这里为 3∗3,也就是9个score map都应将RoI对应的区域分为 3∗3 。那么在pooling时,第一个score map上的top-left bin中进行average pooling, 然后得到pooling后的feature map的左上角的值。然后第二个score map上的top-center bin 中进行average pooling,然后得到pooling后的feature map的top-center的值,依次类推。在图中,我使用了相同的颜色来表示进行average pooling的bin,以及其在pooling后的feature map上对应的位置。需要注意的是,在这里每个bin中使用的是average pooling,那使用max pooling也是可以的。
附:position sensitive score map的通道个数为K*K*(C+1) 。其中C表示物体类别种数,再加上1个背景类别,所以共有(C+1)类,而每个类别都有 K*K个score maps(将该map分成c+1份,每份k*k个)。现在我们只针对其中的一个类别来进行说明,假设我们的目标属于人这个类别,那么其有 K*K 个score maps,每一个score map表示原始图像中的哪些位置含有人的某个部位,该score map会在含有对应的人体的某个部位的位置有高的响应值,也就是说每一个score map都是用来描述人体的其中一个部位出现在该score map的何处,而在出现的地方就有高响应值”。既然是这样,那么我们只要将RoI的各个子区域对应到属于人的每一个score map上然后获取它的响应值就好了。但是要注意的是,由于一个score map都是只属于一个类别的一个部位的,所以RoI的第 i个子区域一定要到第i张score map上去寻找对应区域的响应值,因为RoI的第i个子区域需要的部位和第i张score map关注的部位是对应的。那么现在该RoI的K*K个子区域都已经分别在属于人的K*K个score maps上找到其响应值了,那么如果这些响应值都很高,那么就证明该RoI是人。
3.2 Position-Sensitive Rol Pooling
ROl的K*K个子区域在各个类别的score maps上每个子区域的响应值,就是通过位置敏感Rol池化操作(Position-sensitive RoI pooling)找到的,其字面意思是池化操作是位置敏感的。
通过RPN提取出来的RoI区域,包含了x,y,w,h的4个值,也就是说不同的RoI区域能够对应到score map的不同位置上,而一个RoI会被划分成K*K个bins(也就是子区域。每个子区域bin的长宽分别是 h/k 和 w/k ),每个bin都对应到score map上的某一个区域。既然该RoI的每个bin都对应到score map上的某一个子区域,那么池化操作就是在该bin对应的score map上的子区域执行,且执行的是平均池化。在前面已经讲了,第i个bin应该在第i个score map上寻找响应值,那么也就是在第i个score map上的第i个bin对应的位置上进行平均池化操作。由于有(C+1)个类别,所以每个类别都要进行相同方式的池化操作,同样,结果也是c+1个channel。
那么对于每个类别,该类别的K*K个值都表示该RoI属于该类别的响应值,那么将这K*K个数相加就得到该类别的score,那么一共有(C+1)个scores,那么在这(C+1)个数上面使用简单的softmax函数就可以得到各个类别的概率了(注意,这里不需要使softmax分类器了,只需要使用简答的softmax函数,因为这里就是通过简单的比大小来判断最终的类别的)。