深度学习基础(六)卷积神经网络——目标检测
参考文章
【特征检测】HOG特征算法
第二十九节,目标检测算法之R-CNN算法详解
目标检测:SPP-net
一文读懂Faster RCNN
目标检测|YOLO原理与实现
深度学习基础(六)卷积神经网络——目标检测
-
-
目标检测介绍
-
HOG特征检测算法
-
传统方法——DPM
-
神经网络分类——RCNN
-
RCNN的改进——SPP-net
-
RCNN的改进—fast-RCNN
-
RCNN的改进—faster-RCNN
-
- RPN Region Proposal Networks
-
- anchors
-
bounding box regression原理
- ROI pooling
- Classification
-
神经网络回归——YoLo
-
-
- 分割
-
-
预测
-
神经网络回归——SSD

-
目标检测介绍
目标检测:利用神经网络进行目标识别,同样的目标变为坐标值
回归 是将目标的位置作为变量,特点是算的比较快,但是没有那么准确。
分类 是将目标进行分块。对分块后的图片进行识别,问题主要在于分类框 的选择,选的好的话识别率会很高。
小结:
- 目标探测任务
- 目标检测任务分为回归和分类问题
- 分类的主要思想是找出目标所在的大概位置,在大概位置中进行识别
HOG特征检测算法
HOG(Histogram of Oriented Gridients的简写)特征检测算法,主要思想是:在边缘具体位置未知的情况下,边缘方向的分布也可以很好的表示行人目标的外形轮廓。
HOG特征检测算法的几个步骤:
- 颜色空间归一化
- 梯度计算
- 梯度方向直方图
- 重叠块直方图归一化
- HOG特征
1、颜色空间归一化
避免因为颜色和光照影响图像识别的效果;一般通过两个步骤进行修改
图像灰度化:

Gamma校正 :将图像中的整体亮度提高或者减低。
2、梯度计算
计算图像横坐标和纵坐标方向的梯度,并据此计算每个像素位置的梯度方向值;求导操作不仅能够捕获轮廓,人影和一些纹理信息,还能进一步弱化光照的影响。其思想可以理解为计算每个像素点的变化方向,找到最大比变化的方向,这些方向也就是边缘点 。
最常用的方法是: 首先用[-1,0,1]梯度算子对原图像做卷积运算,得到x方向(水平方向,以向右为正方向)的梯度分量gradscalx,然后用[1,0,-1]T梯度算子对原图像做卷积运算,得到y方向(竖直方向,以向上为正方向)的梯度分量gradscaly。然后再用以上公式计算该像素点的梯度大小和方向。
3、梯度方向直方图
将图像划分成若干个cells(单元),8x8=64个像素为一个cell,相邻的cell之间不重叠 。在每个cell内统计梯度方向直方图,将所有梯度方向划分为9个bin(即9维特征向量),作为直方图的横轴,角度范围所对应的梯度值累加值作为直方图纵轴,每个bin的角度范围如下。
4、重叠块直方图归一化
将cell组合为block进行图像的分割,这样是为了增加在环境和背景情况下的图像识别率。
假设有一幅图像大小为220x310,将其划分成若干个8x8的cells,显然220÷8=27.5、310÷8=38.75不是整数,也就是说划分之后依然还有多余像素不能构成cell。处理办法是将图像缩放成能被8整除的长宽(如216x304),再划分。216÷8=27,304÷8=38,因此,216x304的图像可以得到27x38个cells,没有重叠。
以上述缩放后的图像为例,共得到27x38个cell,也就是将图像划分成了27x38个单元;将上下左右相邻的2x2个cells当做一个block整体,如下所示(为方便观察,每个颜色框故意错开了一点),黑色的8x8像素为一个cell,红、蓝、黄、粉红、绿框都是一个block,即每个框内2x2的cell组成一个block。故27x38个cell可划分成26x37个block,每个block为16x16像素。相邻block之间是有重叠的,这样有效的利用了相邻像素信息,对检测结果有很大的帮助。

接下分别对每个block进行标准化,一个block内有4个cell,每个cell含9维特征向量,故每个block就由4x9=36维特征向量来表征。

