【目标检测】Faster RCNN

概述

Fast RCNN几乎已经是端到端的模型了,并且相较于RCNN速度上有了很大的提升,但是距离实时的检测还有一定距离,当前速度的瓶颈来自于候选框的生成,因为他是跑在CPU上的。所以本文就提出了一个Region Proposal Network(RPN),用于生成候选框,并且,在其中引入了anchor机制,解决多尺度检测的问题。也就是说,Faster RCNN=RPN+Fast RCNN

细节

网络结构

流程也和Fast RCNN几乎一样,唯一的区别就是候选框的生成方式
流程概述:

  1. 通过网络对原图进行特征提取
  2. RPN网络生成候选框
  3. 将候选框投影到特征图中,得到候选框特征,并对其进行ROI池化,得到固定尺寸的候选框特征
  4. 基于候选框特征进行分类和bbox回归(得到更加精确的检测框)

在这里插入图片描述
下图是一张更加具体一点的网络结构图(骨干网络用的是VGG16,输出的尺寸是 ( M / 16 , N / 16 ) (M/16,N/16) (M/16,N/16),这个网络的详情可以看这里):
在这里插入图片描述

RPN

PRN网络主要是用于候选框的生成,代替之前的选择性搜索方法,极大的提高了候选框生成的速度。它主要包括anchor生成、anchor分类、bbox回归微调anchor位置得到候选框这几个步骤。

理论上讲:在RPN之前我们已经对原图进行特征提取得到一个特征图,接着我们在特征图上进行滑动窗口,我们通过窗口的中心点像素的坐标计算它在原图中的像素位置,然后在这个位置上产生k个anchor(默认k=9)。然后我们再基于滑动窗口得到的特征,得到2k个anchor的分类情况和4k个位置回归参数,前者指的是当前位置的k个anchor是前景和是背景的概率,后者指的是当前位置的k个anchor进行位置调整需要的四个参数。注:这里的256-d是因为原论文采用的是ZF网络,输出特征图的通道数是256,这里表示的是一个窗口会生成一个 1 ∗ 1 ∗ 256 1*1*256 11256的向量
在这里插入图片描述

实际上讲:在RPN之前我们已经对原图进行特征提取得到一个特征图,接着我们对他进行一个3x3的same卷积(相当于是3x3的滑动窗口了,滑动窗口得到的特征就是卷积核一次运算得到的结果,并且卷积前后特征图尺寸不变),然后就是两路分支,一路使用1x1卷积将通道数调整为2k,经过softmax得到2k个类别概率,另一路使用1x1卷积将通道数调整为4k,使用全连接层得到4k个位置回归参数。
在这里插入图片描述
有了上述的这些,我们就能得到我们需要的候选框了,操作如下:

  1. 使用4k个位置回归参数对anchor进行位置调整
  2. 根据2k个类别概率得到所有的positive anchor,也就是将不包含前景目标的anchor去掉。对这些包含前景目标的anchor按照softmax中的得分进行排序,选取前N(如6000)个anchor
  3. 剔除掉超过图片边界的anchor,剔除掉尺寸非常小的anchor
  4. 对剩余的anchor进行NMS,最终留下的大概就是2000个左右的anchor,这些anchor就可以称作候选框了。

anchor:主要是用来解决多尺度预测的问题。以往解决多尺度问题的方法有图像金字塔(使用不同尺度的图像构建多个模型,让他们去检测不同尺度的对象)、卷积核设计(特征提取的时候使用不同尺度、不同尺寸的卷积核,希望得到更加具有表征能力的特征)。本文的anchor就是预设一组或者多组不同尺寸不同长宽比例的参考框,它的出现使得模型对一张图片只需要检测一次,就能得到对于不同尺寸和不同长宽比目标的优秀检测效果。具体的话,anchor就是一个预先设定好的矩形框,用一个四元式 ( x 1 , y 1 , x 2 , y 2 ) (x_1,y_1,x_2,y_2) (x1,y1,x2,y2)表示矩阵,包含矩形框左上角和右下角的坐标。

