赞
踩
2014年提出,可以说是利用深度学习进行目标检测的开山之作,将识别准确率从30%多提高到50%多。与R-CNN同一时期的深度学习方法有overfit,但效果没有RCNN好,故听说得少。
① R-CNN算法流程四步
第二步:这里的深度网络指的是图片分类网络,这里将候选区域丢入到特征提取网络就能得到特征向量;
第四步:因为通过SS算法框定的候选框不是那么准,于是选用回归器修正候选框的位置;
Ⅰ 候选区域的生成
通过SS算法在一张图片上生成1k~2k个区域
Ⅱ 对每个候选区域,使用深度网络提取特征
对候选框进行resize处理,不管候选框是什么形状,都要被缩放到227×227pixel的大小;接着输入到CNN网络就能得到一个特征向量了。(一张图片得到一个2000×4096维矩阵)这里用的CNN就是图像分类网络,只不过将全连接层去掉,(在之前所讲的分类网络当中,最后都是首先将向量进行展平处理,然后将展平处理的向量输入到全连接层中),直接得到一个特征向量,这里每一个向量都是4096维,有2k个候选框,所以最后得到一个2000×4096的特征矩阵。矩阵的每一行对应一个候选区域的特征向量。
Ⅲ 特征送入到每一类的SVM分类器,判定类别
① SVM分类器
SVM是一个二分类的分类器,针对每一个类别都有一个专门的分类器,以Pascal VOC数据集为例,在VOC数据集中有20各类别,所以这里有20个SVM分类器。这20个分类器又组成了4096×20的权值矩阵,将特征矩阵与权值矩阵相乘得到2000×20的评分矩阵,评分矩阵表示每个建议框是某个目标类别的得分(属于每个类别的概率)
如图中所示,以2000个候选区域中的一个为例,(本应该是个行向量,因为摆不下所以写成了列向量的形式),将行向量输入到SVM分类器中,就会得到一个分数。
左边是个特征矩阵,每一行就是一个候选框通过CNN得到的一个特征向量,然后有2000个候选框,特征矩阵有2000行;中间的是SVM的权值矩阵,每一列就对应一个类别的权值向量,一共有20个,拼接在一起就得到一个4096×20的权值矩阵。假设第一列代表我们所需检测的猫,第二列代表我们所需检测的狗,那么将候选区域一得到的矩阵向量(第一行)与权值矩阵类别一(第一列)相乘,就得到,2000×20概率矩阵的第一行的第一个元素,也就是对应着我们第一个候选框为猫的概率;再将我们第一个候选框的概率与我们SVM的第二个分类器(判定是否为狗的分类器)相乘,得到第一行的第二个元素,也就是第一个候选框为狗的概率,以此类推,有二十个概率。一共有2000个候选框,所以会有2000行。
然后对每一类即矩阵的每一列进行非极大值抑制,去剔除一些重叠的建议框,从而保留一些高质量的建议框。比如说,2000×20矩阵的第一列代表所有候选框为猫的概率,第一列的第一个元素就代表着第一个候选框为猫的概率,第一列的第二个元素就代表着第二个候选框为猫的概率。
② 非极大值抑制算法
Intersection over Union 两个目标框的交并比,表达形式为A与B的交集➗A与B的并集
目标候选框 <==> 边界框
对于每个类别,首先寻找SVM算法得分最高的目标候选框(即概率最大的目标),然后计算其他目标与该目标的IOU值,我们对每一个目标与最高得分的IOU值进行判断,如果该IOU值大于给定阈值的话,就删除目标框(因通过IoU计算为同一物体),然后将得到的最高得分的目标存起来。再在剩下的目标候选框中寻找得分最高的目标,以此类推,直到将所有的候选框遍历完。
Ⅳ 特征送入到每一类的SVM分类器,判定类别
通过SS算法得到的候选框位置并不准确,因此要通过一系列的回归器去修正候选框的位置,是对非极大值抑制后剩余的候选框进一步筛选。原论文中描述的是,保留那些与真实值标注的目标边界框(GT)有相交,并且它的IOU要大于某一阈值,不满足的候选框删除掉。接着再使用20个回归器,对20个类别中剩余的建议框进行回归操作,最后得到每个类别修正后得分最高的bbox。
回归器的具体训练方法,后面描述。
算法流程分为三步
这里的第二步就已经与R-CNN完全不同了,之前是将每一个候选区域分别送入网络得到特征向量,这里直接将整幅图像直接输入CNN网络中得到相应的特征图,然后将SS算法生成的候选框映射到特征图上,就可以得到特征矩阵。
ROI (region of interest) 即感兴趣区域,将得到的特征图进行展平处理,通过一系列全连接层,得到目标所属的类别以及边界框的回归参数。与R-CNN不同,前者训练了SVM分类器对候选区域进行分类,同时训练了回归器对候选区域框进行调整;在Fast R-CNN中,已经结合在一个网络中了,不用单独训练分类器和边界框回归器。
一次性计算整张图像特征,然后根据原图中的候选框映射到特征图上,得到特征矩阵。
训练数据的采样(正样本,负样本)
在训练时,并不是选用SS算法提供的所有候选区域,SS算法能得到大约2k个候选框,但训练的时候,使用其中的一小部分,并对采样的数据分正、负样本。正样本即在候选框中确实存在我们所学检测目标的样本,负样本简单理解为背景,即没有我们想要检测的目标。
分正负样本的原因:如果我们数据样本分为猫样本和狗样本,如果去训练一个猫狗分类器,猫样本数量远大于狗样本的话,即数据不平衡,那么网路在预测过程中就会更偏向于猫,这样的预测是不对的。同理,如果全都是正样本的话,网络会以很大的概率认为我们的候选区域很大概率认为我们的候选区域是我们的目标,可能框里面就是个背景,也会被认为是目标。
原论文中,从2000个候选框中采集64个候选区域,候选区域中有一部分是正样本,有一部分是负样本。正样本定义:候选框与GT的IOU大于0.5,就认为是正样本,在正样本中采集一部分;负样本:与所有真实边界目标框IOU值最大的,在0.1到0.5之间的为负样本。
只需要明白在Fast R-CNN的训练过程中并不是直接使用SS算法提供的所有的候选框,而是随机采样了一部分进行训练。
ROI pooling层实现
对得到的特征图(下图只是模拟的特征图,实际的特征图是高级语义特征)的第一个块进行最大池化下采样,得到0.1,最终得到一个7×7的特征矩阵。无论候选区域的特征矩阵是什么尺寸,都统一缩放到7×7大小,这样就能不限制输入图像的尺寸。在R-CNN中,输入图像的尺寸只能为227×227,而在Fast R-CNN中不对输入图像尺寸进行限制。
网络框架分析
将整张图像输入CNN网络得到特征图,根据ROI映射关系得到特征矩阵,然后对每个特征矩阵都经过一个ROI pooling层,缩放到一个指定的尺寸。这步之后,进行一个展平处理,通过两个全连接层,得到我们的feature vector。在ROI feature vector的基础上并联两个全连接层,其中一个全连接层用于目标概率的预测,另外一个用于边界框回归参数的预测。
目标概率的分类器
分类器会输出N=1个节点的概率,输出的第一个概率为当前候选框为背景的概率,后面的为我们所需检测的每个类别的概率,因为经过了softmax处理,所以符合概率分布,即概率之和为1。
边界框回归器
输出的对应每个类别都会有四个参边界框参数。
如何利用预测框回归参数,得到预测的边界框?
P代表候选框的参数,G帽代表最终预测的边界框参数,d代表通过全连接层输出的边界框回归参数。dx,dy是用来调整候选框中心点坐标的回归参数,exp为e的dx次方(指数运算)。运算之后,能将黄色候选框调整到红色候选框的位置。
Fast R-CNN的损失计算
分类损失的计算
在原论文中,作者说分类损失是通过log损失进行计算的,log损失就是指交叉熵损失,pu代表分类器预测当前候选框区域为类别u的概率,u的取值从0到k,代表标签类别从背景到各目标类别。
交叉熵损失
Oi*只有在预测正确的位置时等于1的,其余位置是等于0的,因此可以全部省去,只留下i=u(u代表真实标签)的那一项,Oi*=1,Oi即为Ou。
边界框回归损失(定位损失)
smoothL1损失,可以参考链接:https://www.cnblogs.com/wangguchangqing/p/12021638.html
[u≥1]是艾弗森括号:当u≥1时,值等于1;当不满足u≥1时,值等于0(u代表真实标签,u≥1代表候选区域确实属于目标中的某个类别,即为候选框对象为正样本,此时才有回归损失;当不满足u≥1时,即u=0,即为负样本背景,背景没有边界框回归损失)
v对应真实目标框的回归参数,如何计算?
将G帽替换成G即可计算(vx,vy,vw,vh)
总损失=分类损失+回归损失,然后进行反向传播就可以训练Fast R-CNN网络。
Fast R-CNN框架分为两部分
虽然Fast R-CNN比R-CNN推理快了200多倍,但上一部分(SS算法)在CPU上需要两秒左右的时间,而下一部分只需要零点几秒的时间。
用RPN(region proposal network)替代SS(selective search)网络生成候选框
RPN网络结构
在利用骨干网络提取得到的特征图上用3×3的滑窗,每滑动到一个位置,就生成一个一维的向量,在此一维向量的基础上通过两个全连接层分别输出目标概率(2k)以及边界框回归参数(4k),k为anchor boxes的数量,2k为针对每个anchor生成的两个概率scores(一个是它为背景的概率,一个是它为前景的概率)。针对每个anchor会生成4k个回归参数。
ZF:256,VGG16:512,;当将ZF网络作为backbone,那么它所生成的特征图的深度(channel)为256;如果使用的是VGG16,那么它所生成的特征图深度(channel)为512。所以这里一维向量元素的个数是根据所使用的backbone输出特征矩阵的深度(channel)来确定的。
如何在原图上找到特征图上对应的点:
【x方向】首先将原图宽度除以特征图的宽度然后取整得到步距,然后特征图x方向是第3个位置,那么对应在原图上就是:步距×3
【y方向】首先将原图高度除以特征图的高度然后取整得到步距,然后特征图y方向是第2个位置,那么对应在原图上就是:步距×2
anchor boxes
根据特征图的中心点位置找到对应原图的中心点位置,然后以原图的这个位置为中心生成一系列anchor,这些anchor中可能包含了要检测的目标,也有可能没有。
2k scores以及4k个coordinates是如何影响anchor的,比如说cls第一个anchor的值为0.1,0.9(0.1代表为前景的概率为0.1,0.9代表为背景的概率为0.9)reg中的四个参数,dx,dy是对anchor的中心点坐标进行调整,dw,dh是对anchor的宽和高进行调整,通过边界框回归参数调整之后,希望bbox能够尽可能准确的框选出目标
anchor boxes的尺度和比例,论文中给了三种尺度和三种比例,针对每一个中心点都会生成一共9个anchor。
Q:VGG的感受野最大只有228,没有所给的512²的anchor尺度大,为什么可以预测相应的边界框?
A:通过经验,我们看到物体的一部分,其实也能够大概的猜出这个目标完整的一个大概的区域的。
ZF网络感受野计算
1000×600的图片通过特征提取网络之后,大小变为60×40。
对于这6k个anchor使用RPN生成的相应边界框回归参数,将这6k个anchor调整成为6k个候选框,也就是proposal。注意:我们使用这里的anchor和proposal不是同一个东西,我们是利用RPN生成的边界框回归参数将anchor调整为所需要的候选框。
然后根据cls得分,采用非极大值抑制,iou设为0.7,这样每张图片只剩2k个候选框,这样就得到了与ss网络差不多数目的候选框。
在rpn网络生成的2000个候选框之后选取的正负样本应该是fast-rcnn训练的,而rpn网络用于训练的样本应该是在所有的anchor的基础上进行筛选的。
RPN网络的实现
这里的滑动窗口是使用3×3(stride为1,padding也为1)的卷积来进行处理的,这样滑动窗口就能遍历特征图的每一个点,处理完之后,生成了一个高度和宽度与特征图一样的特征矩阵,深度也是与我们特征矩阵一样。然后并联两个1×1的卷积层,对我们的类别(卷积层大小为1×1,卷积层个数为2k)与边界框回归参数进行预测(卷积层大小为1×1,卷积层个数为4k)
训练RPN的过程中采用的正负样本
生成的候选框,并不是都用来训练RPN网络,对于每张图片都有上万个anchor,我们采样256个anchor,这256个anchor由正样本和负样本两部分组成,比例大概为1:1左右,如果正样本个数不足128,那么就用负样本进行填充。比如说在一张图片中正样本数只有100个,是不足128的,那么就采用256-100=156个负样本。
RPN中如何定义正样本,负样本?
训练RPN时是直接从所有anchors中选取正负样本的,不是从最终得到的2000个proposal对应的anchors中选取。
正样本:条件①:与GT相交的,IOU最大的一个anchor(这是对定义②的一个补充,通常使用第二个就能生成足够的正样本,但是在极少数情况下,使用第二个条件是找不到正样本的);条件②:只要anchor与GT的IOU>0.7就是正样本了;
负样本:与所有的GT的IOU都小于0.3;
正负样本之外的anchor全都丢弃掉。
RPN损失计算
Nreg是anchor位置的个数,即中心点的个数;入是平衡参数,用来平衡分类损失以及边界框回归损失。
分类损失
按照原论文理解,应该是个多类别的交叉熵损失,但实质上是个前景和背景的二分类损失,因此很多其他资料就简化为了二分类的交叉熵损失,这里按照原论文理解。
① 多分类交叉熵损失
② 二分类交叉熵损失
边界框回归损失
Fsat R-CNN多类别损失
分类损失
回归损失
Faster R-CNN的训练
现在直接将RPN Loss与Fast R-CNN Loss直接加在一起算总损失,进行反向传播。
论文中,先训练RPN的网路参数,再固定RPN网络参数,训练Fast R-CNN网络参数
然后固定Fast R-CNN网络参数,再微调RPN网络参数,巴拉巴拉
Faster R-CNN框架
融合成一个网络,形成一个端对端的网络
RPN层(region proposal network)。
近乎实时的real-time
state-of-the-art 当前最牛的
RPN网络做最小化时间的代价,全卷积的网络结构,无全连接层了
code has been made publicly available 代码公开了
SS算法只能在CPU上跑,没法在GPU中跑,速度太慢了,因此需要改进
分类+回归
对不同大小的图像进行识别
①图像resized(图像金字塔),输入变多了,可以检测大小物体,但是速度非常慢
②对于filter做不同尺寸的变化
论文的读法:
通读一篇(2h)理清楚整体思路
第二遍慢慢扣
五遍左右才能真正理解
全卷积层是没有显示,image任意的size都是可以的
但有全连接层的时候是对图片大小有限值的
RPN层中关注的是:它是不是物体,即是背景还是前景的得分(二分类)
1个pool池化层,将原图缩放到原来的1/2
用1×1的全卷积层替代全连接层
a convolutional feature map of a size W×H(typically~2,400个像素点),每个点在原图上对应着k=9个候选框(3 scales and 3 aspect ratios),大致WHk=2w个候选框
基于特征图进行映射,cost-efficient比较省时间
IOU>0.7的为正例
IOU<0.3的为负例
其他的就不管了
stochastic gradient decent(SGD)
高斯初始化(标准差0.01)
①先过滤边界
②再过滤重复的框:采用NMS非极大值抑制,如果框与框之间的重叠比例大于0.7,那么再看FPN层是前景的得分值,得分值更高者的保留下来,低的就去掉了。
阈值0.7
③top-N ranked,对得分高的前景框进行一个排序,选取排序靠前的
用精度和recall可以做出一条曲线,曲线下方的面积为AP值
mAP则是对所有类别来说求了一个平均值(检测任务的典型指标)
region of image database (riodb)
index 索引值
image_set图片的一个设置分类
对图像进行反转(使得图像集更加丰富,使得数据量翻倍)flipped
进行反转的时候,还要获得图片的宽度,以此对框的坐标进行变化(坐标的映射)
第一次读数据的时候for index in self.image_index(每一个数据都要去读)
后续就可以直接pickle.load缓存文件
缓存文件cache_file,因为数据是不会变化的,所以可以将数据缓存起来,以便以后直接读取缓存文件.pkl
.xml文件的解析,直接调库ET.
np.zeros实现占位(进行初始化)
overlaps重叠部分归属于哪一类,比如说是属于第九类,那么这个overlaps是与第九个重叠
rb读;wb写
Summary
:所有需要在TensorBoard上展示的统计结果。
tf.summary.scalar()
:添加标量统计结果。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。