这里写目录标题
该文章中的内容借鉴(搬用)了很多知乎文章-一文读懂Faster RCNN的内容,但是也做了一些整理与删减。
R-CNN
R-CNN的思想很简单就是:region proposal与CNN相结合。
- Region proposal:R-CNN采用“选择搜索”策略进行区域提取。会选择2000个ROIs(Region Proposal of Interest)
- 特征提取:使用CNN对每个ROI进行特征提取然后判断该ROI所属的类别。
可以看到选出的2000个ROIs的大小不同,因此在输入到CNN进行特征提取之前要进行图像的大小变换。
原文中的各向同性以及各向异性缩放参考
R-CNN一个非常严重的问题就是慢!
- 使用Selective Search搜索ROI区域的算法很耗时
- 要对每个ROI分别进行特征提取,计算速度非常慢
bounding-box regression
在RCNN的论文中,作者指出:主要的错误是源于mislocalization。为了解决这个问题,作者使用了bounding box regression。
如下图所示绿色框为飞机的Ground Truth(GT),红色为提取的positive
anchors,即便红色的框被分类器识别为飞机,但是由于红色的框定位不准,这张图相当于没有正确的检测出飞机。所以我们希望采用一种方法对红色的框进行微调,使得positive anchors和GT更加接近。
对于窗口一般使用四维向量 (x,y,w,h) 表示,分别表示窗口的中心点坐标和宽高。下图,红色的框A代表原始的positive Anchors,绿色的框G代表目标的GT,
我们的目标是寻找一种关系,使得输入原始的anchor A经过映射得到一个跟真实窗口G更接近的回归窗口G’(即图中的蓝色框),即:
- 给定anchor A = ( A x , A y , A w , A h ) A=(A_x,A_y,A_w,A_h) A=(Ax,Ay,Aw,Ah)和 G T = ( G x , G y , G w , G h ) GT=(G_x,G_y,G_w,G_h) GT=(Gx,Gy,Gw,Gh)
- 寻找一种变换 F F F,使得: F ( A x , A y , A w , A h ) = ( G x ′ , G y ′ , G w ′ , G h ′ ) F(A_x,A_y,A_w,A_h)=(G'_x,G'_y,G'_w,G'_h) F(Ax,Ay,Aw,Ah)=(Gx′,Gy′,Gw′,Gh′),其中 ( G x ′ , G y ′ , G w ′ , G h ′ ) ≈ ( G x , G y , G w , G h ) (G'_x,G'_y,G'_w,G'_h)\approx(G_x,G_y,G_w,G_h) (Gx′,Gy′,Gw′,Gh′)≈(Gx,Gy,Gw,Gh)
那么经过何种变换F才能从图10中的anchor A变为G’呢? 比较简单的思路就是:
观察上面4个公式发现,需要学习的是
d
x
(
A
)
,
d
y
(
A
)
,
d
w
(
A
)
,
d
h
(
A
)
d_x(A),d_y(A),d_w(A),d_h(A)
dx(A),dy(A),dw(A),dh(A) 这四个变换。当输入的anchor A与GT相差较小时,可以认为这种变换是一种线性变换, 那么就可以用线性回归来建模对窗口进行微调。 (注意,只有当anchors A和GT比较接近时,才能使用线性回归模型,否则就是复杂的非线性问题了)。
为什么当A和GT比较接近时才可以使用线性变换进行窗口微调的解释
Fast R-CNN
思想:首先对整张图像进行特征提取,然后将ROI区域映射到特征图中,然后可以直接得到每个ROI区域的特征图,直接进行分类即可。
Fast RCNN缺点:仍然用了Selective Search,还是比较耗时。
ROI Pooling
作用:将大小不一致的ROIs转化为大小一致,然后才能输入到CNN中。
操作思想:对于每个Region Proposal,划分成N* M个块(N,M代表期望的输出大小),在每个块中选取最大值作为该块的代表值保留(max pooling)。最终可以得到一个N*M大小的输出。
这种ROI Pooling操作因为不是等分,因此可能存在一些问题。
Faster R-CNN
最大的特点:提出了一个Region Proposal Network取代了Fast R-CNN中的Selective Search操作。
详细一点的架构图:
Faster RCNN主要包含以下部分:
- Conv layers图像特征提取。 作为一种CNN网络目标检测方法,Faster RCNN首先使用一组基础的conv+relu+pooling层提取image的feature maps。该feature
maps被共享用于后续RPN层和全连接层(ROI Pooling)。 - Region Proposal Networks (RPN)网络。用于生成region proposals。该层通过softmax判断anchors属于positive或者negative,再利用bounding box regression修正anchors获得精确的proposals。
- Roi Pooling。该层收集输入的feature maps和proposals,综合这些信息后提取proposal feature maps,送入后续全连接层判定目标类别。
- Classification。利用proposal feature maps计算proposal的类别,同时再次bounding box regression获得检测框最终的精确位置
Conv Layers
Conv layers包含了conv,pooling,relu三种层。以python版本中的VGG16模型网络结构为例,Conv layers部分共有13个conv层,13个relu层,4个pooling层。
关注点1:Conv layers中的conv层不改变输入和输出矩阵大小:
在Conv layers中:
- 所有的conv层都是:kernel_size=3,pad=1,stride=1
- 所有的pooling层都是:kernel_size=2,pad=0,stride=2
在Faster RCNN Conv layers中对所有的卷积都做了扩边处理( pad=1,即填充一圈0),导致原图变为 (M+2)x(N+2)大小,再做3x3卷积后输出为MxN,与原始图像等大 。
关注点2:pooling层使输出长宽都变为输入的1/2:
Conv layers中的pooling层kernel_size=2,stride=2。这样每个经过pooling层的MxN矩阵,都会变为(M/2)x(N/2)大小。
综上所述,在整个Conv layers中,conv和relu层不改变输入输出大小,只有pooling层使输出长宽都变为输入的1/2。
一个MxN大小的矩阵经过Conv layers固定变为(M/16)x(N/16)!这样Conv layers生成的feature map中都可以和原图对应起来。
Region Proposal Network(RPN)
Faster RCNN则抛弃了传统的滑动窗口和SS(Selective Search)方法,直接使用RPN生成检测框,这也是Faster R-CNN的巨大优势,能极大提升检测框的生成速度。
anchor
对于feature map中的每个像素,RPN会得到k个(9个)不同尺度的anchor,作为初始的检测框。
9个矩形共有3种形状,长宽比为大约为 {w:h=1:1,1:2,2:1} 三种
实际代码中anchor的生成步骤:
首先生成9个base anchor,然后通过坐标偏移在
M
∗
N
M*N
M∗N大小的
1
/
16
1/16
1/16 下采样FeatureMap每个点都放上这9个base anchor,就形成了
M
∗
N
/
16
∗
9
M*N/16*9
M∗N/16∗9个anhcors。至于这9个base anchor坐标是什么其实并不重要,不同代码实现也许不同。
显然这里面有一部分边缘anchors会超出图像边界,而真实中不会有超出图像的目标,所以会有clip anchor步骤。
RPN网络结构
包含下面两条线:
- 上面一条通过softmax分类anchors获得positive和negative分类(有无目标),
- 下面一条用于计算anchors的bounding box regression偏移量,以获得精确的proposal。
- 最后的Proposal层则负责综合positive anchors和对应bounding box regression偏移量获取proposals,同时剔除太小和超出边界的proposals。
其实整个网络到了Proposal Layer这里,就完成了相当于目标定位的功能。
网络维度的变化:
- 在原文中使用的是ZF model中,其Conv Layers中最后的conv5 num_output=256,对应生成256张特征图,所以相当于feature map每个点都是256-dimensions
- 在conv5之后,做了rpn_conv/3x3卷积且num_output=256,相当于每个点又融合了周围3x3的空间信息(猜测这样做也许更鲁棒?反正我没测试),同时256-d不变
- 假设在conv5 feature map中每个点上有k个anchor(默认k=9),而每个anhcor要分positive和negative,所以每个点由256d feature转化为cls=2•k scores;而每个anchor都有(x, y, w, h)对应4个偏移量,所以reg=4•k coordinates
- 补充一点,全部anchors拿去训练太多了,训练程序会在合适的anchors中随机选取128个postive anchors+128个negative anchors进行训练(什么是合适的anchors下文5.1有解释)
其实RPN最终就是在原图尺度上,设置了密密麻麻的候选Anchor。然后用cnn去判断哪些Anchor是里面有目标的positive anchor,哪些是没目标的negative anchor。所以,仅仅是个二分类而已!
对anchors进行softmax二分类
在使用softmax进行positive/negative二分类时,原来的特征维度为[1,2x9,H,W] 需要通过reshape layer将特征变为[1, 2, 9xH, W]大小,即单独“腾空”出来一个维度以便softmax分类,之后再reshape回复原状。
对anchors进行bounding box regression
可以看到输出为36,表示每个像素点生成k=9个anchor,对于每个anchor需要4个变量用于回归。9x4=36。
proposal layer
Proposal Layer负责综合所有 d x ( A ) , d y ( A ) , d w ( A ) , d h ( A ) d_x(A),d_y(A),d_w(A),d_h(A) dx(A),dy(A),dw(A),dh(A) 变换量和positive anchors,计算出精准的proposal,送入后续RoI Pooling Layer。
proposal layer有三个输入:softmax分类结果;bbox reg结果;img_info(这是啥呢,继续向下看~~),另外还有参数feat_stride=16
im_info: 对于一副任意大小PxQ图像,传入Faster RCNN前首先reshape到固定MxN,im_info=[M, N, scale_factor]则保存了此次缩放的所有信息。
feature_stride=16: 然后经过Conv Layers,经过4次pooling变为WxH=(M/16)x(N/16)大小,其中feature_stride=16则保存了该信息,用于计算anchor偏移量。
- 生成anchors,利用[公式]对所有的anchors做bbox regression回归(这里的anchors生成和训练时完全一致)
- 按照输入的positive softmax scores由大到小排序anchors,提取前pre_nms_topN(e.g.6000)个anchors,即提取修正位置后的positive anchor
- 限定超出图像边界的positive anchors为图像边界,防止后续roi pooling时proposal超出图像边界(见文章底部QA部分图21)
- 剔除尺寸非常小的positive anchors 对剩余的positive anchors进行NMS(nonmaximum suppression)
- Proposal Layer有3个输入:positive和negative anchors分类器结果rpn_cls_prob_reshape,对应的bbox reg的(e.g. 300)结果作为proposal输出
之后输出proposal=[x1, y1, x2, y2],注意,由于在第三步中将anchors映射回原图判断是否超出边界,所以这里输出的proposal是对应MxN输入图像尺度的,这点在后续网络中有用。另外我认为,严格意义上的检测应该到此就结束了,后续部分应该属于识别了。
FPN
Fast R-CNN还存在的缺点:是一个单尺度single scale目标检测模型。
单尺度: 最原始的Faster R-CNN使用的VGG网络架构,选择最后一层的特征图(77512)进行RPN操作,该特征图虽然包含很多语义信息,但是分辨率非常小,相比于原始图像会损失很多位置信息。
因此,Faster R-CNN还设计了一个FPN模块。
FPN思想:融合多层的feature map 。
如图(d)实现了多层的特征融合。
好处:可以实现精准定位又有很强的语义信息。
问题:
ROI到底在哪个特征图上进行提取?
有时间需要看看FasterRCNN的论文。(flag+1)
Faster-RCNN的训练
懒得写了,留着吧。