前言
今天我们一起学习Faster RCNN,《Faster R-CNN: Towards Real-Time ObjectDetection with Region Proposal Networks》这篇博客我们依然奉行老规矩,不求面面俱到,但求精简。希望可以帮到像我这样的小白。先看一下整体网络结构:
算法初识
1》算法能干什么?
答:可以高效的检测图片中的物品所在区域并且给出图片中物品的类别。
2》算法有什么优点?
答:其实我不知道,因为他是目标检测算法,无非做的就是检测目标,但是他又不是一阶段的检测器,所以多少会比一阶段end-to-end的检测器慢一点,但是硬说有什么好处的话,还真心不好说,因为目标检测所检测的目标只要画个矩形框出来就行,所检测物体的形状并不重要,所以指标无非就是速度和精度,如果说当时的话Faster RCNN自然是最先进的,现在已经更新好多代了,就不一定了所以优点就不说了,开整。
算法框架
还是先说一下Faster RCNN核心思想:anchors
先让我们看一下anchors的构成:
[[ -84. -40. 99. 55.]
[-176. -88. 191. 103.]
[-360. -184. 375. 199.]
[ -56. -56. 71. 71.]
[-120. -120. 135. 135.]
[-248. -248. 263. 263.]
[ -36. -80. 51. 95.]
[ -80. -168. 95. 183.]
[-168. -344. 183. 359.]]
其中每行四个值分别是左上角和右下角坐标,一般通过特征提取网络后后缩小后的特征图每一个像素点会配备9个anchorsanchors中长宽1:2中最大为352x704,长宽2:1中最大736x384,其实就是预先画好的检测框,Faster RCNN利用的是穷举法的思想,预先画好所有预测框然后只需后续对坐标进行微调就好了。这里有两点要注意:一、并不是多有的anchors都拿来训练,太多了浪费资源,所以只选其中的128个。二、在训练时偏移量求的是(x, y, w, h)对应4个偏移量,并不是坐标。
好了现在让我们进入正式的网络结构讲解。
首先,进入检测器的图像首先要reshape成800x600然后进入VGG16网络,输出通道数为256.
然后,送进3x3卷积融合周边的特征信息,但是保持通道数不变。
然后送入RPN中:
可以看到RPN网络实际分为2条线,上面一条通过softmax分类anchors获得positive和negative分类,下面一条用于计算对于anchors的bounding box regression偏移量,以获得精确的proposal。而最后的Proposal层则负责综合positive anchors和对应bounding box regression偏移量获取proposals,同时剔除太小和超出边界的proposals。其实整个网络到了Proposal Layer这里,就完成了相当于目标定位的功能。
然后送入 RoI pooling,值得注意的是送入 RoI pooling中的有两部分,一部分来自于前面的RPN另一部分来自于通过VGG16的特征图。但是 RoI pooling是做什么的呢?
先来看一个问题:对于传统的CNN(如AlexNet和VGG),当网络训练好后输入的图像尺寸必须是固定值,同时网络输出也是固定大小的vector or matrix。如果输入图像大小不定,这个问题就变得比较麻烦。有2种解决办法:从图像中crop一部分传入网络或者将图像warp成需要的大小后传入网络。
可以看到无论采取那种办法都不好,要么crop后破坏了图像的完整结构,要么warp破坏了图像原始形状信息。
回忆RPN网络生成的proposals的方法:对positive anchors进行bounding box regression,那么这样获得的proposals也是大小形状各不相同,即也存在上述问题。所以Faster R-CNN中提出了RoI Pooling解决这个问题。不过RoI Pooling确实是从Spatial Pyramid Pooling发展而来,但是限于篇幅这里略去不讲,有兴趣的读者可以自行查阅相关论文。
RoI Pooling layer forward过程:
由于proposal是对应MXN尺度的,所以首先使用spatial_scale参数将其映射回(M/16)X(N/16)大小的feature map尺度;
再将每个proposal对应的feature map区域水平分为7x7的网格;
对网格的每一份都进行max pooling处理。
这样处理后,即使大小不同的proposal输出结果都是7x7固定大小,实现了固定长度输出。
我们姑且把他理解为归一化处理吧。
最后就是最后的Classification部分了:
Classification部分利用已经获得的proposal feature maps,通过full connect层与softmax计算每个proposal具体属于那个类别(如人,车,电视等),输出cls_prob概率向量;同时再次利用bounding box regression获得每个proposal的位置偏移量bbox_pred,用于回归更加精确的目标检测框。
从RoI Pooling获取到7x7=49大小的proposal feature maps后,送入后续网络,可以看到做了如下2件事:
1.通过全连接和softmax对proposals进行分类,这实际上已经是识别的范畴了
2.再次对proposals进行bounding box regression,获取更高精度的rect box
然后我们就得到了最后的检测框和分类结果。
训练及损失函数
由于Faster RCNN两次分类存在特殊性所以训练方法也比较特殊这里提一下:
首先,利用训练好的VGG16训练RPN,收集proposals。
然后,第一次训练Faster RCNN。
接着,第二次训练RPN,收集proposals。
最后,第二次训练Faster RCNN。
至于为什么只训练两次,因为再多次也不会有太好的效果,所以没必要。
然后看看损失函数:
这里重点看一下训练RPN网络
整个Loss分为2部分:
cls loss,即rpn_cls_loss层计算的softmax loss,用于分类anchors为positive与negative的网络训练
reg loss,即rpn_loss_bbox层计算的soomth L1 loss,用于bounding box regression网络训练。
训练Faster RCNN网络
最后
这里就写这些了,再多的部分就涉及复杂的原理,有一位前辈写的特别好,这里推荐一下:https://zhuanlan.zhihu.com/p/31426458,这里向各位前辈致以诚挚敬意。