前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >深入浅出理解Faster R-CNN

深入浅出理解Faster R-CNN

作者头像
CristianoC
发布2020-06-02 11:32:51
5550
发布2020-06-02 11:32:51
举报

之前讲解了one-stage算法的代表YOLO,今天将以自顶向下的思想,深入浅出地帮助读者理解two-stage算法代表Faster R-CNN。

目录

  • 整体结构
  • 基础网络
  • Anchor
  • Region Proposal Network(RPN网络)
  • RPN网络的训练以及损失函数
  • RPN后期处理
  • Region of Interst Pooling(RoI)
  • Region-based Convolutional Neural Network(R-CNN)
  • R-CNN的训练以及目标
  • 整体训练
  • 参考

整体结构

  • Faster R-CNN的结构比较复杂,本文将从一个高层次的概述开始,然后再详细介绍各个组件的细节。
  • 首先我们要明白,对于一张待检测的图像,我们期望获得:
  1. 一些bounding box(把物体框出来的边界框)
  2. 分配给各个bounding box的标签(即每个框里面物体类别标签)
  3. 每个bounding box以及标签的概率
  • 整体来看,Faster R-CNN一共要经过4个阶段:
  • 图片首先会经过一个预训练过的卷积特征提取层来提取图片的特征,这里会输出图片的特征图feature map,用作下一阶段的输入。
  • 接下来我们的feature map会通过一个叫做Region Proposal Network(RPN)的网络,RPN可以帮我们找出可能包含物体的那些区域(仅仅是找出可能包含物体的区域,这里不区分物体的种类)。
  • 我们知道使用深度学习来进行目标检测其中困难的一点可能在于生成可变长的bounding box(边界框)列表。这是因为我们神经网络最后一块通常是固定大小的张量输出。比如在分类任务中,我们会固定输出(N,)维的张量,其中N维是物体的种类,每个标量则是物体的概率,而我们无法固定每张图片生成的bounding box的数量。
  • RPN通过使用固定大小的anchor(参考框)来解决这个可变长的问题,这些anchor将会均匀地放置在整个原始图像中(后面会详细展开)。不同于原来我们要检测物体在哪里,我们现在利用anchor将问题转换为另外两部分:
  1. 某个框内是否含有物体
  2. 某个框是否框的准,如果框的不准我们要如何调整框
  • 通过RPN之后我们会获得一些可能含有物体的框,我们用这些框再结合第一部分原图片提取的特征图,使用RoI(Region of Interest)就可以将对应物体找出来并把他们的特征提取到新的张量里面进行分类。
  • 最后会通过一个叫做R-CNN的模块,它利用上一部分我们获得的信息做以下两件事:
  1. 前面我们只是区分某个框内是否含有物体,这里我们将会具体将物体进行分类(或者将其使用“背景”标签舍弃)
  2. 更好地调整框,让边界框更准
  • 上面是Faster R-CNN的基本思路,可能看完还有一些细节疑惑,接下来会介绍其中的各个组件以及训练的细节。

基础网络

  • 正如之前说的,一开始图片会经过一个卷积特征提取层来提取图片的特征,这里的网络可以是VGG,ZF,ResNet,DenseNet,为了说明方便这里用标准的VGG-16来说明。
  • 我们通常使用VGG进行分类的时候,输入的维度为
224 ×224 × 3

,因为网络最后一块是全连接层,所以这个尺寸必须固定。

  • 而由于我们仅仅使用了其中的卷积层中间输出,因此输入的大小不是问题,此外还需要知道我们卷积之后的feature map保持了原图片的相对位置,具体来说如果如果图片左上方有一个太阳,那么经过卷积提取出来的feature map上面这个太阳的特征仍在左上方,这对于后面我们理解有帮助。

Anchor

  • 前面我们提到Anchor是解决可变长方法的一种办法,但是我们跳过了大部分的解释,这部分将仔细展开阐述。
  • 我们的目标是在图片中找到能框住物体的边界框bounding box。这些边界框是矩形形状并可以有不同的大小和宽高比。我们想象一下,假如我们知道有一个图片含有两个物体,我们要怎么把他们找出来?我们的第一想法是训练一个返回值有8个的网络:这8个值分别是两个物体边界框的左上角坐标右下角坐标
