faster rcnn结构及代码讲解

本篇博客主要讲解faster rcnn的基本结构及相关代码讲解。

总体结构介绍

faster_rcnn总体结构图
  从上图中我们可以看出,faster rcnn一共有三个部分,我们大致先说下:

  1.第一个部分为特征提取部分,经过卷积层得到特征图,也就是feature map
  2.第二个部分为RPN(region proposal network)区域候选网络,这是对fast rcnn重点改进的一部分,它的主要作用是得到感兴趣区域(ROI)。该网络会输出两个值,侯选框和分类(一张图像有许多候选框,分类这里分背景和物品也就是前景)
  3.分类回归层,这是最终的输出环节,最终输出目标图片预测框和分类

  这里可以看到1,3部分为主体结构;第2部分的主要作用是选择候选区域是一个辅助结构。

  RPN以及fast-RCNN主体结构均有预测输出,所以整个loss由4个部分组成(RPN的侯选框和分类,fast-RCNN主体结构的侯选框和分类)。需要关注的两点是:
1.两者候选框的回归任务,预测都是误差值,然后用在初始框上的
2.由前面的讲述不难理解,最终的框得到了两次修正,先产生最初的框,RPN修正一次,后面的回归分类任务修正一次。

具体代码及意义讲解

改代码地址:https://github.com/endernewton/tf-faster-rcnn/blob/a3279943cbe6b880be34b53329a4fe3f971c2c37/lib/nets/network.py#L323
整个代码调用情况可看下:附件

def _build_network(self, is_training=True):
    # select initializers
    if cfg.TRAIN.TRUNCATED:
      initializer = tf.truncated_normal_initializer(mean=0.0, stddev=0.01)
      initializer_bbox = tf.truncated_normal_initializer(mean=0.0, stddev=0.001)
    else:
      initializer = tf.random_normal_initializer(mean=0.0, stddev=0.01)
      initializer_bbox = tf.random_normal_initializer(mean=0.0, stddev=0.001)
	#get feature map
    net_conv = self._image_to_head(is_training)
    with tf.variable_scope(self._scope, self._scope):
      # build the anchors for the image
      self._anchor_component()
      # region proposal network
      rois = self._region_proposal(net_conv, is_training, initializer)
      # region of interest pooling
      if cfg.POOLING_MODE == 'crop':
        pool5 = self._crop_pool_layer(net_conv, rois, "pool5")
      else:
        raise NotImplementedError

    fc7 = self._head_to_tail(pool5, is_training)
    with tf.variable_scope(self._scope, self._scope):
      # region classification
      cls_prob, bbox_pred = self._region_classification(fc7, is_training, 
                                                        initializer, initializer_bbox)

    self._score_summaries.update(self._predictions)

    return rois, cls_prob, bbox_pred

上述代码是总体框架:
  前面是初始化内容不用看,我们从net_conv = self._image_to_head(is_training)看起。
1.net_conv = self._image_to_head(is_training)。
  这其实就是前面的卷积层内容,输出feature map(特征图),一般输出的大小是1*60*40*512([图片个数,高度,宽度,通道数])。
  需要提一句的是Faster RCNN首先是支持输入任意大小的图片的,比如输入的P*Q,进入网络之前对图片进行了规整化尺度的设定,如可设定图像短边不超过600,图像长边不超过1000,我们可以假定M*N=1000*600(如果图片少于该尺寸,可以边缘补0,即图像会有黑色边缘)
  经过Conv layers,图片大小变成(M/16)*(N/16),即:60*40(1000/16≈60,600/16≈40);则,Feature Map就是60*40*512-d(注:VGG16是512-d,ZF是256-d),表示特征图的大小为60*40,数量为512

2.往下看self._anchor_component()。
  这个函数主要产生anchor。这个东西是什么呢?
  前面提到经过Conv layers后,图片大小变成了原来的1/16,令feat_stride=16。
  然后我们来生成Anchors,首先要认识到特征图(60*40)上的一个点,可以对应到原图(1000*600)上一个16*16大小的区域(点位)(不难想象)。然后我们要对特征图上每一个点生成不同的矩形框。一般来说每个特征图上的点会生成9个矩形框,那么一共既是60*40*9(21600)个anchor box。这些anchor box会被映射到原图中,如下图:
anchor
  当然特征图上每个点不可能随便生成9个anchor box,它是有一定规则的,根据长宽比和面积大小产生,就如上图一样。我们首先给定一个base anchor大小为[16,16](特征图与原图比例为1:16),我们先看下面积保持不变,长、宽比分别为ratios=[0.5, 1, 2]。产生的Anchors box,如下图:
在这里插入图片描述
  接下来我们再看下面积大小变化scales=[8, 16, 32]。
scale
  综合以上3*3种情况,如图:
综合
  特征图每一个点位都照此处理。
详细的代码过程讲解(建议看一下,有助于理解):https://blog.csdn.net/m0_37663944/article/details/103652881

3.rois = self._region_proposal(net_conv, is_training, initializer)
  这里就是实现区域候选网络(RPN)。RPN
  rpn如上图feature map经过一个3*3卷积之后,特征图保存不变,然后出现了两个1*1的卷积。
  上面1*1卷积是预测类别的(背景还是物体,是一个二分类[0,1],[1,0]表示),特征图大小变成了[1,h(60),w(40),2*9],其实就是对以上60*40*9个anchor进行预测。所以图上的18就是每个点位中9个锚的二分类情况。
  下面的1*1卷积是用来预测anchor box与真实框之间的偏移量,特征图大小变成了[1,h(60),w(40),4*9]。这个偏移量样本是如何计算的呢?看以下公式:

