RPN网络

RPN网络RPN思路:1、先通过conv层+pooling层+relu层,可以是vgg,得到featuremaps。2、在featuremaps上提取对应的图。在第一步基础上,先通过rpn生成regionproposals。通过softmax判断anchors(9个框),是foreground还是background,再通过boundingboxregression…

大家好,又见面了,我是你们的朋友全栈君。

RPN

       这里写图片描述 

思路:

1、先通过conv层+pooling层+relu层,可以是vgg,得到feature maps。

2、在feature maps上提取对应的图。在第一步基础上,先通过rpn生成region proposals。通过softmax判断anchors(9个框),是foreground还是background,再通过bounding box regression 进行修正anchors,也就是进一步确定proposals。

3、目的是为了得到proposals feature maps,提取框的特征图,这一步是为了下面的分类做准备,也就是先得到框图在分类。这一步先通过上面得到的proposals,和roi pooling,提取proposals feature maps。

4、分类。用proposals feature maps和一开始的proposals判断类别。

RPN网络

1、一个图片从由p*q大小,变为m*n大小(600*1000),进入网络,经过13个conv,13个relu,4个pooling。得到feature maps(40*60*256)。

2、先经过3*3conv,经过1*1conv,分成foreground和background,上面一条线是通过softmax分类anchor,获得foreground和background,下面计算anchor的boundingboxregression偏移情况。然后计算出来proposals。

3、roi pooling,用proposals从最一开始的feature maps,通过全连接和softmax,分类。

步骤:

1、卷积层

    包括conv,relu,pooling。以vgg16为例,13个conv参数为kernelsize为3*3,pad为1,4个pooling为2*2,stride为2,一个图形进去网络出来后大小为m/16 ,n/16的feature maps。

2、region proposal networks(RPN)
RPN网络

  • 上面一层目的是为了完成分类anchors(9个框),以获得foreground和background,目的是留着foreground。
  • 下面是对anchors进行bounding box regression,为了得到精准的参数,可以帮助后面得到精准的proposal。
  • 最后proposal是为了整合上面两个步骤得到proposal。

     从第一层说,进入3*3前图形是m/16 ,n/16的feature maps,进行3*3卷积应该是为了更好融合每个点周围的信息,每个点都有9个anchors,如下所示:每个点都有256-d,每个点都要对框分fore和back,为2个维度,所以为2k,k为9个框,所以每个点输出为W*H*18。同理回归是需要四个值定框,分别为左上右下,4个维度,所以为4k,为W*H*36。虽然文章里面有些到,但是其实在程序里面没有这样的内容,找不到所谓的框和所谓框的四个维度。

     proposals layer 3个输入,一个是分类器结果foreground,一个是anchor回归结果reg,还有一个是im-info,就是把图像进行了缩减后,进行proposal layer。

1、先再生成anchor,对做reg回归。

2、按照输入foreground softmax scores对anchor排序。目的找到最优anchor(2000个)。

3、通过feat_stride和im_info,把anchor映射回原图。

4、nms。

5、按照nms由大到小排序foreground anchors。提取top作为结果输出proposal(256个)。

from:https://blog.csdn.net/N_Sapientia/article/details/81487968


 

RPN网络

这里介绍一下分类层中的两个reshape操作:

   对于cls层,使用1*1的卷积操作输出了18(9个anchor*2类fg/bg)个通道的feature map,大小不变。而对于regression层,也使用1*1的卷积层输出了36(4*9个anchor)个通道的feature map,大小不变。 

   对于cls层后又接了一个reshape层,其实只是为了便于softmax分类,这就要从caffe的实现形式说起了。在caffe基本数据结构blob中以如下形式保存数据:blob=[batch_size, channel,height,width]

   对应至上面的保存bg/fg anchors的矩阵,其在caffe blob中的存储形式为[1, 2*9, H, W]。而在softmax分类时需要进行fg/bg二分类,所以reshape layer会将其变为[1, 2, 9*H, W]大小,即单独“腾空”出来一个维度以便softmax分类,之后再reshape回复原状。

                         RPN网络

从中其实我们也能发现,对于rpn每个点的18个输出通道,前9个为背景的预测分数,而后9个为前景的预测分数。

   对于regression,不需要这样的操作,那么他的36个通道是不是也是如上面18个通道那样呢?即第一个9通道为dx,第二个为dy,第三个为dw,第五个是dh。还是我们比较容易想到的那种,即第一个通道是第一个盒子的回归量(dx1,dy1,dw1,dh1),第二个为(dx2,dy2,dw,2,dh2)…..。待后面查看对应的bbox_targets就知道了

正如图上所示,我们还需要准备一个层rpn-data。

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"
  }
}

这一层输入四个量:data,gt_boxes,im_info,rpn_cls_score,其中前三个是我们在前面说过的,

data:         1*3*600*1000 
gt_boxes: N*5,                   N为groundtruth box的个数,每一行为(x1, y1, x2, y2, cls) ,而且这里的gt_box是经过缩放的。
im_info: 1*3                   (h,w,scale) 

rpn_cls_score是cls层输出的18通道,shape可以看成是1*18*H*W.  