(x_{min},y_{min},x_{max},y_{max})

。这个方法显然存在一些问题,比如当物体是不同大小有不同的宽高比,那训练一个效果很好的检测模型将会是非常复杂的(复杂的原因有两个,一个是如果整个图片很大,那么预测出的边界框坐标的绝对值变化很大,不容易拟合;第二个原因则是框的大小长宽都在变化,加大了我们的拟合难度)。另一个问题则是会存在一些无效的预测,比如当预测

x_{min},x_{max}

值的时候我们必须还要要求

x_{min} < x_{max}

  • 事实证明我们可以使用另一种更简单有效的方法来预测边界框:学习参考框的偏移。我们使用一个参考框
(x_{center},y_{center},width,height)

,我们来学习这个参考框的偏移

(\Delta x_{center},\Delta y_{center},\Delta width,\Delta height)

,因为我们学习的偏移值是相对于我们的参考框来说,所以这个值相比于直接预测这个框的坐标值来说小得多,这有利于我们训练。用数学语言来表示这个偏移就是(公式里的g代表ground-truth真实物体,a代表anchor框):

\Delta x_{center}=(x_g - x_a) × width_a,\Delta y_{center}=(y_g - y_a) × height_a
\Delta width=log(width_g/width_a),\Delta height=log(height_g/height_a)
  • 上面引出的这个参考框即是我们的Anchor,Anchor是一组固定的框,它们以不同的大小以及宽高比放在整个图像当中。
  • 当我们接受前一部分传来的维度为(conv_width,conv_height,conv_depth)的feature map,我们会在feature map每一个点(conv_width,conv_height)的地方放置k个anchor(这里假定k=9)。除此之外我们要知道即使我们在feature map设置anchor,这个anchor的信息也是基于原图像的(正如我们前面讲述卷积映射的时候一样)。
  • 因为我们的特征提取层只有卷积层和池化层,所以我们的feature map特征图的尺寸将和原图像成比例。从数学上讲如果原图像是
w × h

,那么我们的特征图的尺寸将会是

w/r × h/r

,其中这个

r

代表采样率,在VGG中这个

r

是16。如果我们在feature map每个位置上都设置一个anchor,那么可以说原图像上将以

r

像素分割,我们可视化一下这个过程:

  • 那anchor是如何选取的呢?我们通常定义几个尺寸(比如
64

px,

128

px,

256

px)以及一系列的宽高比(比如

0.5,1,1.5

)然后用这两者的不同组合来形成我们的anchor集合,同样我们来可视化一下:

  • 有了anchor之后我们就可以让对应尺寸宽高比的anchor去预测对应的尺寸宽高比groud-truth,我们很容易就可以理解针对性地训练不同大小宽高比anchor对应的回归器总比训练单一回归器适应不同大小宽高比容易。现在我们对anchor有了一个基本的概念,我们会结合RPN网络再加深一下理解。

Region Proposal Network(RPN网络)

RPN获取卷积特征图并在图像上生成可能含有物体的建议

  • 正如我们之前提到的,RPN网络接受所有的Anchors,并且输出可能含有物体的那些建议框。因此每个anchor会有两个不同的输出:
  • 第一个是anchor含有物体的概率。这里要注意RPN阶段我们对他具体是什么物体并不感兴趣,我们只是对他是前景还是背景感兴趣,我们可以理解为进行一轮粗筛,将那些更像是背景的Anchor框筛选掉;第二部分的输出则是边界框的偏移,这部分用来调整Anchor框来更好地框物体。
  • 我们使用第一部分返回的feature map进行输入,以全卷积的方式实现RPN。我们首先使用一个
3 × 3 × 512

的卷积层,然后使用两个并行的

1 × 1