经过上述对有重叠部分block的直方图归一化之后,将所有block的特征向量都组合起来,则形成26x37x36=34632维特征向量,这就是HOG特征,这个特征向量就可以用来表征整个图像了。
实际上,在运用的时候,我们通常是选取一幅图像中的一个窗口来进行特征提取,依然以上述220X310大小图像为例,经过缩放处理后为216x304,但并不直接提取整个图像的HOG特征,而是用一个固定大小的窗口在图像上滑动,滑动的间隔为8个像素,opencv中默认的窗口大小为128x64(高128,宽64),即有(128÷8)x(64÷8)=16x8个cell,也即有15x7个block,这样一来一幅图像就可以取到(27-15)x(38-7)=12x31=372个窗口。现在提取每个窗口的HOG特征,则可得到105x36=3780维HOG特征向量。
将这330个3780维的HOG特征当做测试样本,用支持向量机(SVM)分类器来判别出,这些窗口的HOG特征是否有行人,有行人的用矩形框标记起来。HOG行人特征及所对应的SVM分类器的参数,在opencv中已经训练好了,我们只需要得到HOG特征,然后调用SVM即可得到判别结果。
传统方法——DPM
基本思想:提取图像特征,制作激励模板,在原始图像滑动计算,得到激励效果图,根据激励分布确定目标位置。
人为设计一个卷积核,使用卷积核对原图像进行卷积运算计算得到一个特征图,通过特征图来判断是否为所需要的识别的物体,但是由于存在方向或者姿态等影响到我们图像识别的因素,我们在进行识别时可以采用局部识别的方式,例如不去识别一个人的整体而是通过识别一个模板,例如,头,胳膊,腿等方式进行识别。
DPM算法的步骤:
1、产生多个模板,整体模板以及不同的局部模板;
2、拿这些不同的模板同输入图像“卷积”产生特征图;
3、将这些特征图组合形成融合特征;
4、对融合特征进行传统分类,回归得到目标位置。
DPM算法优点:
1、方法直观简单;
2、运算速度块;
2、适应动物变形;
神经网络分类——RCNN
通过分割多个位置,不同尺寸的图片,用卷积神经网络判断图片是否为某物。
RCNN的基本还是按照提取框,对每个框提取特征、图像分类、非极大值抑制等步骤进行识别的。只是在一些小部分上进行了改进。
- 经典的目标检测算法使用滑动窗法依次判断所有可能的区域。而这里预先提取一系列较可能是物体的候选区域,之后仅在这些候选区域上提取特征,进行判断,大大减少了计算量。
- 将传统的特征(如SIFT,HOG特征等)换成了深度卷积网络提取特征。
在训练时使用两个数据库:
- 一个较大的识别库(ImageNet ILSVC 2012):标定每张图片中物体的类别。一千万图像,1000类。
- 一个较小的检测库(PASCAL VOC 2007):标定每张图片中,物体的类别和位置。一万图像,20类。
使用识别库(ImageNet)进行预训练,而后用检测库(VOC fine-tuning)调优参数。最后在检测库上评测。
RCNN算法简述
数据集采用pascal VOC,这个数据集的object一共有20个类别。
首先用selective search方法在每张图像上选取约2000个region proposal,region proposal就是object有可能出现的位置。
然后根据这些region proposal构造训练和测试样本,注意这些region proposal的大小不一,另外样本的类别是21个(包括了背景)。
然后是预训练,即在ImageNet数据集下,用AlexNet进行训练。然后再在我们的数据集上fine-tuning,网络结构不变(除了最后一层输出由1000改为21),输入是前面的region proposal进行尺寸变换到一个统一尺寸227×227,保留f7的输出特征2000×4096维。
针对每个类别(一共20类)训练一个SVM分类器 ,以f7层的输出作为输入,训练SVM的权重4096×20维,所以测试时候会得到2000×20的得分输出,且测试的时候会对这个得分输出做NMS(non-maximun suppression),简单讲就是去掉重复框的过程。同时针对每个类别(一共20类)训练一个回归器,输入是pool5的特征和每个样本对的坐标即长宽。
RCNN的改进——SPP-net
在R-CNN中,候选区域需要进过变形缩放,以此适应CNN输入,那么能不能修改网络结构,使得任意大小的图片都能输入到CNN中呢?作者提出了spatial pyramid pooling结构来适应任何大小的图片输入。
由于FC层的存在,普通的CNN通过固定输入图片的大小来使得全连接层输入固定。作者不这样思考,既然卷积层可以适应任何尺寸,那么只需要在卷积层的最后加入某种结构,使得后面全连接层得到的输入为固定长度就可以了。
在最后的卷积层和全连接层之间加入SPP层。具体做法是,在conv5层得到的特征图是256层,每层都做一次spatial pyramid pooling。先把每个特征图分割成多个不同尺寸的网格,比如网格分别为4×4、2×2、1×1,然后每个网格做max pooling ,这样256层特征图就形成了16×256,4×256,1×256维特征,他们连起来就形成了一个固定长度的特征向量(16+4+1),将这个向量输入到后面的全连接层。