输出为4个量:

rpn_labels : (1, 1, 9 * height, width)

rpn_bbox_targets(回归目标): (1, 36,height, width)

rpn_bbox_inside_weights(内权重):(1, 36,height, width)

rpn_bbox_outside_weights(外权重):(1, 36,height, width)

通俗地来讲,这一层产生了具体的anchor坐标,并与groundtruth box进行了重叠度计算,输出了kabel与回归目标。

       regression可以利用rpn_bbox_pred,rpn_bbox_targets,rpn_bbox_inside_weights,rpn_bbox_outside_weights计算SmoothL1Loss,输出rpn_loss_bbox。

回到我们之前有一个问题rpn_bbox_pred的shape怎么构造的。其实从rpn_bbox_targets的生成过程中可以推断出应该采用后一种,即第一个盒子的回归量(dx1,dy1,dw1,dh1),第二个为(dx2,dy2,dw,2,dh2)…..,这样顺序着来。

from:https://blog.csdn.net/alibabazhouyu/article/details/80875383

RPN结构流程图:

                  RPN网络

Note:

  1. 只有在train时,cls+reg才能得到强监督信息(来源于ground truth)。即ground truth会告诉cls+reg结构,哪些才是真的前景,从而引导cls+reg结构学得正确区分前后景的能力;在测试阶段,就要靠cls+reg自力更生了。
  2. 在train阶段,会输出约2000个proposal,但只会抽取其中256个proposal来训练RPN的cls+reg结构;到了测试阶段,则直接输出最高score的300个proposal。此时由于没有了监督信息,所有RPN**并不知道这些proposal是否为前景**,整个过程只是惯性地推送一波无tag的proposal给后面的Fast R-CNN。

RPN网络

1、在 RPN头部 ,通过以下结构生成 anchor(其实就是一堆有编号有坐标的bbox);  

2、在 RPN中部, 分类分支(cls) 和 边框回归分支(bbox reg) 分别对这堆anchor进行计算。Note: two stage型的检测算法在RPN 之后 还会进行 再一次 的 分类任务 和 边框回归任务,以进一步提升检测精度;

3、在 RPN末端,通过对 两个分支的结果进行汇总,来实现对anchor的 初步筛除(先剔除越界的anchor,再根据cls结果通过NMS去重)和 初步偏移(根据bbox reg结果),此时输出的都改头换面叫 Proposal 。


损失函数_add_losses

faster rcnn包括两个损失:rpn网络的损失+rcnn网络的损失。其中每个损失又包括分类损失和回归损失。分类损失使用的是交叉熵,回归损失使用的是smooth L1 loss。

其中rpn_cross_entropy和rpn_loss_box是RPN网络的两个损失,cls_score和bbox_pred是rcnn网络的两个损失。前两个损失用于判断archor是否是ground truth(二分类);后两个损失的batchsize是256。

将rpn_label(1,?,?,2)中不是-1的index取出来,之后将rpn_cls_score(1,?,?,2)及rpn_label中对应于index的取出,计算sparse_softmax_cross_entropy_with_logits,得到rpn_cross_entropy。

计算rpn_bbox_pred(1,?,?,36)和rpn_bbox_targets(1,?,?,36)的_smooth_l1_loss,得到rpn_loss_box。

rpn_bbox_targets= bbox_targets = _compute_targets(anchors, gt_boxes[argmax_overlaps, :])  # 通过archors和archors对应的正样本计算坐标的偏移

计算cls_score(256*21)和label(256个正样本和负样本对应的真实的类别)的sparse_softmax_cross_entropy_with_logits:cross_entropy。

labels, rois, roi_scores, bbox_targets, bbox_inside_weights = _sample_rois(all_rois, all_scores, gt_boxes, fg_rois_per_image, rois_per_image, _num_classes) # 选择256个archors

计算bbox_pred(256*84)和bbox_targets(256*84)的_smooth_l1_loss:loss_box。

最终将上面四个loss相加,得到总的loss(还需要加上regularization_loss)。

至此,损失构造完毕。

RPN网络RPN网络

