Bounding box Regression分析
2018-04-04 10:20
197 查看
一. 问题的数学表达,回归的对象是什么?
我们一般最开始都有一个初始的BBox,但是这只是个粗略的BBox。比如RCNN,fastrcnn用Selective Search方法生成的一系列Proposals,faster-rcnn的anchors对应的boxes。这些都是粗略的框。我们最终要得到精确的位置框,所以需要用回归的方法精修BBox。因此,我们的输入是初始的BBox,需要找到一个映射把初始的BBox精修到最后Ground Truth。对应的数学描述如下:
二. 如何进行回归
下一步的问题就是设计算法得到这四个映射。
当输入的Proposals与Ground Truth相差较小时,(RCNN中设置的是IOU>0.6),可以认为这种变化是一种线性变化,因此可以用线性回归对该问题建模,从而微调窗口。
这样以来,我们回归的结果是原始Proposals需要微调的dx,dy,dw,dh。最后再使用下面的公式也就是上面的公式(1)~(4)得到最后的回归框。
三. rcnn中的实现
rcnn使用Selective Search的方法从一张图像生成约2000-3000个候选区域。基本思路如下:- 使用一种过分割手段,将图像分割成小区域
- 查看现有小区域,合并可能性最高的两个区域。
- 重复直到整张图像合并成一个区域位置
- 输出所有曾经存在过的区域,所谓候选区域
Rcnn中候选区域生成和后续步骤相对独立,也就是在rcnn网络中,提前用Selective Search的方法已经得到了上面将的候选框,即Px,Py,Pw,Ph。RCNN通过线性回归器进行每个候选框的精修工作,即回归器的输入为深度网络pool5层的4096维特征(这里使用的是alexnet),输出为xy方向的缩放和平移,即dx,dy,dh,dw。
由于rcnn比较简单,这里不再讲述,这列出一张计算t的实例代码。
下面会重点讲述faster rcnn。
四. Faster rcnn中的实现
Faster –rcnn中Bbox回归的实现。1.网络的RPN
RPN的核心思想是使用卷积神经网络直接产生region proposal,使用的方法本质上就是滑动窗口。Region ProposalNetwork(RPN)如下图:
RPN网络结构图如上所示(ZF模型:256维),假设给定600*1000的输入图像,经过卷积操作得到最后一层的卷积feature map(大小约为40*60),最后一层卷积层共有256个feature map。
在这个特征图上使用3*3的卷积核(滑动窗口)与特征图进行卷积,那么这个3*3的区域卷积后可以获得一个256维的特征向量。因为这个3*3的区域上,每一个特征图上得到一个1维向量,256个特性图即可得到256维特征向量。
3*3滑窗中心点位置,对应预测输入图像3种尺度(128,256,512),3种长宽比(1:1,1:2,2:1)的regionproposal,这种映射的机制称为anchor,产生了k=9个anchor。即每个3*3区域可以产生9个region proposal。所以对于这个40*60的feature map,总共有40*60个anchor,约20000(40*60*9)个proposal,也就是预测20000个region proposal。
下面是RPN回归的网络结构。
#========= RPN ============ layer { name: "rpn_conv/3x3" type: "Convolution" bottom: "conv5_3" top: "rpn/output" param { lr_mult: 1.0 } param { lr_mult: 2.0 } convolution_param { num_output: 512 kernel_size: 3 pad: 1 stride: 1 weight_filler { type: "gaussian" std: 0.01 } bias_filler { type: "constant" value: 0 } } } layer { name: "rpn_relu/3x3" type: "ReLU" bottom: "rpn/output" top: "rpn/output" } layer { name: "rpn_bbox_pred" type: "Convolution" bottom: "rpn/output" top: "rpn_bbox_pred" param { lr_mult: 1.0 } param { lr_mult: 2.0 } convolution_param { num_output: 36 # 4 * 9(anchors) kernel_size: 1 pad: 0 stride: 1 weight_filler { type: "gaussian" std: 0.01 } bias_filler { type: "constant" value: 0 } } } layer { name: 'rpn-data' type: 'Python' bottom: 'rpn_cls_score' bottom: 'gt_boxes' bottom: 'im_info' bottom: 'data' top: 'rpn_labels' top: 'rpn_bbox_targets' top: 'rpn_bbox_inside_weights' top: 'rpn_bbox_outside_weights' python_param { module: 'rpn.anchor_target_layer' layer: 'AnchorTargetLayer' param_str: "'feat_stride': 16" } } layer { name: "rpn_loss_bbox" type: "SmoothL1Loss" bottom: "rpn_bbox_pred" bottom: "rpn_bbox_targets" bottom: 'rpn_bbox_inside_weights' bottom: 'rpn_bbox_outside_weights' top: "rpn_loss_bbox" loss_weight: 1 smooth_l1_loss_param { sigma: 3.0 } }
rpn_bbox_pred层用卷积层,实现了线性回归,输出了36个通道的特征图。这里36表示每个anchors有9个boxes,每个box需要回归dx,dy,dw,dh四个参数。所以每个anchors一共对应4*9=36个值。如果输入40*60的feature map,总共有约40*60个anchors。
rpn_loss_bbox层计算损失函数,也就是上面分析的损失函数,即
只不过这里计算的是SmoothL1Loss,不求平方,另外第二项就是这里rpn_bbox_pred的输出,即rpn_bbox_pred。第一项就是真实值,即rpn_bbox_targets。
下面看看rpn_bbox_targets是怎么计算的。
在AnchorTargetLayer 层中完成了rpn_bbox_targets的计算。
AnchorTargetLayer位置在 py-faster-rcnn/lib/rpn中。
AnchorTargetLayer类中forward函数中计算了bbox_targets。
可见bbox_targets是用anchors和gt_box计算出来的。
下面分两步讲解,先讲一下_compute_targets的实现再讲anchors是怎么生成的。
(1)_compute_targets的实现。
AnchorTargetLayer类中实现了_compute_targets函数中。
bbox_transform函数位于py-faster-rcnn/lib/fast-rcnn/bbox_transform.py文件中。
可见,bbox_transform实现的功能,实际就是上面我们计算t的过程,即
这里的Px,Py,Ph,Pw就是上面计算的anchors,Gx,Gy,Gh,Gw就是上面gt_box,即我们提前标注的边界框。
(2)anchors怎么计算
下面是AnchorTargetLayer类中forward函数中用anchors的地方。
可是anchors怎么创建的呢?AnchorTargetLayer类中setup函数实现了这个功能。
generate_anchors位于py-faster-rcnn/lib/rpn/generate_anchors.py中。
可见,generate_anchors函数中定义的anchors的scale为2^3,2^4,2^5,即[8,16,32],由于_ratio_enum函数会将scale乘以base_size(16),即对应的预测的尺度变为(128,256,512)。另外Ratios为[0.5,1,2]。这里,和之前讲述RPN中所说的,对应预测输入图像3种尺度(128,256,512),3种长宽比(1:1,1:2,2:1)的region proposal是一致的。
base_anchor对应一个box的x,y,w,h。即一个region proposal的x,y,w,h。
ratio_anchors变量是对应3个不同比例的boxes的x,y,w,h;
_scale_enum(ratio_anchors[i,:], scales)中scales是个二维矩阵,矩阵为3行,每一行对应一个box的x,y,w,h,ratio_anchors[i,:]也是二维矩阵,矩阵为3行,每一行对应一个box的x,y,w,h。_scale_enum()返回二维矩阵,矩阵为9行,每一行对应一个box的x,y,w,h。即9个不同尺寸,不同rate的box的x,y,w,h。
anchors为特征图所有位置对应的box的x,y,w,h。每个位置对应9个不同尺寸,不同rate的box的x,y,w,h。
_ratio_enum函数定义如下:
_scale_enum函数定义如下:
五、SSD中的回归
Default Box 的生成SSD利用不同层的 feature map 来模仿学习不同尺度下物体的检测。假定使用 m 个不同层的feature map 来做预测,最底层的 feature map 的 scale 值S_min 为0.2,最高层的S_max为 0.95,其他层通过下面公式计算得到
六. mtcnn中的回归
这里只讲述mtcnn从回归的数据中如果恢复出最终的bbox。因为回归出来的4个数值是dx,dy,dh,dw。如何把这些转换成x,y,w,h。即使用下面的公式得到最后的回归框。下面以P网络的输出举例说明。
P网络的输出是out。
out第一行所有待选框回归出来的dx1,dy1, dx2,dy2,
out第二行是所有待选框的概率值。
1. 使用generateBoundingBox函数,将预测的概率的大于阈值的候选框的回归值挑选出来。
2. 用下式计算出来Bbox左上角的x,y,和右下角的x,y。这里的total_boxes[:,5]~ total_boxes[:,8]对应着回归出来的dx,dy。total_boxes[:,0]~ total_boxes[:,4]对应着原始候选框的左上角和右下角坐标。即下面的Px,Py。
下面是generateBoundingBox函数.
stride=2,表示候选框右下角的坐标就是左上角坐标的的2倍。
cellsize=12,表示选框右下角的坐标还需要平移12个单位。
P网络在训练时生成候选框的规则也应该是上面的方式。预测时,候选框的生成方式和训练是生成的候选框保持一致。
由于mtcnn在候选框生成时没有像faster-rcnn,一个anchors会生成不同尺度,不同rate的的候选框,所以mtcnn会一开始先生成图像的金字塔,生成不同尺度的图片,这样以来,最后的候选框就相当于有了不同尺度的候选框。
q1是预测的概率的大于阈值的候选框的左上角坐标(除以scale,转换为在原图中的坐标)。
q2是预测的概率的大于阈值的候选框的右下角坐标(除以scale,转换为在原图中的坐标)。
reg是对应的候选框回归的dx1,dy1, dx2,dy2。
相关文章推荐
- RCNN中bounding box regression理解(13)---《深度学习》
- bounding box regression
- 目标检测中bounding box regression
- Bounding-box Regression深度解析
- bounding-box regression
- RCNN - Bounding-box Regression 详解
- 关于RCNN中Bounding-box regression的个人理解
- Single Bounding Box Regression
- Bounding-box Regression
- Ogitor探索之代码分析(3)---CBaseEditor::showBoundingBox(bool bShow)
- 边框回归(Bounding Box Regression)详解
- 边框回归(Bounding Box Regression)详解
- iOS中自定义event原理分析与使用步骤
- IoC/DI入门,是什么、能干什么,分析IoC/DI的思想演变进程
- 环信UI开源Demo情景分析九、聊天界面(一)
- 通过Intent传输图片导致广播消息异常的问题根因分析(通过分析Android源码反向推理)
- java 动态代理机制分析及扩展
- 分析
- 生活中的数学:杀人游戏的理论分析
- .net Cookies安全性实践分析