的卷积内核,其中两个并行卷积层的通道数取决于每个点的Anchor数量(k个)。

  • 如上图所示,两个并行的卷积层分为左边用来分类的卷积层以及右边用来边界框回归的卷积层:
  1. 对于分类层,我们为每个Anchor输出2个预测值:背景得分以及前景得分(实际含有物体)。
  2. 对于边界框回归层,我们输出4个预测值:也就是前面我们提到anchor的偏移值
(\Delta x_{center},\Delta y_{center},\Delta width,\Delta height)
  • 通过最后调整好的边界框坐标以及他们的物体分类得分(仅仅粗分是否为物体),我们现在有一组可能含有物体的框。

RPN网络的训练以及损失函数

  • 通过上一部分讲解,我们知道RPN主要进行两种不同类型的预测:判断是否含有物体的二分类以及边界框回归调整。显然这是一种监督学习,监督学习就需要打上标签,这时候我们前面讲到的anchor就起到作用了。
  • 训练阶段,我们将所有Anchor放在两个不同的类别中(物体,背景)。具体划分的标准为:我们将与ground-truth(真实物体)IoU大于0.7的Anchor视为前景(如果没有就找一个与ground-truth的IoU最大的anchor),而与真实物体IoU小于0.1的视为背景。而IoU处于两个阈值中间的则忽略,忽略的原因是我们这一阶段只是进行粗筛,我们不想对那些比较困难的样本(又像前景又像背景)进行筛选,那些困难样本我们希望在第二阶段筛。用数学语言表达就是:
p*= \begin{cases} 1, & IoU >0.7 \ or \ max \ IoU \ for \ ground-truth,\\ 0, & IoU < 0.1 \\ ignore, &0.1 <= IoU <= 0.7 \end{cases}
  • 上一部分输出的feature map上的每一点生成对应原图的9个anchor,然后对9个anchor计算IoU,按照我们前面讲到的方式分配标签,正样本的anchor还要和对应的ground truth联系起来,对每个正样本anchor对应的ground truth,打上标签,交给该anchor对应的回归器预测。这里要注意,正样本anchor的大小长宽比被用来确定预测相应ground truth用哪个回归器。9个回归器并不是都起作用的(看检测的物体)。由于回归器和锚一一对应,就是说不是所有的anchor都有作用。
  • 理解了这些之后,我们可能会有疑问,按照anchor的生成方式一张原本
480 × 480

的图片首先经过VGG16倍采样率的下采样会得到

30×30

的feature map,feature map每一个点对应9个anchor,那一共就是

30×30×9=8100

个anchor,这样anchor的数量太多我们不可能一下子全送去训练,所以我们需要做一个采样。我们对这些anchors进行一个mini-batch采样来尝试在前景anchor和背景anchor之间保持一个平衡,一般一个mini-batch为256,其中取128个前景anchor,128个背景anchor,如果前景anchor的数量不足128个,就减少负样本的anchor数量直至与正样本数量相同,这里采样的anchor都来自特征图上不同的点。

  • 有了标签和mini-batch之后就可以开始计算损失,对于分类损失,我们通过二分类交叉熵进行计算,而对应回归损失,我们自然只会针对那些正样本进行回归,这个回归具体来说就是回归偏移(对应前面anchor部分讲到的
(\Delta x_{center},\Delta y_{center},\Delta width,\Delta height)

),回归建议框跟anchor之间的偏移以及ground-truth跟anchor之间的偏移。

  • 不同于使用普通的L1或者L2损失来就算边界框回归损失,论文建议使用Smooth L1损失。smooth L1损失让损失对于离群点更加鲁棒,相比于L2损失函数,可控制梯度的量级使训练时不容易震荡。
  • 由于许多原因,使用动态批处理是一件有挑战性的事情。即使我们试图在前景anchor和背景anchor之间保持一个平衡,但这不一定都能做到,这取决于图片中的真实物体以及anzhor的大小和比率,最终可能会得到0个前景anchor。假如真的发生了这种情况,我们将转向与地面具有最大IoU的anchor去匹配我们的真实物体,虽然这样不是我们原本理想的方式,但从实际意义上来讲,我们总是有前景样本和目标可以学习。
  • 为了方便读者理解,这里重新会过一遍RPN的训练过程,如果已经理解的读者跳过即可。
  • 1、假设输入的图片是
