前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Faster RCNN 网络理解

Faster RCNN 网络理解

作者头像
嵌入式视觉
发布2022-09-05 14:30:38
5480
发布2022-09-05 14:30:38
举报
文章被收录于专栏:嵌入式视觉

Contents [hide]

本文为学习笔记,部分内容参考网上资料和论文而写的,内容涉及 Faster RCNN 网络结构理解和代码实现原理。

Faster RCNN 网络概述

faster rcnn网络结构

backbone 为 vgg16 的 faster rcnn 网络结构如下图所示,可以清晰的看到该网络对于一副任意大小 PxQ 的图像,首先缩放至固定大小 MxN,然后将 MxN 图像送入网络;而 Conv layers 中包含了 13 个 conv 层 + 13 个 relu 层 + 4 个 pooling 层;RPN 网络首先经过 3×3 卷积,再分别生成 positive anchors 和对应 bounding box regression 偏移量,然后计算出 proposals;而 Roi Pooling 层则利用 proposals 从 feature maps 中提取 proposal feature 送入后续全连接和 softmax 网络作 classification(即分类: proposal 是哪种 object)。

faster rcnn网络详细结构

RPN 在 Extractor(特征提取 backbone)输出的 feature maps 的基础之上,先增加了一个3*3 卷积(用来语义空间转换?),然后利用两个 1x1 的卷积分别进行二分类(是否为正样本)和位置回归。进行分类的卷积核通道数为 9×2( 9 个anchor,每个 anchor 二分类,使用交叉熵损失),进行回归的卷积核通道数为9×4(9 个 anchor,每个 anchor 有4个位置参数)。RPN 是一个全卷积网络(fully convolutional network),这样对输入图片的尺寸就没有要求了。  RPN完成positive/negative分类 + bounding box regression坐标回归两个任务。

Conv layers

论文中 Faster RCNN 虽然支持任意图片输入,但是进入 Conv layers 网络之前会对图片进行规整化尺度操作,如可设定图像短边不超过 600,图像长边不超过 1000,我们可以假定 M*N=1000*600(如果图片少于该尺寸,可以边缘补 0,即图像会有黑色边缘)。

  1. 13 个 conv 层:kernel_size=3, pad=1, stride=1,卷积公式:N = (W F + 2P )/S+1,所以可知 conv 层不会改变图片大小
  2. 13 个 relu 层: 激活函数,增加非线性,不改变图片大小
  3. 4 个 pooling 层:kernel_size=2,stride=2pooling 层会让输出图片变成输入图片的1/2。

所以经过 Conv layers,图片大小变成 \((M/16) \ast (N/16)\),即:\(60\ast 40(1000/16≈60,600/16≈40)\);则Feature Map 尺寸为  \(60\ast 40\ast 512\)-d (注:VGG16 是512-d, ZF 是 256-d,d 是指特征图通道数,也叫特征图数量),表示特征图的大小为 \(60\ast 40\),数量为 512。

RPN 网络

RPN 在 Extractor(特征提取 backbone )输出的 feature maps 的基础之上,先增加了一个 3*3 卷积(用来语义空间转换?),然后利用两个 1x1 的卷积分别进行二分类(是否为正样本)和位置回归。RPN 网络在分类和回归的时候,分别将每一层的每一个 anchor 分为背景和前景两类,以及回归四个位移量,进行分类的卷积核通道数为9×2(9 个 anchor,每个 anchor 二分类,使用交叉熵损失),进行回归的卷积核通道数为 9×4(9个anchor,每个 anchor 有 4 个位置参数)。RPN是一个全卷积网络(fully convolutional network),这样对输入图片的尺寸就没有要求了。

RPN 完成 positive/negative 分类 + bounding box regression 坐标回归两个任务。

Anchors

RPN 中,作者提出了 anchors,所谓 anchors,实际上就是一组rpn/generate_acchors.py生成的一组矩形框,运行官方代码的 generate_anchors.py 可以得到以下示例输出:

[[ -84. -40. 99. 55.]  [-176. -88. 191. 103.]  [-360. -184. 375. 199.]  [ -56. -56. 71. 71.]  [-120. -120. 135. 135.]  [-248. -248. 263. 263.]  [ -36. -80. 51. 95.]  [ -80. -168. 95. 183.]  [-168. -344. 183. 359.]]

