Faster Rcnn算法复现

Faster Rcnn算法复现


复现算法Faster Rcnn
Faster Rcnn算法原文链接: https://arxiv.org/abs/1506.01497

Faster Rnn 实现流程

Faster Rcnn是双阶段目标检测家族中的一员,由Rcnn -> Spp-net -> Fast Rcnn 再到Faster Rcnn,Faster Rcnn中首次使用深度学习的方法进行关键区域的提取,真正实现了end to end的目标检测,Faster Rcnn是双阶段目标检测系列最关键的节点,其后出现的Mask Rcnn与Cascade Rcnn都是基于Faster Rcnn而来,本次实现一个简要版的Faster Rcnn以增强自己对其的理解。
在之前参加天池比赛时,使用了Faster Rcnn和FPN,并做出了一定的改进也取得了不错的成绩,但当时是在mmdetection框架的基础上进行改进,难免无法顾及一些细节,通过这次从头开始实现Faster Rcnn和FPN,对细节方面有了更好的掌握,相信在实现了Faster Rcnn后,双步和和单步的目标检测算法我都可以进行简要版的复现,下图是Faster Rcnn的结构图。
图1
Faster Rcnn的实现分为五个阶段:

  1. 第一阶段,根据输入的图像和标注的框信息(后续称为ground-truth)计算anchor的真实标签和位移坐标,该阶段生成的anchor的真实标签和位移坐标将用于与RPN网络预测的anchor的标签和位移坐标计算RPN网络的损失以更新RPN网络的权重。
    假设输入图像大小为(800, 800),采用vgg16作为特征提取网络,下采样16倍,得到的特征图大小为(50,
    50),对特征图上的每个点,映射回原图产生anchor,假设设置anchor_scale为(8, 16,
    32),anchor_ratio为(0.5,1,2),那么每个位置将产生9个anchor,其中anchor_scale为anchor的大小,anchor_ratio为anchor的长宽比,需要注意的是,这里设置的anchor_scale是相对于特征图的,当映射回原图时需要乘以下采样倍数。对每个位置产生9个anchor,一共需要产生 50 ∗ 50 ∗ 9 50*50*9 50509即22500个anchor,对这些anchor进行anchor的定位和采样,即将anchor分配给与其具有最大iou的ground_trouth(会从中采样256个,别的忽略即label为-1,正负样本比例为1:1,根据iou判断正负样本),转换公式如式1、2、3、4。
    d x = ( g t x − a n c h o r x ) / a n c h o r w (1) dx=(gt_x-anchor_x)/anchor_w \tag{1} dx=(gtxanchorx)/anchorw(1)
    d y = ( g t y − a n c h o r y ) / a n c h o r h (2) dy=(gt_y-anchor_y)/anchor_h\tag{2} dy=(gtyanchory)/anchorh(2)
    d w = l o g ( g t w / a n c h o r w ) (3) dw=log(gt_w/anchor_w)\tag{3} dw=log(gtw/anchorw)(3)
    d h = l o g ( g t h / a n c h o r h ) (4) dh=log(gt_h/anchor_h)\tag{4} dh=log(gth/anchorh)(4)
    其中,dx、dy、dw、dh为anchor相对于ground_truth的位移坐标,gt_x、gt_y、gt_w、gt_h为ground_truth的中心坐标和宽高,anchor_x、anchor_y、anchor_w、anchor_h为anchor的中心坐标和宽高,同时根据anchor与ground_truth的iou来生成其真实标签(0或1),RPN网络只有前景和背景两种。该阶段的目的是对所有anchor生成其真实的位移坐标和标签,即gt_anchor_locations和gt_anchor_labels,用于联合RPN网络预测的pred_anchor_locations和pred_anchor_labels计算损失函数。

  2. 第二阶段,用RPN网络预测所有anchor的位移坐标和标签,即pred_anchor_locations和pred_anchor_labels。
    下图显示了RPN网络细节 如图3所示,为RPN网络的实现细节,在实际实现时,第一阶段产生的特征图大小为 50 ∗ 50 50*50 5050, 通道数为512,RPN网络由一个 3 ∗ 3 3*3 33的卷积核和两个 1 ∗ 1 1*1 11的卷积分支构成, 3 ∗ 3 3*3 33的卷积核加入了padding=1,即不改变原特征图的尺寸大小,两个 1 ∗ 1 1*1 11的卷积分支分别预测每个位置9个anchor的类别和位移坐标,因此此处输入为提取到的(50,50,512)的特征图,其中512为通道数,而输出为(50, 50,18)的类别预测和(50,50,36)的位移坐标预测。第二阶段产生的pred_anchor_labels和pred_anchor_locations将用于与第一阶段计算的gt_anchor_labels和gt_anchor_locations一起计算RPN阶段的损失loss。
    在这里插入图片描述

  3. 第三阶段,对第二阶段预测的anchor处理,根据第二阶段预测的pred_anchor_locations中的dx、dy、dw、dh结合初始anchor信息反向计算出RPN阶段预测的ground_truth的左上坐标和右下坐标(x1,y1,x2,y2),根据score对其进行排序,取前12000个进行nms,在nms后的剩余框中取前2000个,注意此时的pred_anchor_locations中存储的是反向推算出的预测框在原图上的位置,对剩下的这2000个框根据ground_truth进行采样和定位,计算出这2000个框相对于ground_truth的真实labels和位移坐标locations,根据iou进行采样和定位,与groud_truth的iou大于0.5的分为正样本,此时需要记录其对应的ground_truth的label,该部分标签为类别数,而不是前景背景(0,1),定位公式同第一阶段,然后对定位后的框进行采样,该阶段采样128个,其中正样本比例为0.25,该阶段最后产生的是根据RPN网络预测的pred_anchor_locations、pred_anchor_labels与ground_truth计算出的128个gt_roi_labels和gt_roi_locations。

  4. 第四阶段,第二阶段通过RPN网络产生了pred_anchor_labels和pred_anchor_locations,第三阶段从其中采样出了128个sample_rois,对这128个sample_rois计算出了其相对于ground_truth的真实标签和位移坐标即gt_roi_labels和gt_roi_locations,第四阶段将第三阶段采样出的sample_rois先送入roi pooling层获得 7 ∗ 7 ∗ 512 7*7*512 77512固定大小的特征图,然后将其拉平产生一个(1, 25088)的特征向量,然后送入两层全连接层得到(1,4096)的特征向量,最后通过两个全连接层分支,分别预测其类别(num_class+1)和位移坐标((num_class+1)*4),即pred_roi_labels和pred_roi_locations。

  5. 第五阶段,根据前四个阶段计算的结果计算损失,其中RPN阶段的损失通过gt_anchor_labels、gt_anchor_locations、pred_anchor_labels、pred_anchor_locations计算,ROI阶段的损失通过gt_roi_labels、gt_roi_locations、pred_roi_labels、pred_roi_locations计算,分类损失使用交叉熵损失函数计算,回归损失通过smooth L1损失函数计算,分别计算出rpn_cls_loss、rpn_loc_loss、roi_cls_loss、roi_loc_loss,计算损失时要注意,分类损失是对所有框进行计算,而回归损失只对样本标签有意义的框计算,因此在计算总损失时要在回归损失前乘以10或者使分类损失除以10,即
    rpn_loss = rpn_cls_loss/10 + rpn_loc_loss,
    roi_loss = roi_cls_loss/10+roi_loc_loss,
    total_loss = rpn_loss+roi_loss。
    最后根据损失更新权重。 交叉熵损失函数如式5所示,smooth L1损失如式6所示。
    L = − ∑ c = 1 M y c log ⁡ ( p c ) (5) L=-\sum_{c=1}^{M} y_{c} \log \left(p_{c}\right)\tag{5} L=c=1Myclog(pc)(5)
    L = { 0.5 x 2 , ∣ x ∣ < 1 ∣ x ∣ − 0.5 , ∣ x ∣ ≥ 1 (6) L=\left\{\begin{array}{cc}{0.5 \mathrm{x}^{2},} & {|x|<1} \\ {|x|-0.5,} & {|x| \geq 1}\end{array}\right.\tag{6} L={ 0.5x2,x0.5,x<1x1(6)

代码

辅助模块util.py

1.	import numpy as np  
2.	  
3.	def iou(valid_anchors, gt_box):  
4.	    # 传入两个box,左上坐标和右下坐标,大小为 n*4  
5.	    # 返回ious,((len(valid_anchors)*len(gt_box)))  
6.	    # 每个valid_anchor与每个gt_box都有iou,ious维度:(len(valid_anchors)*len(gt_box))  
7.	    valid_anchors_num = valid_anchors.shape[0]  
8.	    gt_box_num = gt_box.shape[0]  
9.	    ious = np.empty((valid_anchors_num, gt_box_num))  
10.	    ious.fill(0)  
11.	    for i, anchor in enumerate(valid_anchors):  
12.	        xa1, ya1, xa2, ya2 = anchor  
13.	        area1 
  • 4
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值