原文为我的CSDN:https://pfeiwang.blog.csdn.net/article/details/104361394
一、何为目标检测
给你一张图片,告诉我图里有什么?在哪?
二、如何做到目标检测
学过深度学习的都知道已经事情,一个深度神经网络就是一个巨大的函数,给它输入,它给你输出,相信很多读者都自己构建过深度神经网络并在MNIST手写数字数据集上进行过实验。
根据上面的描述,我们总能够设计一个神经网络,输入一张图片,输出图片的类别。也就是说这个神经网络就是一个判别器。那么问题来了,如果你要判断的物体沾满了整个图片,那么还好说,如果你要判别的物体在图片中的某个角落,或者一个图片里面有多个物体,该怎么办?显然只去完成一个判别器的训练是达不到我们的要求的。
考虑到要检测的物体有大有小,其在图片中的位置,有上右下,所以最暴力的放方法就是枚举,不同大小的方框,然后将这些方框圈出的图像区域放入判别器中去判断到底是什么物品,最原始的方法就是建立图像金字塔,简单来说,就是对原始图像进行一定比例的放大或者缩小,然后用同一大小的矩形框在不同缩放比例图片上滑动,来截取区域,一般情况这样形成的候选区域有上万个。所以时间代价非常大。我此处介绍的图像金字塔的方式获取候选区域的方法非常暴力,还有很多不错的其他的方法,这里不做赘述。
考虑到实际物体的大小并不一定是我们设置好的一个矩形大小,所以其总是有所变动的,所以这里又将回归引入到了神经网络中,也就是说,预测的位置,要尽可能的逼近Ground Truth(GT:数据集中认为标注出来的正确的物品区域)。
讲到这里大家已经基本上了解了目标检测的大体方式,要有候选区域、分类器、回归器。
三、R-CNN
引入
R-CNN算法首次将CNN用作物体的特征提取器,候选区域的选择,有独立的算法,一般用SS(这里的算法可以百度一下,很多)。
根据图一并且考虑到前面说到的目标检测的大体步骤,我们可以看出,R-CNN算法的步骤是,在原图片上进行候选区域的选取,于此同时需要训练一个CNN的特征提取器(这个特征提取器只需要保留一个CNN分类神经网络的CONV部分即可,全连接层可以不要),之后将每一个候选区域一次放入到CNN特征提取器中提取图像特征,然后将图像特征放入SVM中进行判断是否是物体(此处的SVM也是预先训练好的),之后再将提取的图像特征放入回归器中得到回归框的位置,然后将经过判断器判断为物体的候选区域的回归框标出,这些很多个框框就是检测出来的目标结果,显然这些结果中会有很多的重复覆盖的部分,需要进行一定的筛选,这里用到了NMS算法(该算法思想简单,就是普通的编程算法)。
R-CNN的缺点有哪些
- 候选区域的选择需要花费大量的时间
- 所有的候选区域都要进行独立的特征提取过程,也就是说,每一次判断都要进行一个大型的卷积特征提取过程
四、Fast R-CNN
引入
从图二中,至少可以看明白一点,那就是对应输入图片没有先进行候选区域的选择,直接将原图放入了CNN的特征提取网络,最后形成了名为conv5的feature map,但是这并不意味着不需要候选区域了,候选区域还是需要在原始图片上进行提取的,但是得到的候选区域需要全部映射到conv5的feature上,因为在特征提取的CNN网络ConvNet中,缩放的尺寸是可以计算的(不同的网络架构有不同的缩放尺寸,一般是缩小了16倍,也就是经历了4次池化操作),所以所有的候选区域被在conv5的feature map中被框出,然后得到了区域,但是区域有大有小,如何进行大小尺寸的归一化呢?这里用到了RoIPooling技术(均等的网格化,来进行池化,具体可以百度),最后将RoIPooling处理之后的特征区域(该区域大小是认为强行规定的)作为一个深度全连接网络的输入,输出为两个部分,一个为分类,一个为回归(这个部分和R-CNN是一致的)。
Q:有的人可能会疑惑,怎么一个分类,一个回归,如何训练呢?
A:其实很简单,对于RoIPooling处理之后的特征区域,加入被映射到1024维度的特征中,起就是一个矩阵的运算,那么此时初始化两个矩阵,一个用于分类,一个用于回归,但是都作用在这个1024维的全连接层上,但是此时训练的时候,就可以分别作损失,然后将损失结果通过一定的比例进行相加即可。
Fast R-CNN比R-CNN优化的地方,以及其依旧存在的问题
- 运行时间比R-CNN更快了,可以回头看一下R-CNN的第二条缺点,也就是特征提取的CNN网络需要作用在每一个特征区域上,耗费了大量的时间,但是Fast R-CNN想对图像进行了CNN网络的特征提取,而其候选区域也是直接映射到了feature map上,节省掉了大量的重复时间,这就是为啥Fast R-CNN更快的点
- Fast R-CNN依旧没有能够摆脱对候选区域的依赖,所以还是耗费了大量的时间在候选区域上
五、Faster R-CNN
引入
下面将详细讲解本文的重点,Faster R-CNN的原理,训练流程(我也看过很多blog上,都没有很好的解释如何训练,全是围绕着什么优缺点在描述,完全搞不懂Faster R-CNN真实的内在)。
几乎所有的有关Faster R-CNN的blog都会pose上图三这张图,说实话,乍一看这张图你会感觉所有的东西都是一气呵成的,都是一个输入图片,然后得到结果,循环训练即可,然而当你再仔细扣细节的时候发现,根本就不是这么回事,自己都解释不通。那么该如何去理解上面的这个图片呢?
网络结构
对于图三,正确的理解是,这是两个独立的网络合成的。首先是RPN网络,其次是Fast R-CNN网络。这两个网络是完全的单独训练的,不是放在一起训练。(这两行是理解Faster R-CNN的重点要记住)。
其实真正的网络流程是这样的,我们训练一个RPN网络,RPN网络代替了传统候选区域的选取算法,那么RPN就是一个候选区域生成器,之后,我们训练一个Fast R-CNN网络,这个网络的训练需要在RPN网络训练完成之后,因为Fast R-CNN需要用到候选区域,而这里的候选区域是通过训练好的RPN网络得到的。这么看的话Faster R-CNN的结构就已经非常的明了了,就是将Fast R-CNN中的候选区域算法换成了一个候选区域生成器(CNN网络)。但是更加细节的流程,将在文章的后面介绍。
相信读到这里,我们对Faster R-CNN有了非常宏观的理解了。
网络训练
RPN网络训练
总体流程
如果只是根据图四的话,很多人又开始晕了,这张图又将两个要独立训练的网络放到了一起。所以有关RPN训练的具体步骤,请参考我手绘的下图
首先来讲解一个这里流程,对于一个输入图片,对其进行缩放(使高等于600),然后将一个CNN特征提取器作用在上面,这里的CNN特征提取器可以是VGG等(为什么用VGG这种网络呢?因为这些网络可以很好的区分物体之间,以及区分背景和物体之间,并不是为了其分类效果)。在经历了CNN特征提取器之后,我们得到了256个40x60的feature map(张量形式[40, 60, 256]),再添加一个核大小为3x3,输出通道为256的卷积层,之后就需要兵分两路了。
Q:1x1卷积的作用是什么?
A:很多blog总是说一句话,相当于全连接层,但是这样很容易产生歧义理解,通过下图,便可以一目了然,1x1卷积的值只是一个对原始一层feature map的放缩,就相当于对上一层的一个神经元加上一个权重。
理解了1x1卷积的作用,下面就是如何理解k的值,k表示的anchor的个数,对于anchor的理解,相信在很多blog里面都有讲解,这里不做赘述(本文的重点的理解Faster R-CNN的整体过程),那么左边的分支表示的是,对于feature map上的每一个像素点,以该点位中心,k个anchor所圈出的区域是否为背景,右边的分支表示,k个anchor所选出的区域如果存在物体,那么其box框的位置在哪(一个框位置的界定,由四个部分组成,中心点坐标x、y,矩形框的宽高w、h)。
RPN网络标签的生成
既然是要单独训练RPN网络那么其标签又是什么样子的呢?形象的说地话,RPN网络的标签的形式就是图五的输出形式。我们总可以将40x60feature map上的一个区域映射到原始图片上,并且我们知道原始图像中物体所在的位置(框出的物体框-数据集给出),接下来通过解决下面的三个问题就可以解决RPN网络的标签问题了。
Q1:如何判断一个像素点的k个anchor在原图中是否框出了一个物体?
A1:论文指出,通过两种方式
- 第一种:对于一个像素点,对其k个anchor在原始图像中的映射与GT进行IoU的计算,选择最大的为1(存在物体)
- 第二种:如果一个anchor在原始图像中的映射与GT进行IoU计算,如果IoU>0.7就标注为1
如果IoU<0.3,标注为0(背景);如果IoU在0.3~0.7之间,那么不做处理。此时就可以理解为什么要用1x1卷积的输出通道数为2k了,因为一个种类的anchor有两种结果,分别是negitive、positive。
Q2:RPN网络回归框输出部分如何理解?
A2:我们知道回归框部分是经过核为1x1,输出通道为4k,得到的一个40x60x4k的一个方块,那么每一个特征像素点下面有着4k长度的向量,表示k个anchor在原图中的映射框定位(x、y、w、h)。
Q3:RPN网络回归框的LOSS如何定义?
A3:RPN分类部分的LOSS很好定义,使用SoftMax Loss的定义即可,那么对于回归部分,我们要达到的要求是,让预测值和anchor的比例更加接近GT与anchor的比例,anchor起到了中间值过度的作用,这样只需要缩放anchor即可。具体步骤如下
设
分别表示预测值的、anchor的、GT的
RPN网络LOSS
读到这里我们知道RPN的原理,以及RPN是如何训练的。
Faster R-CNN网络训练
上文讲述了,如何独立的训练RPN网络,那么还有第二个需要独立训练的部分就是一个Fast R-CNN网络部分,这个部分需要用到候选区域,那么就用我们训练好的RPN网络生成候选区域,然后用来独立地训练Fast R-CNN网络。但是此时我们遇到一个问题,无论是训练Fast R-CNN网络还是训练RPN网络,我们对原始图片的特征提取的VGG是预训练好的(但是在后续训练中需要对其进行微调),但是他们训练之后变成了参数不同的VGG网络,这对合并Fast R-CNN和RPN网络增加了难度,所以将采取以下方式来减少合并网络带来的影响
- 用VGG作为RPN的特征提取器,训练RPN网络
- 使用RPN提取图片的候选区
- 使用2中的候选区,训练Fast R-CNN网络
- 用训练好的Fast R-CNN网络的特征提取器部分的参数初始化RPN特征提取器部分的神经网络
- 再次对RPN网络进行训练