anchor box: 中心点位置坐标x_a,y_a和宽高w_a,h_a
ground truth:标定的框也对应一个中心点位置坐标x*,y*和宽高w*,h*
所以,偏移量:
△x=(x*-x_a)/w_a   △y=(y*-y_a)/h_a 
△w=log(w*/w_a)   △h=log(h*/h_a)

  通过ground truth box与预测的anchor box之间的差异来进行学习,从而是RPN网络中的权重能够学习到预测box的能力
  生成的60*40*9个anchor box,然后累加上训练好的△x, △y, △w, △h,从而得到了相较于之前更加准确的预测框region proposal,进一步对预测框进行越界剔除和使用nms非最大值抑制,剔除掉重叠的框;比如,设定IoU为0.7的阈值,即仅保留覆盖率不超过0.7的局部最大分数的box(粗筛)。最后留下大约2000个anchor,然后再取前N个box(比如300个);这样,进入到下一层ROI Pooling时region proposal大约只有300个

综上所述,这段函数其实就是做分类,回归和筛选,得到proposal。
详情看代码详解
RPN网络

4.pool5 = self._crop_pool_layer(net_conv, rois, “pool5”)
  通过以上代码,我们得到了ROI,然后我们就要将ROI映射到feature map上(因为ROI的大小是在原图的基础上)。这个做法就和fast rcnn的做法差不多一致。通过这个方法得到了一个一个特征图。我们详细看下:

我们了解一下它的输入吧:
bottom:特征图,shape=(1,60,40,512)
rois:筛选出来的roi,shape=(N,5)
作用:根据roi得到对应的特征图部分

  def _crop_pool_layer(self, bottom, rois, name):
    with tf.variable_scope(name) as scope:
    #得到索引
      batch_ids = tf.squeeze(tf.slice(rois, [0, 0], [-1, 1], name="batch_id"), [1])
      # Get the normalized coordinates of bounding boxes
      bottom_shape = tf.shape(bottom)
      height = (tf.to_float(bottom_shape[1]) - 1.) * np.float32(self._feat_stride[0])
      width = (tf.to_float(bottom_shape[2]) - 1.) * np.float32(self._feat_stride[0])
      x1 = tf.slice(rois, [0, 1], [-1, 1], name="x1") / width
      y1 = tf.slice(rois, [0, 2], [-1, 1], name="y1") / height
      x2 = tf.slice(rois, [0, 3], [-1, 1], name="x2") / width
      y2 = tf.slice(rois, [0, 4], [-1, 1], name="y2") / height
#以上其实是在归一化,下面函数的要求,会讲到。

      # Won't be back-propagated to rois anyway, but to save time
      bboxes = tf.stop_gradient(tf.concat([y1, x1, y2, x2], axis=1))
      pre_pool_size = cfg.POOLING_SIZE * 2
      crops = tf.image.crop_and_resize(bottom, bboxes, tf.to_int32(batch_ids), [pre_pool_size, pre_pool_size], name="crops")
#可以看下这篇博客https://blog.csdn.net/m0_38024332/article/details/81779544
    return slim.max_pool2d(crops, [2, 2], padding='SAME')

5.fc7 = self._head_to_tail(pool5, is_training)
cls_prob, bbox_pred =self._region_classification(fc7,is_training, initializer, initializer_bbox)
这里两行代码一起讲,第一行代码将pool5变成fc的结构,之后送入**_region_classification**,得到最终的分类和偏移量。
这个过程就是以下第三部份。
在这里插入图片描述

参考文献:
https://blog.csdn.net/qq_41576083/article/details/82966489
https://www.cnblogs.com/wangyong/p/8513563.html
https://blog.csdn.net/sinat_33486980/article/details/81099093

  • 2
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Fast R-CNN 是一种目标检测算法,而 Faster R-CNN 是在 Fast R-CNN 的基础上进行改进的算法。下面是 Faster R-CNN 的代码结构的详细解释: 1. 数据准备:首先,需要准备训练和测试所需的数据集。这包括图像数据和标注信息,如物体的类别和位置。 2. 数据预处理:在训练之前,需要对数据进行预处理。这包括图像的缩放、裁剪、归一化等操作,以及生成锚框(anchor boxes)。 3. 模型架构:Faster R-CNN 的主要组成部分包括卷积网络(如 ResNet)和 Region Proposal Network(RPN)。卷积网络负责提取图像特征,RPN 负责生成候选区域。 4. 特征提取:使用卷积网络对输入图像进行特征提取。这些特征将作为后续步骤的输入。 5. Region Proposal Network(RPN):RPN 是 Faster R-CNN 的核心部分。它通过滑动窗口在特征图上生成候选区域。每个候选区域都是一个锚框,包含了物体的可能位置和尺寸。 6. 候选区域分类:对于每个候选区域,通过分类器来判断其是否包含物体。常用的分类器是全连接层或者支持向量机(SVM)。 7. 候选区域回归:对于包含物体的候选区域,需要进一步调整其边界框的位置和尺寸。这个过程叫做边界框回归。 8. 损失函数:Faster R-CNN 使用多任务损失函数来训练模型。这个损失函数包括分类损失和边界框回归损失。 9. 训练与测试:使用准备好的数据集进行训练。在训练过程中,通过反向传播来更新模型参数。测试时,将模型应用于新的图像,得到物体的位置和类别。 以上是 Faster R-CNN 的代码结构的概述。具体实现可能会有一些变化,取决于使用的框架和库。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值