faster rcnn接口_faster-rcnn算法总结

faster-rcnn的整体流程比较复杂,尤其是数据的预处理部分,流程比较繁琐。我写faster-rcnn系列文章的目的是对该算法的原始版本有个整体的把握,如果需要使用该算法做一些具体的任务,推荐使用mmdetection框架,该框架使用PyTorch写成,相比于原始的基于caffe python接口的版本就简洁优雅多了。下面对改算法的整体过程做一个梳理,分为训练过程(端到端的训练)和测试过程两部分。本文注重算法原理,因此直接从如下的数据输入开始:

layer {

name: 'input-data'

type: 'Python'

top: 'data'

top: 'im_info'

top: 'gt_boxes'

python_param {

module: 'roi_data_layer.layer'

layer: 'RoIDataLayer'

param_str: "'num_classes': 2"

}

}

一、训练过程

1、输入数据经过一个ConvNet得到一个feature map(backbone的输出),记为bk_feat;

2、bk_feat经过1个3x3的Conv得到rpn/output;

3、从rpn/output分出两个分支:一个分支经过1个1x1的Conv,输出通道数为2*num_anchor,得到输出rpn_cls_score,它表示在feature map的每一个位置,每一个anchor内含有物体的概率。另一个分支经过1个1x1的Conv,输出通道数为4*num_anchor,得到输出rpn_bbox_pred,它表示网络预测出的,在feature map的每一个位置,每一个anchor相对于它“负责”的物体的真实边界框的偏移量dx, dy, dw, dh;

4、接下来是rpn-data层,该层的工作首先是生成anchor,然后按照一定的规则为anchor打上0(背景),1(前景),-1(忽略)标签,最后计算出每一个anchor相对于它“负责”的gt的偏移量dx, dy, dw, dh(bbox_targets),这个偏移量就是第一阶段的回归目标。

5、利用第4步得到的bbox_targets和第3步得到的rpn_bbox_pred产生第一阶段的SmoothL1Loss损失rpn_loss_bbox,同时用第4步得到的label和第3步得到的rpn_cls_score产生第一阶段的SoftmaxWithLoss损失rpn_loss_cls;

6、然后是proposal层,该层的工作首先也是生成anchor,然后将anchor和rpn_bbox_pred“相加”,得到proposal。然后经过NMS,从结果中选取分数最大的前2000个作为RPN网络产生的rois;

7、接着是roi-data层,该层的工作是从上面的rois中,按照前景:背景=1:3的比例选出总共128个rois,每个rois的label是它“负责”的gt(和该rois交并比最大的gt)的类别,背景rois的label为0。接下来与第4步一样,计算出每一个rois相对于它“负责”的gt的偏移量bbox_targets,作为第二阶段的回归目标。,所不同的是这个偏移量是和类别一一对应的,其它类别的偏移量都为0;

8、利用第6步得到的rois,从bk_feat中截取相应区域的feature,并对这个feature做经过2个FC,最后分出两个分支:一个分支经过1个FC,输出维度为num_class+1(num_class是数据集的类别个数,不包含背景),得到输出cls_score,它表示每个rois内含有的物体属于每个类别(包含背景)的概率。另一个分支经过1个FC,输出维度为4*(num_class+1),得到输出bbox_pred,它表示每个rois相对于它“负责”的每个类别(包含背景)的物体的真实边界框的偏移量dx, dy, dw, dh。

9、用第7步得到的bbox_targets和第8步得到的bbox_pred产生第二阶段的SmoothL1Loss损失loss_bbox,同时用第7步得到的label和第8步得到的cls_score产生第二阶段的SoftmaxWithLoss损失loss_cls。

二、测试过程

1、输入数据经过一个ConvNet得到一个feature map(backbone的输出),记为bk_feat;

2、bk_feat经过1个3x3的Conv得到rpn/output;

3、从rpn/output分出两个分支:一个分支经过1个1x1的Conv,输出通道数为2*num_anchor,得到输出rpn_cls_score,它表示在feature map的每一个位置,每一个anchor内含有物体的概率。另一个分支经过1个1x1的Conv,输出通道数为4*num_anchor,得到输出rpn_bbox_pred,它表示网络预测出的,在feature map的每一个位置,每一个anchor相对于它“负责”的物体的真实边界框的偏移量dx, dy, dw, dh;

4、接下来是proposal层,该层的工作首先是生成anchor,然后将anchor和rpn_bbox_pred“相加”,得到proposal。之后取分数最大的前6000个(训练时取前12000个)proposal进行NMS操作,overlap阈值是0.7,最后从结果中选取分数最大的前300个(训练时取前2000个)作为RPN网络产生的rois;

5、利用第4步得到的rois,从bk_feat中截取相应区域的feature,并对这个feature做经过2个FC,最后分出两个分支:一个分支经过1个FC,输出维度为num_class+1(num_class是数据集的类别个数,不包含背景),得到输出cls_prob,它表示每个rois内含有的物体属于每个类别(包含背景)的概率。另一个分支经过1个FC,输出维度为4*(num_class+1),得到输出bbox_pred,它表示每个rois相对于它“负责”的每个类别(包含背景)的物体的真实边界框的偏移量dx, dy, dw, dh。

6、将第4步得到的rois和第5步得到的bbox_pred“相加”得到bbox,它的shape为(num_rois, 4*(num_class+1))。因此,每一个bbox都和唯一的一个类别相对应,bbox的分数即为第5步得到的cls_prob。接下来对每一类物体,筛选出分数大于一定阈值(0.05)的bbox做NMS(overlap阈值是0.3),最后把所有类别的结果合并起来,得到的所有bbox和它们相应的分数即为最终的检测结果。该过程的部分代码摘录如下:

rois = net.blobs['rois'].data.copy()#unscale back to raw image space

boxes = rois[:, 1:5] /im_scales[0]

scores= blobs_out['cls_prob']

box_deltas= blobs_out['bbox_pred']

pred_boxes=bbox_transform_inv(boxes, box_deltas)

im=cv2.imread(imdb.image_path_at(i))

scores, boxes=im_detect(net, im, box_proposals)#skip j = 0, because it's the background class

for j in xrange(1, imdb.num_classes):

inds= np.where(scores[:, j] >thresh)[0]

cls_scores=scores[inds, j]

cls_boxes= boxes[inds, j*4:(j+1)*4]

cls_dets=np.hstack((cls_boxes, cls_scores[:, np.newaxis])) \

.astype(np.float32, copy=False)

keep=nms(cls_dets, cfg.TEST.NMS)

cls_dets=cls_dets[keep, :]ifvis:

vis_detections(im, imdb.classes[j], cls_dets)

all_boxes[j][i]= cls_dets

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值