def _add_losses(self, sigma_rpn=3.0):
    with tf.variable_scope('LOSS_' + self._tag) as scope:
        rpn_cls_score = tf.reshape(self._predictions['rpn_cls_score_reshape'], [-1, 2])  # 每个archors是正样本还是负样本
        rpn_label = tf.reshape(self._anchor_targets['rpn_labels'], [-1])  # 特征图中每个位置对应的是正样本、负样本还是不关注(去除了边界在图像外面的archors)
        rpn_select = tf.where(tf.not_equal(rpn_label, -1))    # 不关注的archor到的索引
        rpn_cls_score = tf.reshape(tf.gather(rpn_cls_score, rpn_select), [-1, 2])    # 去除不关注的archor
        rpn_label = tf.reshape(tf.gather(rpn_label, rpn_select), [-1])        # 去除不关注的label
        rpn_cross_entropy = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(logits=rpn_cls_score, labels=rpn_label))  # rpn二分类的损失

        rpn_bbox_pred = self._predictions['rpn_bbox_pred']  #  每个位置的9个archors回归位置偏移
        rpn_bbox_targets = self._anchor_targets['rpn_bbox_targets']   # 特征图中每个位置和对应的正样本的坐标偏移(很多为0)
        rpn_bbox_inside_weights = self._anchor_targets['rpn_bbox_inside_weights']  # 正样本的权重为1(去除负样本和不关注的样本,均为0)
        rpn_bbox_outside_weights = self._anchor_targets['rpn_bbox_outside_weights']   #   正样本和负样本(不包括不关注的样本)归一化的权重
        rpn_loss_box = self._smooth_l1_loss(rpn_bbox_pred, rpn_bbox_targets, rpn_bbox_inside_weights, rpn_bbox_outside_weights, sigma=sigma_rpn, dim=[1, 2, 3])

        cls_score = self._predictions["cls_score"]  # 用于rcnn分类的256个archors的特征
        label = tf.reshape(self._proposal_targets["labels"], [-1])   # 正样本和负样本对应的真实的类别
        cross_entropy = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(logits=cls_score, labels=label))   # rcnn分类的损失

        bbox_pred = self._predictions['bbox_pred']   # RCNN, bbox loss
        bbox_targets = self._proposal_targets['bbox_targets']    # 256*(4*21)的矩阵,只有为正样本时,对应类别的坐标才不为0,其他类别的坐标全为0
        bbox_inside_weights = self._proposal_targets['bbox_inside_weights']  # 256*(4*21)的矩阵,正样本时,对应类别四个坐标的权重为1,其他全为0
        bbox_outside_weights = self._proposal_targets['bbox_outside_weights']   # 256*(4*21)的矩阵,正样本时,对应类别四个坐标的权重为1,其他全为0
        loss_box = self._smooth_l1_loss(bbox_pred, bbox_targets, bbox_inside_weights, bbox_outside_weights)

        self._losses['cross_entropy'] = cross_entropy
        self._losses['loss_box'] = loss_box
        self._losses['rpn_cross_entropy'] = rpn_cross_entropy
        self._losses['rpn_loss_box'] = rpn_loss_box

        loss = cross_entropy + loss_box + rpn_cross_entropy + rpn_loss_box  # 总共的损失
        regularization_loss = tf.add_n(tf.losses.get_regularization_losses(), 'regu')
        self._losses['total_loss'] = loss + regularization_loss

        self._event_summaries.update(self._losses)

    return loss

RPN网络

 

caffe prototxt文件:https://github.com/rbgirshick/py-faster-rcnn/tree/master/models/pascal_voc/ZF/faster_rcnn_end2end

 

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/152276.html原文链接:https://javaforall.net

(0)
上一篇 2022年6月23日 下午4:36
下一篇 2022年6月23日 下午4:36


相关推荐

  • echarts中国地图(百度地图)

    echarts中国地图(百度地图)script varmyChart echarts init document getElementBy map vardata1 map safe vargeoCoordM 海门 121 15 31 89 鄂尔多斯 109 39 招远 120 38 37 35 舟山 122 29 齐齐哈尔 123 97 script

    2026年3月26日
    2
  • #Photoshop#_pdf文档解析失败

    #Photoshop#_pdf文档解析失败来源:导入AdobePhotoshop(.psd)图像AdobePhotoshop档案格式规格:https://www.adobe.com/devnet-apps/photoshop/fileformatashtml/#50577409_89817vs2017案例

    2022年5月3日
    49
  • 数据结构——HashMap

    数据结构——HashMap众所周知,HashMap是一个用于存储Key-Value键值对的集合,每一个键值对也叫做Entry。这些个键值对(Entry)分散存储在一个数组当中,这个数组就是HashMap的主干。HashMap数组每一个元素的初始值都是Null。对于HashMap,我们最常使用的是两个方法:Get和Put。1.Put方法的原理调用Put方法的时候发生了什么呢?…

    2022年5月12日
    46
  • 爬取7160美女图片

    爬取7160美女图片#coding=utf-8importurllib.requestfrombs4importBeautifulSoupfromurllibimporterrorimportrels=[‘zhenrenxiu’,’meinv’,"lianglichemo",’rentiyishu’,’xiaohua’]defvalidateTitle(title):rstr=r"…

    2025年8月2日
    6
  • 谷歌的发明者(天才纨绔)

    导读:本文为《金融时报》网站发表的一篇人物特写,文章的主角是GoogleChromeV8引擎的开发者拉斯巴克(LarsBak)。他是一个编程天才,却远离计算机世界的核心,在丹麦为Google工作。LarsBak在他的农场远离计算机世界核心奥尔胡斯(Aarhus)是丹麦第二大城市,也是日德兰半岛(Jutland)的非正式首府。在该市郊外5英里的地方,有一座改造过的农舍。里面有宽敞的木地

    2022年4月16日
    54
  • matlab数字图像处理常用操作

    matlab数字图像处理常用操作把图片加载到当前文件夹 strong 步骤 strong 1 读取图片 2 灰度化 3 二值化 4 去噪音 5 腐蚀膨胀 strong 过程 strong 1 读取图片 2 图像

    2026年3月16日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号