576 × 960

,经过VGG16生成卷积特征图,缩放16倍,得到

36 × 60

的特征图。

  • 2、使用
3×3

的滑窗在特征图滑动(stride=1,padding=2),找到每个三维滑窗的中心在原图映射的像素位置,然后在原图上生成9个anchor,这9个anchor的中心重合且和滑窗对应的中心相同。共有

36 × 60

个滑窗,则共有

36 × 60 × 9=19440

个原图上的anchor。

  • 3、生成anchor的同时根据ground truth的IoU值确定每个anchor是前景还是背景。为两种anchor分配正样本标签:(1)和一个ground truth的IoU值最大的那些anchor;(2)和任意一个ground truth的IoU大于或等于0.7的anchor。这里单个ground truth可能分配正样本标签给多个anchor。不是前景样本的anchor中,那些和所有ground truth的IoU值小于0.3的被分配为负样本,其余那些既不是正样本也不是负样本的anchor,不作为训练样本,被忽略。这样对于一个滑窗,原图产生的9个anchor,anchor可能被分配到正样本、负样本、被忽略样本的标签。然后对每个正样本anchor对应的ground truth,打上回归的标签,交给该anchor对应的回归器预测。
  • 4、从一张图片当中随机采样256个anchor作为一个mini-batch,正负样本anchor的比例是1:1,如果一张图片中正样本anchor的数量少于128个,就减少负样本anchor的数量和正样本anchor数量相同。
  • 5、mini-batch中的每个样本anchor对应的
3×3

的三维滑窗经过

3×3

卷积生成512维的向量,这512维的向量进入分类层、9个独立的回归层,最后输出一定是

(4+2)× 9

维,然后对正样本anchor对应的ground truth的回归层输出,计算回归损失loss,然后还要计算其分类损失,负样本也要计算分类损失。被忽略的锚对应的输出loss=0。

RPN后期处理

  • 1.取所有前景建议框中的得分前N个框
  • 2.clip限定超出图像边界的前景anchor作为图像边界,防止下面RoI的时候超出边界
  • 3.忽略掉长或者宽太小的建议框
  • 4.进行NMS
  • 5.最后重新再按得分排序,取得分前N个框

Region of Interst Pooling(RoI)

  • 经过了RPN网络,我们得到了一些没有具体类别的可能含有物体的框,那么接下来我们要解决的就是如何利用这些边界框将他们具体分类。
  • 最简单的方法是将每一个建议框裁剪,将物体那部分的特征剪出来,然后通过我们的特征提取网络就可以将提取的特征用作分类网络的输入。但是这里存在一个问题,不同的建议框的大小是不同的,如果只是简单的裁剪出来尺度不唯一就无法固定大小送去分类网络。
  • Faster R-CNN通过使用RoI为每一个建议框提取固定大小的特征图来完成的,我们最后具体分类的R-CNN网络需要固定大小的特征图,以便把他们分类成固定数量的类别。
  • 具体来说,我们将得到的建议框对应的feature map裁剪出来,这时候不同的建议框对应裁剪出来的feature map的尺寸是不一样的,但是我们把这些尺寸不一的feature map统一划分为a × b块,对每块使用max_pool池化,这样最终获得的feature map的尺寸就统一了。举个例子:比如原图上的的RoI大小是280×480,得到对应的特征图的尺寸是18×30。将特征图分成6块,也就是每块大小是3×5,然后在每一块中分别选择最大值放入6×6的对应区域中,这样所有的建议框的feature map就统一到了6 × 6了。
  • 将最终裁剪后的输出固定在这个尺寸是有原因的,这和接下来的R-CNN模块有关,重要的是我们要了解这些对应尺寸可以根据下一阶段的使用进行更改。