anchor产生:我们以原图中某一个像素点为中心,按照不同的尺度和横纵比得到若干个不同的矩形框,就是anchor。比如我们设置尺度和横纵比分别为 [ 8 , 16 , 32 ] 、 [ 0.5 , 1 , 2 ] [8,16,32]、[0.5,1,2] [8,16,32][0.512],使vgg16作为骨干网络。那么输入图像尺寸是 800 ∗ 600 800*600 800600,得到的特征图是尺寸是 c e i l ( 800 / 16 ) ∗ c e i l ( 600 / 16 ) = 50 ∗ 38 ceil(800/16)*ceil(600/16)=50*38 ceil(800/16)ceil(600/16)=5038,每一点对应原图的感受野是 16 ∗ 16 16*16 1616,所以按照比例得到的面积是: [ 16 ∗ 8 ∗ 16 ∗ 8 , 16 ∗ 16 ∗ 16 ∗ 16 , 16 ∗ 32 ∗ 16 ∗ 32 ] [16*8*16*8,16*16*16*16,16*32*16*32] [168168,16161616,16321632]也就是 [ 128 ∗ 128 , 156 ∗ 156 , 512 ∗ 512 ] [128*128,156*156,512*512] [128128,156156,512512]。现在有了三个面积,还有三个纵横比,我们就能得到9种组合就是9个anchor。上面我们提到,是将特征图上的点映射到原图中,然后产生anchor的,也就是说我们总共会产生 50 ∗ 38 ∗ 9 50*38*9 50389个anchor。注:vgg中最后输出特征图的感受野是 228 ∗ 228 228*228 228228但是最大框的面积会达到 512 ∗ 512 512*512 512512,超过我们的感受野了,作者认为这个是ok的,因为只知道目标的部分也是可以实现对整个目标的预测的,而最终的实验结果也说明了这点。
但是,产生了这么多的anchor,我们都用来训练吗?这就产生了正负样本的问题。正样本选择有两种标准,对于每一个gt box,选取与其IoU最大的anchor作为正样本,或者如果一个anchor至少与任意一个ground-truth box的IoU大于0.7,则认为这个anchor为正样本,打上标签为1。如果IoU小于0.3,则认为这个anchor为负样本,打上标签为0。那些IoU值位于(0.3,0.7)区间的anchor不参与训练,也就没有标签。正样本的第二条其实就够了,加上第一条能保证一定会有一定的正样本存在。

计算特征图上像素点在原图中的位置:原图width/特征图的width=stride_x,然后得到特征图中当前像素的x坐标,x * stride_x就得到了原图上对应点的x坐标,y坐标同理

bbox回归

我们可以发现Faster RCNN中有两次bbox回归,一次是将anchor的位置进行微调,另一次是对候选框进行微调,两次的操作其实是一样的,就是根据模型输出的四个位置参数调整原来的边框,让它和gt box更加接近。同样的操作在Fast RCNN和RCNN中也出现了。

我们知道一个框可以用四个参数来表示,分别是中心点的xy坐标以及框的宽和高,我们假设原来的框是 [ A x , A y , A w , A h ] [A_x,A_y,A_w,A_h] [Ax,Ay,Aw,Ah],而真实的表框gt box是 [ G x , G y , G w , G h ] [G_x,G_y,G_w,G_h] [Gx,Gy,Gw,Gh],我们需要寻找一个变换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]

一个简单的思路就是先平移再缩放,我们使用四个参数 [ t x , t y , t w , t h ] [t_x,t_y,t_w,t_h] [tx,ty,tw,th]就可以描述这个变化,如下:
G x " = A w ∗ t x + A x G^"_x=A_w*t_x+A_x Gx"=Awtx+Ax
G y " = A h ∗ t y + A y G^"_y=A_h*t_y+A_y Gy"=Ahty+Ay
G w " = A w ∗ e x p ( t w ) G^"_w=A_w*exp(t_w) Gw"=Awexp(tw)
G h " = A h ∗ e x p ( t h ) G^"_h=A_h*exp(t_h) Gh"=Ahexp(th)
也就是说,只要模型能够输出合适的参数 [ t x , t y , t w , t h ] [t_x,t_y,t_w,t_h] [tx,ty,tw,th],我们就可以实现对原有框的调整,使他更加接近gt box。那么我们怎么得到监督值呢?其实也简单,就是对上面式子的变形,训练的时候,我们有gt box的信息,有anchor box的信息,就可以得到变换F中的四个参数了,然后用这些真实的参数做监督,强迫网络进行学习。那么当推理的时候,网络就会输出较为合适的变换参数,我们也就可以完成对原边框的微调了。
t x = ( G x " − A x ) / A w t_x=(G^"_x-A_x)/A_w tx=(Gx"Ax)/Aw
t y = ( G y " − A y ) / A h t_y=(G^"_y-A_y)/A_h ty=(Gy"Ay)/Ah
t w = l o g ( G w " / A w ) t_w=log(G^"_w/A_w) tw=log(Gw"/Aw)
t h = l o g ( G h " / A h ) t_h=log(G^"_h/A_h) th=log(Gh"/Ah)

损失函数与训练

Faster RCNN论文中的训练步骤是先训练RPN网络,然后再训练整个Fast RCNN网络。但是两个部分的形式其实差不多,都是分类损失+回归损失,前者用交叉熵损失函数,后者用smooth L1损失函数,虽然长得和Fast RCNN不太一样,但其实是一样的。具体点可以看之前的分析:链接
在这里插入图片描述

在训练RPN的时候,一张图片随机选取256个anchors计算loss,正样本anchor和负样本anchor的比例是1:1,如果正样本的个数小于128,那么就用负样本来填充。

训练Faster RCNN作者没提,估计是和Fast RCNN中类似吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值