Faster-RCNN 的网络框架如下:
整体结构
1.首先输入图片经过一个神经网络生成层次比较深的feature map,这个网络目前来说比较流行的就是resnet101,然后在这个feature map 上进行两个分支,其中一个输入到RPN网络。
2.进行region的一个proposal,类似于rcnn中使用selective search进行的区域提取,在feature map上提取出来region后,需要对每个region对应的anchor进行一个二分类,判断其是前景(存在物体)还是后景(不存在)。在这里还要对bounding box第一次做一个回归,使anchor对ground truth有一定的逼近。
3.之后是另一条路,输入的是feature map和RPN网络给出的region,首先进行ROI pooling层,使这一层网络输出的向量维度统一。
4.最终对每个region进行一个分类,判断物体的类别,使用全连接,再输入到softmax中进行预测。使用L1 Loss再次进行一次bounding box的回归,输出类别和框选。
网络结构
摘自 https://www.cnblogs.com/wangyong/p/8513563.html
1.Conv layers
Faster RCNN首先是支持输入任意大小的图片的,比如上图中输入的PQ,进入网络之前对图片进行了规整化尺度的设定,如可设定图像短边不超过600,图像长边不超过1000,我们可以假定MN=1000*600(如果图片少于该尺寸,可以边缘补0,即图像会有黑色边缘)
① 13个conv层:kernel_size=3,pad=1,stride=1;
卷积公式:
所以,conv层不会改变图片大小(即:输入的图片大小=输出的图片大小)
② 13个relu层:激活函数,不改变图片大小
③ 4个pooling层:kernel_size=2,stride=2;pooling层会让输出图片是输入图片的1/2
经过Conv layers,图片大小变成(M/16)(N/16),即:6040(1000/16≈60,600/16≈40);则,Feature Map就是6040512-d(注:VGG16是512-d,ZF是256-d),表示特征图的大小为60*40,数量为512
2.RPN(Region Proposal Networks)
Feature Map进入RPN后,先经过一次33的卷积,同样,特征图大小依然是6040,数量512,这样做的目的应该是进一步集中特征信息,接着看到两个全卷积,即kernel_size=1*1,p=0,stride=1;
如上图中标识:
① rpn_cls:6040512-d ⊕ 1151218 ==> 604092
逐像素对其9个Anchor box进行二分类
② rpn_bbox:6040512-d ⊕ 1151236==>604094
逐像素得到其9个Anchor box四个坐标信息(其实是偏移量,后面介绍)
如下图所示:
Anchor生成
前面提到经过Conv layers后,图片大小变成了原来的1/16,令feat_stride=16,在生成Anchors时,我们先定义一个base_anchor,大小为1616的box(因为特征图(6040)上的一个点,可以对应到原图(1000600)上一个1616大小的区域),源码中转化为[0,0,15,15]的数组,参数ratios=[0.5, 1, 2]scales=[8, 16, 32]
先看[0,0,15,15],面积保持不变,长、宽比分别为[0.5, 1, 2]是产生的Anchors box
如果经过scales变化,即长、宽分别均为 (168=128)、(1616=256)、(16*32=512),对应anchor box如图
综合以上两种变换,最后生成9个Anchor box
所以,最终base_anchor=[0,0,15,15]生成的9个Anchor box坐标如下:
1 | 1 [[ -84. -40. 99. 55.] |
特征图大小为6040,所以会一共生成6040*9=21600个Anchor box
源码中,通过width:(060)*16,height(040)*16建立shift偏移量数组,再和base_ancho基准坐标数组累加,得到特征图上所有像素对应的Anchors的坐标值,是一个[216000,4]的数组
Bounding Box regression
这个对于CVPR2019的一篇MOT是个基础,需要再次深入理解一下。
例如绿色的框是ground truth,而红色是我们的一个region,它们都代表了框内的物体是个飞机,但是我们现在的红色的框明显不是很精确,于是我们需要用一个小网络,使红色的框尽可能的接近绿色的GT,这就是BBox回归的思想。我的理解就是,随便在图片上选取一个有物体的框,让网络自己去适应最好的结果,也就是我给你的虽然不是很好,但是要让你自己去把好的给我找到,让网络自己学习一个好的效果,感觉十分的需要训练集的强大。
那么经过何种变换才能从图 2 中的窗口 P 变为窗口G^G^呢? 比较简单的思路就是: 平移+尺度放缩
先做平移(Δx,Δy)(Δx,Δy), Δx=Pwdx(P),Δy=Phdy(P)Δx=Pwdx(P),Δy=Phdy(P) 这是R-CNN论文的:
G^x=Pwdx(P)+Px,(1)
G^x=Pwdx(P)+Px,(1)
G^y=Phdy(P)+Py,(2)
G^y=Phdy(P)+Py,(2)
然后再做尺度缩放(Sw,Sh)(Sw,Sh), Sw=exp(dw(P)),Sh=exp(dh(P))Sw=exp(dw(P)),Sh=exp(dh(P)), 对应论文中:
G^w=Pwexp(dw(P)),(3)
G^w=Pwexp(dw(P)),(3)
G^h=Phexp(dh(P)),(4)
G^h=Phexp(dh(P)),(4)
观察(1)-(4)我们发现, 边框回归学习就是dx(P),dy(P),dw(P),dh(P)dx(P),dy(P),dw(P),dh(P)这四个变换。下一步就是设计算法那得到这四个映射。
线性回归就是给定输入的特征向量 X, 学习一组参数 W, 使得经过线性回归后的值跟真实值 Y(Ground Truth)非常接近. 即Y≈WXY≈WX 。 那么 Bounding-box 中我们的输入以及输出分别是什么呢?
ROI Pooling 层
输入RPN层产生的region proposal,也就是在原图上的回归后的anchor(region)转化而成的feature框,再输入原feature map(如果是VGG net就是将region缩小16倍)。根据ROI Pooling 层的网络参数,pooled_w:7,pooled_h:7将区域划分为7×7个区域,每个小区域上max pooling形成一个7×7的feature map。将例如300个region proposal遍历,形成[300,512,7,7]的张量输入到全连接层。
之后就比较好理解了,做了分类和第二次更精确的回归。