Region-based Convolutional Neural Network(R-CNN)

  • R-CNN是Faster R-CNN里的最后一步。从图像获得卷积特征图后,我们通过RPN获取建议框并通过RoI池为每一个建议框提取特征,我们最终需要使用这些特征进行分类,最后通过全连接层来为每个可能的类别输出分数。
  • R-CNN有两个不同目标:
  1. 将建议框的物体进行具体分类(这里要加上一个“背景”类,用于删除错误的建议框)
  2. 根据预测的类别更好地调整我们的边界框
  • R-CNN把每个建议框提取的特征展平,并且使用两个具有ReLU激活层的4096大小的全连接层进行分类(对应两个不同的目标):
  1. 第一个全连接层有N+1个单元,其中N是物体的类别,加的1是背景类。
  2. 另一个全连接层有4N个单元,对应我们边界框的4个偏移量(x_center,y_center,width,height),其中N是类别数
  • 这里比较简单和RPN也有类似之处,相信读者也都能理解,就不多赘述了。

R-CNN的训练以及目标

  • R-CNN这部分与RPN几乎相同,但要考虑具体的物体类别,而边界框回归部分则将建议框与ground-truth物体一起计算IoU。
  • 与任一一个ground-truth物体的IoU大于0.5的建议框将分配给对应的ground-truth物体,而那些介于0.1和0.5之间的建议框则标记为背景。和RPN阶段相反,我们忽略了那些IoU小于0.1的建议框。这是因为在R-CNN这个阶段我们认为我们已经有了好的建议框,这个阶段我们队解决更困难的情况更感兴趣,可以理解为在这个阶段我们进行的是细筛。
  • 对于边界框回归,我们仅仅对那些被分配类别的建议框才进行计算,同样我们也是计算与真实框的偏移值。
  • 和计算RPNloss一样,我们使用交叉熵计算分类损失,使用Smooth L1计算回归损失。

R-CNN后续处理

  • 与RPN类似,我们最终得到了一堆分配了具体类别的框,这些框在返回之前还需要做一些处理。
  • 为了进行边界框的调整,我们必须考虑哪一类是该框中可能性最高的类,同时我们还必须忽略那些将背景类作为最高概率的框。
  • 在获得最终的框并忽略了那些被预测为背景的框之后,我们将会基于类别使用NMS。通过类别进行分组,按照概率对他们进行排序,然后将NMS应用于每一个独立的组。
  • 对于我们最终的物体列表,我们还可以为每个类别设置概率阈值和物体数量限制。

整体训练

  • 看到这里相信大家对整一个结构都十分清楚了,我们用一张图自行回顾一下从特征提取网络到RPN到RoI最后分类的各个细节:
  • 将完整的模型放在一起后,我们可以进行端对端的训练,我们有4种不同的损失,其中RPN有2种,R-CNN有2种。
  • 整个训练过程可以用一张图表示,图来源https://zhuanlan.zhihu.com/p/24916624
  • 1.用一些模型初始化,先独立训练一个RPN网络,得到一些建议框proposal;
  • 2.同样先用一些预训练模型初始化,使用上一步RPN网络产生的proposal作为输入,训练一个Fast-RCNN网络;
  • 3.使用前面的Fast-RCNN网络参数重新初始化一个新的RPN网络。
  • 4.使用新的RPN网络输出的建议框继续训练Fast-RCNN网络。
  • 其实相当于把RPN网络和Fast-RCNN网络重新训了两次,增强检测识别效果。

参考

  • 1.https://arxiv.org/abs/1506.01497
  • 2.http://www.telesens.co/2018/03/11/object-detection-and-classification-using-r-cnns/
  • 3.https://tryolabs.com/blog/2018/01/18/faster-r-cnn-down-the-rabbit-hole-of-modern-object-detection/
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-04-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 计算机视觉漫谈 微信公众号,前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 目录
  • 整体结构
  • 基础网络
  • Anchor
  • Region Proposal Network(RPN网络)
  • RPN网络的训练以及损失函数
  • RPN后期处理
  • Region of Interst Pooling(RoI)
  • Region-based Convolutional Neural Network(R-CNN)
  • R-CNN的训练以及目标
  • R-CNN后续处理
  • 整体训练
  • 参考
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档