RCNN的改进—fast-RCNN
Fast-cnn可以看做是针对SPP-net与RCNN的增强版,针对两个方法中存在的问题提出了以下的解决方案:
- RCNN中存在大量的重叠的proposal选择框,因为在RCNN中针对每个选择框都需要进行单独的卷积运算,计算量比较大。是否可以缩小计算量?
- 训练的空间需求大。因为RCNN中,独立的分类器和回归器需要很多的特征作为训练。RCNN中提取候选框,提取特征和分类回归是分开的,可独立。
- SPP-net通过最后的maxPooling提取了多个维度的特征,但是计算量依然很大,是否可以再缩减?
针对以上的问题,fastcnn有以下的贡献
- fast-rcnn提出的想法是将整个图进行卷积运算提取特征,将整张图像归一化后直接送入深度网络。在邻接时,才加入候选框信息,在末尾的少数几层处理每个候选框。
- 将regressor放进网络一起训练,每个类别对应一个regressor,同时用softmax代替原来的SVM分类器。
- 用ROI pooling进行特征的尺寸变换,ROI层最后得到的特征为固定值不在需要进行多次的maxpooling,计算量减少。

RCNN的改进—faster-RCNN
经过R-CNN和Fast RCNN的积淀,Ross B. Girshick在2016年提出了新的Faster RCNN,在结构上,Faster RCNN已经将特征抽取(feature extraction),proposal提取,bounding box regression(rect refine),classification都整合在了一个网络中,使得综合性能有较大提高,在检测速度方面尤为明显。
Faster RCNN其实可以分为4个主要内容:
- Conv layers。 作为一种CNN网络目标检测方法,Faster RCNN首先使用一组基础的conv+relu+pooling层提取image的feature maps。该feature maps被共享用于后续RPN层和全连接层。
- Region Proposal Networks。 RPN网络用于生成region proposals。该层通过softmax判断anchors属于positive或者negative,再利用bounding box regression修正anchors获得精确的proposals。
- Roi Pooling。 该层收集输入的feature maps和proposals,综合这些信息后提取proposal feature maps,送入后续全连接层判定目标类别。
- Classification。 利用proposal feature maps计算proposal的类别,同时再次bounding box regression获得检测框最终的精确位置。
对于一个输入的
- 首先缩放至固定大小MxN,然后将MxN图像送入网络;
- Conv layers中包含了13个conv层+13个relu层+4个pooling层;
- RPN网络首先经过3x3卷积,再分别生成positive anchors和对应bounding box regression偏移量,然后计算出proposals;
- 而Roi Pooling层则利用proposals从feature maps中提取proposal feature送入后续全连接和softmax网络作classification

由于对于CNN网络已经比较了解,这里不再叙述feature map的生成过程目前只需要了解这个feature map是由ROI Pooling和RPN共享的。之后主要描述RPN网络以及RoI pooling两个部分。
RPN Region Proposal Networks
下图为RPN网络结构

可以看到RPN网络实际分为2条线
- 上面一条通过softmax分类anchors获得positive和negative分类。
- 下面一条用于计算对于anchors的bounding box regression偏移量,以获得精确的proposal。
- 而最后的Proposal层则负责综合positive anchors和对应bounding box regression偏移量获取proposals,同时剔除太小和超出边界的proposals。其实整个网络到了Proposal Layer这里,就完成了相当于目标定位的功能。
anchors
所谓anchors,实际上就是一组由rpn/generate_anchors.py生成的矩形。直接运行作者demo中的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 \in \left\{ {1:1,1:2,2:1} \right\}三种,如图6。实际上通过anchors就引入了检测中常用到的多尺度方法 。
遍历Conv layers计算获得的feature maps,为每一个点都配备这9种anchors作为初始的检测框。 这样做获得检测框很不准确,不用担心,后面还有2次bounding box regression可以修正检测框位置。