其中每行的4个值 \( (x_{1},  y_{1},  x_{2},  y_{2}) \)表矩形左上和右下角点坐标。9个矩形共有3种形状,长宽比为大约为width:height ϵ {1:1,1:2,2:1}三种,如下图:实际上通过anchors就引入了检测中常用到的多尺度方法。 

anchor

然后利用这 9 种anchor在特征图左右上下移动(遍历),每一个特征图上的任意一个点都有 9 个 anchor,假设原图大小为 M*N,经过 Conv layers 下采样 16 倍,则每个 feature map 生成 (M/16)*(N/16)*9个 anchor。例如,对于一个尺寸为 62×37 的 feature map,有 62×37×9 ≈ 20000 个 anchor。 也就是对一个 feature map,会产生约 20000 个左右的 anchor。这种做法很像是暴力穷举,20000 多个 anchor,哪怕是蒙也能够把绝大多数的 ground truth bounding boxes 蒙中。

因此,anchor 的数量和 feature map 相关,不同的 feature map 对应的 anchor 数量也不一样。

生成 RPN 网络训练集

在这个任务中,RPN做的事情就是利用(AnchorTargetCreator)将20000多个候选的 anchor 选出256个anchor进行分类和回归位置。选择过程如下:

  • 对于每一个ground truth bounding box (gt_bbox),选择和它重叠度(IoU)最高的一个anchor作为正样本;
  • 对于剩下的anchor,从中选择和任意一个gt_bbox重叠度超过 0.7 的 anchor ,同样作为正样本;
  • 随机选择和 gt_bbox 重叠度小于 0.3 的 anchor 作为负样本。

同时,保证正样本为 128 个,负样本为 128 个,负样本和正样本的总数为256 ,正负样本比例 1:1

positive/negative 二分类

1*1卷积实现,卷积通道数为9×2(9个anchor,每个anchor二分类,使用交叉熵损失),后面接softmax分类获得positive anchors,也就相当于初步提取了检测目标候选区域box(一般认为目标在positive anchors中)。  所以可知,RPN的一个任务就是在原图尺度上,设置了密密麻麻的候选Anchor。然后用cnn(1*1卷积,卷积通道数9*2)去判断哪些Anchor是里面有目标的positive anchor,哪些是没目标的negative anchor

bounding box regression

在挑选 1:1 正负样本比例的 anchor 用作 RPN 训练集后,还需要计算 anchor box 与 ground truth 之间的偏移量: \(t_x t_y t_w t_h\)。

对于每个anchor, gt_label 要么为1(前景),要么为0(背景),而 gt_loc 则是由4个位置参数 (tx,ty,tw,th) 组成,这样比直接回归座标更好。在Faster RCNN原文,positive anchorground truth之间的平移量 (\ (t_{x}, t_{y}) \) 与尺度因子 \( (t_{w}, t_{h}) \)计算公式如下 :

\(t_{x} = (x-x_{a})/w_{a}, t_{y}=(y-y_{a})/h_{a},\) \(t_{w} = log(w/w_{a}), t_{h}=log(h/h_{a}),\) \(t^{*}_{x} = (x^{*}-x_{a})/w_{a}, t^{*}_{y}=(y^{*}-y_{a})/h_{a},\) \(t^{*}_{w} = log(w^{*}/w_{a}), t^{*}_{h}=log(h^{*}/h_{a}),\)

参数解释:where \( x, y, w, \) and h denote the box’s center coordinates and its width and height. Variables \( x, x_{a} \), and \( x^{*}\) are for the predicted box, anchor box, and groundtruth box respectively likewise for \( y, w, h \)). 

计算分类损失用的是交叉熵损失,而计算回归损失用的是Smooth_l1_loss. 在计算回归损失的时候,只计算正样本(前景)的损失,不计算负样本的位置损失。loss计算公式如下:

公式解释:Here,  \(i\)  is the index of an anchor in a mini-batch and \(p_{i}\) is the predicted probability of anchor i being an object. The ground-truth label \(p^{*}_{i}\) is 1 if the anchor is positive, and is 0 if the anchor is negative. \(t_{i}\) is a vector representing the 4 parameterized coordinates of the predicted bounding box, and \(t^{*}_{i}\) is that of theground-truth box associated with a positive anchor.

