Faster R-CNN详解和网络模型搭建
发布网友
发布时间:2024-09-25 22:11
我来回答
共1个回答
热心网友
时间:2024-09-25 22:56
论文原文: arxiv.org/abs/1506.0149...
个人代码仓库: GitHub - dailonggang/Faster-R-CNN
文章部分图片引自: zhuanlan.zhihu.com/p/31...
我们知道Faster RCNN是由R-CNN、Fast R-CNN改进而来,是非常经典的两阶段网络,下面我们就原理和代码进行介绍。在此之前大家可以先了解一下R-CNN、Fast R-CNN的原理,这样对Faster RCNN也能有更好的理解,毛遂自荐一下:
Faster R-CNN其实可以分为5个主要内容:
Faster R-CNN整体结构图如下所示:
下面就Faster R-CNN上面的5个部分做一个比较详细的介绍:
二、Resize
首先对输入的图像进行resize操作,以适应模型要求,单独resize.py文件进行实验。
三、Backbone
接下来利用ResNet50网络进行特征提取得到特征图(Feature Map)。有关ResNet50的原理和代码部分可以参考: ResNet网络结构详解与Pytorch版本模型的搭建。还可以单独进行调试。
四、RPN网络
RPN网络实际分为2条线,上面一条通过 softmax 对前景(positive)和背景(negative)进行分类,下面一条用于对anchors进行bounding box regression偏移量,以获得精确的proposal。
Region Proposal Networks(RPN)和锚框(anchor)
RPN作为Faster RCNN的一大主要创新点,网络直接使用RPN生成候选区域,这也将生成区域提议的时间从2s缩减到了10ms,大大提升了生成待检测区域的速度。从网络图也可以看出Faster R-CNN其实就是RPN和Fast-RCNN的结合。提到RPN网络,就不能不说锚框(anchor)。锚框是在原图上设置不同大小的假想框,来检测框中是否出现物体。简单地说,RPN依靠一个在共享特征图上滑动的窗口,为每个位置生成9种预先设置好长宽比与面积的框(anchor)。这9种初始anchor包含三种面积(128×128,256×256,512×512),每种面积又包含三种长宽比(1:1,1:2,2:1)。如下图所示:
anchor生成代码:
在原文中,经过特征提取后,共享特征图的大小约为40×60,RPN生成的初始anchor总数为20000(40×60×9)。对于生成的anchor,RPN要做的事情有两个,第一个是判断anchor到底是前景还是背景,意思就是判断这个anchor到底有没有覆盖目标,在训练的时候排除掉了超越图像边界的anchor,剩下大约6000个,通过上面的分支,也就是先经过一个3×3卷积,得到一个相同大小shape的特征图,然后经过一个1×1的卷积层输出了18个值,因为是每一个点对应9个anchor,每个anchor有一个前景分数和一个背景分数,所以9×2=18;第二个是为属于前景的anchor进行第一次坐标修正。经过另一个1×1的卷积层输出了36个值,因为是每一个点对应9个anchor,每个anchor对应了4个修正坐标的值,所以9×4=36。那么,要得到这些值,RPN网络需要训练。在训练的时候,就需要对应的标签。那么,如何判定一个anchor是前景还是背景呢?文中做出了如下定义:如果一个anchor与ground truth的IoU在0.7以上,那这个anchor就算前景(positive)。类似地,如果这个anchor与ground truth的IoU在0.3以下,那么这个anchor就算背景(negative)。这样最终得到约2000个候选框。但是作者在进行RPN网络训练的时候,只使用了上述两种情况的anchor,与ground truth的IoU介于0.3和0.7的anchor没有使用。在训练anchor属于前景与背景的时候,是在一张图中,随机抽取了128个前景anchor与128个背景anchor。其实还有另一种方案就是取IoU最大值。正样本是在不够,就用负样本进行补充。下面的propsal还会细说。代码如下:
这里补充一点,其实原论文中是对k个anchor进行的操作,使用二分类交叉熵损失函数,如果按照我们使用2k个,那么就应该使用多分类交叉熵损失函数。另外,如果我们使用VGG作为主干特征提取网络的话,那么对于提取得到的特征图的感受野应该是228,显然小于256和512这两个面积,但是论文中也提到了,其实小于只看部分也能推测出结果,通过后续算法验证也确实如此。
对于感受野的计算大家可以参见下面文章:
五、Proposal Layer
由网络结构图可以看出,Proposal Layer负责综合所有计算出精准的proposal,送入后续RoI Pooling Layer。
首先解释im_info。对于一副任意大小PxQ图像,传入Faster RCNN前首先reshape到固定MxN,im_info=[M, N, scale_factor]则保存了此次缩放的所有信息。然后经过Conv Layers,经过4次pooling变为WxH=(M/16)x(N/16)大小,其中feature_stride=16则保存了该信息,用于计算anchor偏移量。
Proposal Layer forward按照以下顺序依次处理:
之后输出proposal=[x1, y1, x2, y2],注意,由于在第2步中将anchors映射回原图判断是否超出边界,所以这里输出的proposal是对应MxN输入图像尺度的,这点在后续网络中有用。另外我认为,严格意义上的检测应该到此就结束了,后续部分应该属于识别了。
通俗点来讲就是Proposal Layer会对RPN输出的分类和回归结果进行后处理(如NMS等),得到网络认为包含物体的区域,称为感兴趣的候选区域——RoI。至此,其实已经完成了定位任务,因为已经得到了包含物体的区域(bbox),只不过没有对物体类别进行细分,仅区分了前、背景。另外,由于anchor的位置和大小是人工预设的,且用于训练的样本有限,因此此处得到的检测结果可能并不够精准。
代码如下:
到这里RPN就解析完毕了。
六、RoI Pooling和Classifier
RoI Pooling就不再赘述。Classifier部分利用已经获得的proposal feature maps,通过full connect层与softmax计算每个proposal具体属于那个类别(如人,车,电视等);同时再次利用bounding box regression获得每个proposal的位置偏移量bbox_pred,用于回归更加精确的目标检测框。Classification部分网络结构如下图。
从RoI Pooling获取proposal feature maps后,送入后续网络,可以看到做了如下2件事:
注意,这里回归的结果是预测框中心点相对于正样本RoIs中心点坐标的位移以及两者长宽的比例,并且是归一化(减去均值除以标准差)后的结果。
代码如下:
在训练分类器和RoI边框修正时,步骤如下所示:
1) 首先通过RPN生成约20000个anchor(40×60×9)。
2) 对20000个anchor进行第一次边框修正,得到修订边框后的proposal。
3) 对超过图像边界的proposal的边进行clip,使得该proposal不超过图像范围。
4) 忽略掉长或者宽太小的proposal。
5) 将所有proposal按照前景分数从高到低排序,选取前12000个proposal。
6) 使用阈值为0.7的NMS算法排除掉重叠的proposal。
7) 针对上一步剩下的proposal,选取前2000个proposal进行分类和第二次边框修正。
总的来说,Faster R-CNN的loss分两大块,第一大块是训练RPN的loss(包含一个SoftmaxLoss和SmoothL1Loss),第二大块是训练Fast R-CNN中分类器的loss(包含一个SoftmaxLoss和SmoothL1Loss),其实原论文中训练方法特别复杂,但是现在大多直接采用RPN Loss + Fast R-CNN Loss的联合训练方法。
宝藏UP主: Bubbliiiing的个人空间_哔哩哔哩_Bilibili