- 在原文中使用的是ZF model中,其Conv Layers中最后的conv5层num_output=256,对应生成256张特征图,所以相当于feature map每个点都是256-dimensions
- 在conv5之后,做了rpn_conv/3x3卷积且num_output=256,相当于每个点又融合了周围3x3的空间信息(猜测这样做也许更鲁棒?反正我没测试),同时256-d不变
- 假设在conv5 feature map中每个点上有k个anchor(默认k=9),而每个anhcor要分positive和negative,所以每个点由256d feature转化为cls=2×k 个scores;而每个anchor都有(x, y, w, h)对应4个偏移量,所以reg=4×k 个偏移量。
- 补充一点,全部anchors拿去训练太多了,训练程序会在合适的anchors中随机选取128个postive anchors+128个negative anchors进行训练
其实RPN最终就是在原图尺度上,设置了密密麻麻的候选Anchor。然后用cnn去判断哪些Anchor是里面有目标的positive anchor,哪些是没目标的negative anchor。所以,仅仅是个二分类而已!

bounding box regression原理
所示绿色框为飞机的Ground Truth(GT),红色为提取的positive anchors,即便红色的框被分类器识别为飞机,但是由于红色的框定位不准,这张图相当于没有正确的检测出飞机。所以我们希望采用一种方法对红色的框进行微调,使得positive anchors和GT更加接近。

针对红框变为绿框中需要进行的变化为平移以及拉伸,对于长宽分别需要两个数字表示,因此共需要4个元素进行变换。
针对这个要求得到对应的损失函数为

在了解bounding box regression后,再回头来看RPN网络第二条线路
Proposal Layer负责综合所有[d_x(A),d_y(A),d_w(A),d_h(A)] 变换量和positive anchors,计算出精准的proposal,送入后续RoI Pooling Layer。
RPN网络结构就介绍到这里,总结起来就是:
生成anchors - > softmax分类器提取positvie anchors -> bbox reg回归positive anchors -> Proposal Layer生成proposals
ROI pooling
ROI层的特点已经在上面说通过不同的输入图像,提取出特定相同大小的特征图方便特征的计算。
Classification
Classification部分利用已经获得的proposal feature maps,通过full connect层与softmax计算每个proposal具体属于那个类别(如人,车,电视等),输出cls_prob概率向量;同时再次利用bounding box regression获得每个proposal的位置偏移量bbox_pred,用于回归更加精确的目标检测框。Classification部分网络结构如下图。

神经网络回归——YoLo
在分类中我们最后在fasterRCNN中使用了proposal进行了特征框的提取。那能否在特征框的提取中进行目标的检测呢?

YoLo的主要分为两步走:
- 对于图像进行分割
- 对于图像进行预测
分割
为了减少滑动窗口的计算量,对于图片的计算中是直接进行图片的分割(已经resize成一个固定大小的输入),例如一个256×256大小的一个图片,分割成一个S×S大小的网络,每个单元格中会预测B个边界框,以及每个边界框的置信度。
每个边框的置信度包括两个方面,边框含有目标的可能性Pr(Object)(是否为背景,如果为背景则为0)以及IOU交并比。其实置信度的定义为两个相乘:

在置信度之后还要给出每个分类的预测值C。
总结一下
每个单元格需要预测 (B*5+C) 个值。如果将输入图片划分为 S×S 网格,那么最终预测值为 S×S×(B*5+C)大小的张量。整个模型的预测值结构如下图所示。对于PASCAL VOC数据,其共有20个类别,如果使用 S=7,B=2 ,那么最终的预测结果就是7×7×30大小的张量。每个单元格的预测值的分布位置为(20个类别的概率+两个预测框的可信度+两个4维的预测框的偏移量)。
预测
Yolo算法将目标检测看成回归问题,所以采用的是均方差损失函数。但是对不同的部分采用了不同的权重值。
损失函数如下:

第一项是边界框中心坐标的误差项,第二项是边界框的高与宽的误差项,第三项是包含目标的边界框的置信度误差项,四项是不包含目标的边界框的置信度误差项。
神经网络回归——SSD
待续