RPN 生成 RoIs(Proposal Layer)

RPN 网络在自身训练的同时,还会由 Proposal Layer 层产生 RoIs(region of interests)给 Fast RCNN(RoIHead)作为训练样本。RPN 生成 RoIs 的过程( ProposalCreator )如下:

  1. 对于每张图片,利用它的 feature map, 计算(H/16)× (W/16)×9(大概20000)个 anchor 属于前景的概率,以及对应的位置参数`。选取概率较大的 12000 个 anchor;
  2. 利用回归的位置参数,修正这 12000 个 anchor 的位置,得到 RoIs
  3. 利用非极大值((Non-maximum suppression, NMS)抑制,选出概率最大的 2000 个 RoIs。

在 RPN 中,从上万个 anchor 中,选一定数目(2000 或 300),调整大小和位置生成 RoIs,用于 ROI Head/Fast RCNN 训练(ProposalTargetCreator 会从中选择 128 个 RoIs 用以训练)。

注意:在 inference 的时候,为了提高处理速度,12000 和 2000 分别变为 6000 和 300。Proposal Layer 层,这部分的操作不需要进行反向传播,因此可以利用 numpy/tensor 实现

RPN 网络总结

  • RPN网络结构:生成anchors -> softmax分类器提取positvie anchors -> bbox reg回归positive anchors -> Proposal Layer生成proposals
  • RPN的输出:RoIs(region of interests)(形如 2000×4 或者 300×4 的 tensor

ROIHead/Fast R-CNN

RPN 只是给出了 2000个 候选框,RoI Head 在给出的 2000 候选框之上继续进行分类和位置参数的回归。ROIHead 网络包括 RoI pooling + Classification(全连接分类)两部分,网络结构如下: 

ROI Head网络结构

由于 RoIs 给出的 2000个 候选框,分别对应 feature map 不同大小的区域。首先利用 ProposalTargetCreator 挑选出 128 个 sample_rois, 然后使用了RoI Pooling 将这些不同尺寸的区域全部 pooling 到同一个尺度(7×7)上,输出7*7大小的 feature map,送入后续的全连接网络

  • FC 21 用来分类,预测RoIs属于哪个类别(20个类+背景)
  • FC 84 用来回归位置(21个类,每个类都有4个位置参数)

Roi pooling

RoI pooling 负责将 128 个RoI区域对应的 feature map 进行截取,而后利用 RoI pooling 层输出 7*7 大小的 feature map,送入后续的全连接网络。从论文给出的 Faster R-CNN网络结构图中,可以看到 Rol pooling 层有2个输入:

  • 原始的 feature maps
  • RPN 输出的 RoIs (proposal boxes, 大小各不相同)

RoI Pooling 的两次量化过程以及 RoI Align 如何改进: 

(1)、在原图上生成的 region proposal 映射到 feature map 需要除以 16 或者 32 的时候,边界出现小数,这是第一次量化。 (2)、在每个 roi 里划分成 k×k (7×7) 的 bins,对每个 bin 中均匀选取多少个采样点,然后进行 max pooling,也会出现小数,这是第二次量化。

ROI Align 并不需要对两步量化中产生的浮点数坐标的像素值都进行计算,而是设计了一套优雅的流程。如下图,其中虚线代表的是一个feature map,实线代表的是一个roi(在这个例子中,一个roi是分成了2*2个bins),实心点代表的是采样点,每个bin中有4个采样点。我们通过双线性插值的方法根据采样点周围的四个点计算每一个采样点的值,然后对着四个采样点执行最大池化操作得到当前bin的像素值。 (更多内容,参考这篇文章)

RoI Align示意图

RoI Align做法:假定采样点数为4,即表示,对于每个2.97 x 2.97的bin,平分四份小矩形,每一份取其中心点位置,而中心点位置的像素,采用双线性插值法进行计算,这样就会得到四个小数坐标点的像素值。

ROI Head训练

RPN会产生大约2000个RoIs,ROI Head 在给出的 2000 个 RoIs候选框基础上继续分类(目标分类)和位置参数回归。注意,这2000个RoIs不是都拿去训练,而是利用 ProposalTargetCreator(官方源码可以查看类定义) 选择128个RoIs用以训练。选择的规则如下:

  • RoIs 和 gt_bboxes 的IoU大于 0.5 的,选择一些(比如 32 个)作为正样本;
  • 选择 RoIs 和 gt_bboxes 的IoU小于等于 0(或者 0.1, 0.5 的选择一些(比如 128 – 32 = 96 个)作为负样本。

选择出的 128 个 RoIs,正负样本比例为 3:1,在源码中为了便于训练,还对他们的gt_roi_loc 进行标准化处理(减去均值除以标准差)。  和RPN一样,对于分类问题, 直接利用交叉熵损失. 而对于位置的回归损失,一样采用 Smooth_L1 Loss, 只不过只对正样本计算损失,而且是只对正样本中的这个类别4个参数计算损失。举例来说:

  • 一个 RoI 在经过FC 84 后会输出一个 84 维的 loc 向量. 如果这个 RoI 是负样本, 则这84维向量不参与计算 L1_Loss
  • 如果这个 RoI 是正样本,属于label K, 那么它的第 K×4, K×4+1 ,K×4+2, K×4+3 这4个数参与计算损失,其余的不参与计算损失。

ROI Head测试

ROI Head 测试的时候对所有的 RoIs(大概 300 个左右) 计算概率,并利用位置参数调整预测候选框的位置。然后再用一遍极大值抑制(之前在RPN的ProposalCreator用过)。  这里注意:

  • 在 RPN 的时候,已经对 anchor 做了一遍 NMS,在 Fast RCNN 测试的时候,还要再做一遍,所以在Faster RCNN框架中,NMS操作总共有 2 次
  • 在 RPN 的时候,已经对 anchor 的位置做了回归调整,在 Fast RCNN 阶段还要对 RoI 再做一遍
  • 在 RPN 阶段分类是二分类,而 Fast RCNN/ROI Head 阶段是 21 分类

概念理解

在阅读Faster RCNN论文和源码中,我们经常会涉及到一些概念的理解。

四类损失

在训练Faster RCNN的时候有四个损失:

  • RPN 分类损失:anchor 是否为前景(二分类)
  • RPN位置回归损失:anchor 位置微调
  • RoI 分类损失:RoI 所属类别(21分类,多了一个类作为背景)
  • RoI位置回归损失:继续对 RoI 位置微调

四个损失相加作为最后的损失,反向传播,更新参数

三个creator

Faster RCNN官方源码中有三个 creator 分别实现不同的功能,不能弄混,各自功能如下:

  • AnchorTargetCreator : 负责在训练RPN的时候,从上万个anchor中选择一些(比如256)进行训练,以使得正负样本比例大概是1:1. 同时给出训练的位置参数目标。 即返回gt_rpn_loc和gt_rpn_label。
  • ProposalTargetCreator: 负责在训练RoIHead/Fast R-CNN的时候,从 RoIs 选择一部分(比如128个,正负样本比例 1:3 )用以训练。同时给定训练目标, 返回(sample_RoI, gt_RoI_loc, gt_RoI_label)
  • ProposalCreator: 在RPN中,从上万个anchor中,选择一定数目(2000或者300),调整大小和位置,生成RoIs,用以Fast R-CNN训练或者测试。

其中 AnchorTargetCreator 和 ProposalTargetCreator 是为了生成训练的目标,只在训练阶段用到,ProposalCreator 是 RPN 为 Fast R-CNN 生成 RoIs ,在训练和测试阶段都会用到。三个 creator 的共同点在于他们都不需要考虑反向传播(因此不同框架间可以共享numpy实现)。

参考资料

一文读懂Faster RCNN 从编程实现角度学习Faster RCNN 你真的学会了RoI Pooling了吗 Faster RCNN 学习笔记

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-03-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Faster RCNN 网络概述
  • Conv layers
  • RPN 网络
    • Anchors
      • 生成 RPN 网络训练集
        • positive/negative 二分类
          • bounding box regression
            • RPN 生成 RoIs(Proposal Layer)
              • RPN 网络总结
              • ROIHead/Fast R-CNN
                • Roi pooling
                  • ROI Head训练
                    • ROI Head测试
                    • 概念理解
                      • 四类损失
                        • 三个creator
                        • 参考资料
                        领券
                        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档