目标检测系列:
目标检测(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)系列(十三) CenterNet:no Anchor,no NMS
目标检测(object detection)系列(十四)FCOS:用图像分割处理目标检测
目标检测扩展系列:
目标检测(object detection)扩展系列(一) Selective Search:选择性搜索算法
目标检测(object detection)扩展系列(二) OHEM:在线难例挖掘
目标检测(object detection)扩展系列(三) Faster R-CNN,YOLO,SSD,YOLOv2,YOLOv3在损失函数上的区别
R-FCN简介:
R-FCN是承接Faster R-CNN的工作,论文是《R-FCN: Object Detection via Region-based Fully Convolutional Networks》,可以简单的理解为R-FCN是Faster R-CNN 位置敏感(position sensitive)卷积层。提出的初衷是为了解决R-CNN系列,在新的图像分类backbone下效果不好的问题。R-FCN之所以起这个名字,是因为图像分割任务中出现了一个FCN(全卷积网络),而这种全卷积的说法和R-FCN想要表达的意思很契合。
CNN的旧形态
用于图像分类的基础CNN模型,有一个旧形态与新形态的区分,基于旧形态的CNN结构如AlexNet,VGG,Network-in-Network,ZF-Net等等,它们都有一个特点是卷积之后保留了几层用于逻辑判断的全连接网络。何凯明和RBG团队的R-CNN系列在Faster R-CNN之前都是在这种旧形态的CNN模型上改出来了,又因为Faster R-CNN及其之前的网络一直在解决的问题就是如何充分的利用原有模型的卷积层作共享计算,所以才会有用卷积层完成整幅图像的特征提取,区域建议的生成等等工作。
CNN的新形态
我们都知道基础的CNN模型,一般情况下层数越深,特征图的厚度也就会越大,这样一来,为了适应第一层的全连接的维度,往往会在最后一层特征图上做全尺寸的卷积,这层卷积的参数量是非常巨大的,比如AlexNet一共只有60M个参数,但是这一层卷积的参数量就会占去一多半,所以新形态的CNN呈现全卷积化的趋势,比如ResNet,GoogleNet,DenseNet等等,而且最后一层一般采用全局平均池化而不是全尺寸卷积,这样一来可以在尽量减少参数的情况下增加网络的深度。
R-CNN系列在新形态CNN下的问题
Faster R-CNN及其之前的结构都是基于旧形态CNN设计的,如果把新形态的CNN迁移到Faster R-CNN中就会出现问题,对于这个问题,作者给出了如下解释:
图片分类任务与目标检测任务性质是有所差异的,分类任务想要的是对于变换的不变性(Translation invariance),也就是说不管这个类别的东西在图片的什么位置,它占图像的什么比例,对分类的结果不应该产生影响。就像上面这张图,这是ImageNet中类别为野马的两张图,尤其是第二种,其实把label贴成兔子我也是信的。╮( ̄▽  ̄)╭
但是检测任务想要的是对于变换的敏感性(Translation variance),因为需要知道物体到底在哪里,还要知道目标在图像中到底多大。
但是卷积的层数越深,下采样的次数就越多,特征提取的就越抽象,不变性就越强,敏感性就会变弱。所以Faster R-CNN的结构并不适合新形态的CNN。
这里需要说明一点:这些观点大多来源于论文,其实在现在的很多工程实践中,Faster R-CNN就是在用ResNet,在这里之所以把论文的观点说出来主要是为了理解作者是如何一步一步的改进,最后完成R-CNN整个系列,个人认为这个思路的理解也是同样重要的。
R-FCN原理
设计理念
在Faster R-CNN中,作者其实有提到过使用ResNet101网络,但是ResNet101是一个全卷积网络,一系列的卷积层之后直接接了全局平均池化层,已经没有隐藏全连接层了,只有一个用于输出的全连接层。这就带来一个一问题,Faster R-CNN应该用哪几层共享卷积计算呢?
使用全部的卷积层,这显然不靠谱,一方面是因为最后一层特征图的不变性太强,更重要的一点是ROI分支子网络的能力太弱了,只有一层全连接。那就只能把共享卷积计算的层前移了,让ROI分支加深,让共享卷积层变浅,最后确定下来一个经验值,那就是ResNet101的第91层,这样实验下来,mAP效果相比VGG16是变好的,因为毕竟主干网络强了很多,但是分支的计算量变大了,而且选择多少个区域建议,分支就要跑几次,这使得ResNet101的Faster R-CNN速度很慢。
在这个背景下,就有了R-FCN,R-FCN是为了适应全卷积化的CNN结构,首先R-FCN在共享所有的卷积层的,其次为了解决上面提到的问题,R-FCN提出了:
- 位置敏感分值图(Position-sensitive score maps),用来判断某一个框到底属于哪一个类别;
- 位置敏感池化(Position-sensitive RoI pooling),在位置敏感分值图的基础上提出的一种池化操作。
网络结构
上面这张图就是R-FCN的结构:
- 在绿色框里的内容就是ResNet-101模型,这部分卷积计算还是用来被RPN和Position-sensitive Net共享的,他就相当于Faster R-CNN使用VGG16主干时的前15层卷积一样,有一点区别在于,ResNet-101的最后一层特征图用1times1 的卷积做了降维,降到了1024,可能是考虑到位置敏感卷积节省计算量;
- 蓝色的框内是RPN,它在R-FCN中的作用和在Faster R-CNN中是一样的,负责输出建议区域与边界框;
- 最重要的部分,就是红色框内的位置敏感卷积与池化,实际上,这部分的结构在Faster R-CNN中是RoI pooling 全连接 多任务损失函数等等,在R-FCN中,这部分内容换成了对位置敏感卷积,并把RPN的建议框扣在在分值图上做位置敏感池化。
位置敏感卷积
上面图中,feature maps后面那根线就是位置敏感卷积层,它的卷积核个数是k^2(c 1) ,其中K是超参数,在论文用的比较多的是k=3,K^2 是Grid的个数,这个个数与位置敏感池化操作后的尺寸相关联的。C 是物体的类别数量,加1是因为还有一个背景类。经过了这一层卷积之后的输出就是位置敏感分值图,分值图的宽高尺寸是与feature maps的宽高一致的,分值图的通道数就是k^2(c 1) ,即每一个类别都有K^2 个通道。
虽然这一层卷积操作叫位置敏感卷积,并输出了位置敏感分值图,但是它本质上只是一个常规的卷积,不同的地方其实在于配合它一起使用的位置敏感池化。
位置敏感卷池化
位置敏感池化是在分值图上的一种池化操作,它是RoI池化的变种,之前说分值图的通道是k^2(c 1) ,每一个类别有K^2 个通道,换句话说,分值图上就有K^2 个C 1 的通道的组合。那么假设k=3 的话,这种情况就像上面图示的那样,每一个颜色都有C 1个通道,RPN的区域建议扣在分值图上后,位置敏感池化会把这个区域在每一个通道上平均分为K^2 份,然后在每一份内做Max Pooling,其中Ktimes K 的格子的位置是和通道是一一对应的,如上图中深黄色的通道数有C 1个,那么位置敏感池化操作的时候,只要深黄色通道为左上角的bin内的值,作为Ktimes K 格子的左上角位置的值,所以K*K格子的左上角位置也是深黄色的。这种对应关系就是从左到右,从上到下。这样的话,会得到一个Ktimes K 的格子,厚度是C 1 ,也就是每一个通道代表一个类别。位置敏感池化层之后,再做一步全局平均池化,就得到了1times1times(C 1) 的特征,刚好是C 1 个数,这样一来,维度固定了,同样实现了将不同的输入整理成相同维度的输出,同时维度刚好与分类数相等。下面我们拿具体的数带一遍,假设类别数C= 20 ,格子的尺寸是3times 3 ,那么位置敏感卷积的卷积核数量就应该是3^2times(20 1) = 189 ,输出特征图通道数也是189。189要分成9份,每一份都有21个通道,代表着21个类别。经过位置敏感池化层,特征图尺寸变成3times 3times21 ,再经过全局平均池化变成21。下面这张图可以更直观的说明位置敏感池化,红色的箭头就说明了这种对应关系:
R-FCN损失函数
这个损失函数,和之前的没啥区别,同样是一个分类 回归的多任务损失,最后在一个batch加和计算loss。
用于分类的是还是负的概率log值;
用于回归的是smooth L1。
关键的地方是,R-FCN把什么特征送到了Bounding box回归模型里面,在Fast R-CNN里是conv5特征经过RoI pooling之后的特征,在RPN里是用一个卷积分支专门生产的特征,在R-FCN里面也是用一个单独的卷积分支生成的,特征的通道数是4K^2,方法和位置敏感卷积时一样的,只是C 1改成了4。
R-FCN训练
R-FCN训练的步骤与Faster R-CNN相同,同样是分步训练法,只是把Fast R-CNN换成了R-FCN。
此外,文章提出了一个叫做OHEM(Online Hard Example Mining)的训练技巧:
当一个图片生成N个区域建议后,会使用当前的网络一次计算所有N个区域的loss,并根据loss从大到小排序建议区域,并从这N个排序后的区域中取前Batch-size个。
这是因为,如何某区域的loss更大,那么说明网络中的参数并没有照顾到这种特征,而这种特征应该是被学习到的,如果把本来loss就很小的特征在送入网络中参与训练,对参数的更新也没啥影响。
R-FCN性能评价
上面这张图说明了超参数k对最后的mAP的影响:
初始的Faster R-CNN RoI pooling的k选择为1时,mAP为61.7%,选择为7时,mAP为68.9%;
R-FCN RoI pooling的k选择为1时是没有位置敏感信息的,直接fail,k选择为3和7时,mAP分别为75.5%与76.6%。
上面这张图从多个角度对比了Faster R-CNN与R-FCN,其中Faster R-CNN用的是Resnet101,把前91层做共享卷积计算,后10层代替原来的3层全连接,所以这个Faster R-CNN的测试时间不是之前说的0.18s,而是mAP也不是66.9%。
关注中间一行,在使用OHEM的情况下,以ResNet-101为初始模型的两个结构,单张训练时间,R-FCN比Faster R-CNN快3倍多,单张测试时间R-FCN比Faster R-CNN快2.5倍左右。而0.17s这个时间,和Faster R-CNN使用旧形态的CNN模型时间是差不多的,但是mAP确实79.5%,优于原来的69.9%。