从RCNN经SPPNet、Fast RCNN到Faster RCNN(RCNN系列白话叙述)
RCNN
RCNN 简述
RCNN可以说是将CNN引入到目标检测领域的开山之作,这和以往的单纯用机器学习的方法相比,性能大幅度提升。
RCNN算法总的来说分为四步:
1.输入一张图片,采用selective search的方法生成2k个region proposals(候选区域),并将每个候选区域裁剪缩放至固定尺寸大小(227×227);
2.对于每一个候选区域,使用卷积神经网络来提取特征,这里可以用AlexNet或者VGG都可以,得到4096维的特征向量(2000×4096);
3.将特征送入到每一类的SVM分类器中(4096×N,N是类别数),判断是否属于该类;
4.使用回归器精细修正候选框的位置。
RCNN中用到的一些方法和问题:
1.selective search 根据图像的颜色、纹理、面积和位置等先生成若干小的区域,再逐步合并,最后形成region proposals
2.缩放至固定尺寸大小,论文中提到了两种方法,一种叫做各向异性缩放,不管图片长宽比例,直接缩放,会造成图片扭曲变形;一种叫做各向同性缩放,先扩充后缩放或者先裁剪后扩充。最终作者选择了各向异性缩放,同时进行padding=16。
3.CNN特征提取阶段,采用了先在辅助任务(图像分类)上有监督的预训练,再在指定任务(目标检测)上微调(fine-tuning),用到了迁移学习的思想。为什么这样做呢,因为有标签的训练数据少,直接初始化效果不佳。
4.正负样本的问题 对于一张图片,经过selective search后得到了2000个候选框,对于这2000个候选框哪些与人工标注的框匹配,在CNN阶段我们用计算IOU的方法将这2000个候选框分为正负样本。如果候选框与标注框的IOU大于0.5,则该候选框定义为正样本,反之则定义为负样本。这样操作,最终得到的正负样本数肯定是负样本数量远远大于正样本数量(一张图中的目标数量或者说标注框的数量毕竟还是少数),每个batch训练128个候选框,包含32个正样本和96个负样本。
5.hard negative mining 难分样本挖掘 因为出现了正负样本不均衡的问题,所以采用了hard negative mining方法,把在训练时产生的假正例false postive中得分较高的样本重新放入网络中训练,从而加强网络对false postive的判断能力。
6.为什么最后一层不用softmax直接进行分类,而要用SVM?这是因为svm训练和cnn训练过程的正负样本定义方式各有不同,导致最后采用CNN softmax输出比采用svm精度还低(当时就试验过了)。cnn在训练的时候,对训练数据做了比较宽松的标注,比如一个bounding box可能只包含物体的一部分,那么我也把它标注为正样本,用于训练cnn;采用这个方法的主要原因在于因为CNN容易过拟合,所以需要大量的训练数据,所以在CNN训练阶段我们是对Bounding box的位置限制条件限制的比较松(IOU只要大于0.5都被标注为正样本了);然而svm训练的时候,因为svm适用于少样本训练,所以对于训练样本数据的IOU要求比较严格,我们只有当bounding box把整个物体都包含进去了,我们才把它标注为物体类别,然后训练svm。
7.位置精修方面,对每一类目标,使用一个线性脊回归器进行精修。正则项λ=10000。 输入为深度网络pool5层的4096维特征,输出为xy方向的缩放和平移。 训练样本:判定为本类的候选框中和真值重叠面积大于0.6的候选框。
SPPNet
SPPNet简述
SPPNet是在RCNN的基础上做了改进,对于RCNN,每张图片通过 Selective Search 选择2000个建议框,通过变形,利用CNN提取特征,分成两路,一路svm进行分类,一路回归对位置精修。
裁剪变形有很大问题,裁剪会导致信息的丢失,变形会导致位置信息的扭曲变形。
为什么要进行裁剪变形呢?这是因为CNN的输入需要固定的尺寸;
那为什么CNN需要固定尺寸呢?这是因为在CNN中卷积层可以接受任意尺寸的图像,而到了全连接层则必须是固定尺寸的特征向量。
有什么方法可以让输入图像的尺寸不受限制?SPPNet解决了这一问题!
SPPNet主要是在R-CNN的基础上进行改进的,它仍然延续R-CNN的多阶段的处理过程:
1.输入一张图片,采用selective search的方法生成2k个region proposals(候选区域)
2.使用CNN对输入图片进行特征提取并将提取的候选区域(region proposal)映射到conv5的feature map,使用SPP layer统一feature的输出送入全连接层
3.提取到的feature输入到SVM中进行分类
4.Non-maximum suppression,用于去除掉重复的box
5.使用回归器精细修正候选框的位置
和RCNN对比来看,SPPNet只需要对整张图做一次卷积,RCNN则需要对每个region proposal都做一次卷积,大大节省了时间;另一方面,SPPNet引入了SPP layer,这使得输入图片的尺寸不再受限制,这是一个大的突破。
SPPNet中用到的一些方法和问题:
1.原图位置与特征图的映射关系
卷积仍然保留了空间位置关系,也就是说原图上的位置与特征映射图的位置是对应的,之间存在了某种关系,所以可以根据原图的位置找到对应的特征映射图的位置,从而得到特征。需要确定两个映射,一个是尺寸大小的映射,一个是位置坐标的映射,相关公式推导这里先省去,可以去查看相关资料。
2.SPP Layer(spatial Pyramid Pooling空间金字塔池化层)
空间金字塔池化层是SPPNet的核心,其主要目的是对于任意尺寸的输入产生固定大小的输出。将SPP层放在最后一个卷积层之后。SPP层对特征图进行池化,并产生固定长度的输出,这个输出再喂给全连接层(或其他分类器)。思路是对于任意大小的feature map首先分成16、4、1个块,然后在每个块上最大池化,池化后的特征拼接得到一个固定维度的输出,以满足全连接层的需要。不过因为不是针对于目标检测的,所以输入的图像为一整副图像。
输入M ×M 13×13 输出N×N 3×3、2×2、1×1
要预先计算每个的卷积核大小window size和步长stride
其中 window size = ceil(M/N)、stride=floor(M/N) ceil是向上取整,stride是向下取整
1.window size =ceil(13/3)= 5 stride=floor(13/3)=4
2.window size =ceil(13/2)= 7 stride=floor(13/1)=6
3.window size =ceil(13/1)= 13 stride=floor(13/1)=13
4.单尺度、多尺度训练 虽然可以实现任意尺寸大小的图片输入来训练,但是每次喂给网络batch个的样本的尺寸大小还是要一样的,不然卷积无法计算了。所以作者将网络训练分成了single-size和multi-size。
单一尺寸训练,仍然把输入限制在固定尺寸,只是在卷积之后加上空间金字塔池化层,这个尝试的目的是开启多级别池化行为;
多尺寸训练,输入为不同尺寸,并且包含空间金字塔池化,目的是模拟多尺度输入的训练。作者预先设定了2个尺寸,224224 和 180180,224通过裁剪得到,180通过缩放得到;
对于输入为180的网络,卷积层一样,空间金字塔池化层设计池化野和步长,接上全连接;
对于输入为224的网络,卷积层一样,空间金字塔池化层设计池化野和步长,接上全连接,这样两个网络的参数就一样了,池化不需要参数。
在训练时,我们一个epoch输入224(或者180)的图片,训练参数,保存参数;下一个回合先读取参数,再输入180(或者224)的图片,进行训练,保存参数,依次交替进行。这样的本质是通过共享参数的多个固定输入的网络实现了不同尺寸输入的SPPNet。
Fast RCNN
Fast RCNN简述
Fast RCNN是在RCNN和SPPNet的基础上又做了改进,对于RCNN,训练分为多步(先预训练、再fine-tuning、还需要对每个类别单独训练SVM分类器、还要用回归器对位置精修),步骤繁琐,时间、内存消耗大,同时存在重复卷积的问题。SPPNet虽然解决了RCNN重复卷积的问题,但是其他问题基本上和RCNN一样没有改进。针对这种情况,Fast RCNN应运而生。
Fast RCNN主要是对RCNN的后面三个步骤进行了改进:
1.输入一张图片,采用selective search的方法生成2k个region proposals(候选区域)
2.使用CNN对输入图片进行特征提取并将提取的候选区域(region proposal)映射到feature map
3.将每个特征框划分为 H×W个网格(论文中是 7×7 ),在每个网格内进行池化(即每个网格内取最大值),这就是ROI池化。这样每个特征框就被转化为了7×7×C的矩阵(其中C为深度)
4.对每个矩阵拉长为一个向量,分别作为之后的全连接层的输入,全连接层的输出有两个,计算分类得分和bounding box回归(bounding box表示预测时要画的框)。前者是sotfmax的21类分类器(假设有20个类别+背景类),输出属于每一类的概率(所有建议框的输出构成得分矩阵);后者是输出一个 20×4的矩阵,4表示(x, y, w, h),20表示20个类,这里是对20个类分别计算了框的位置和大小
5.对输出的得分矩阵使用非极大抑制方法选出少数框,对每一个框选择概率最大的类作为标注的类,根据网络结构的第二个输出,选择对应类下的位置和大小对图像进行标注
Fast RCNN中用到的一些方法和问题:
1.ROI pooling layer(ROI 池化) RoI池化层使用最大池化将任何有效的RoI内的特征转换成具有H×W(例如,7×7)的固定尺度的小特征图,其中H和W是层的超参数,独立于任何特定的RoI。在本文中,RoI是卷积特征图中的一个矩形窗口。 每个RoI由指定其左上角(r, c)及其高度和宽度(h, w)的四元组(r, c, h, w)定义。RoI最大池化通过将大小为h×w的RoI窗口分割成H×W个网格,子窗口大小约为h/H×w/W,然后对每个子窗口执行最大池化,并将输出合并到相应的输出网格单元中。同标准的最大池化一样,池化操作独立应用于每个特征图通道。RoI池化层从特征图中提取一个固定长度的特征向量(这一点和sppnet实现愿望相同,用RoI池化层替代SPP层(实际上是一种特殊的只有一层的SPP层))
2.反向传播训练所有网络权重 SPPnet不能更新所有的权重,不能更新spp之前层的参数。根本原因是当每个训练样本(即RoI)来自不同的图像时,通过SPP层的反向传播是非常低效的,这正是训练R-CNN和SPPnet网络的方法。低效的部分是因为每个RoI可能具有非常大的感受野,通常跨越整个输入图像。由于正向传播必须处理整个感受野,训练输入很大(通常是整个图像)。
论文提出了一种更有效的训练方法,利用训练期间的特征共享。在Fast RCNN网络训练中,随机梯度下降(SGD)的小批量是被分层采样的,首先采样N个图像,然后从每个图像采样R/N个 RoI。关键的是,来自同一图像的RoI在向前和向后传播中共享计算和内存。减小N,就减少了小批量的计算。例如,当N = 2和R = 128时,得到的训练方案比从128幅不同的图采样一个RoI(即R-CNN和SPPnet的策略)快64倍。
3.在微调阶段联合优化Softmax分类器和检测框回归,而不是分别在三个独立的阶段训练softmax分类器,SVM和回归器。
损失函数 一个Fast RCNN网络有两个输出层,第一个输出为K+1个类别的离散概率分布,而第二个输出为bbox回归的偏置,每一个正在训练的ROI均利用一个ground truth类别u与ground truth框v,采用多任务损失进行分类与边框回归:
第一部分是类别的log损失,第二部分是位置的回归损失。V为ground truth, t为预测值,方括号是一个指示函数,满足条件为1,否则为0,按照惯例,u=0为背景类,此时忽略回归损失,对于检测框的回归采用了smooth-L1损失,没有使用L2损失,这个损失函数相比于L2损失对于对于异常值更加鲁棒。
4.ROI pooling如何进行反向传播
无论max pooling还是average pooling,都没有需要学习的参数。因此,在卷积神经网络的训练中,Pooling层需要做的仅仅是将误差项传递到上一层,而没有梯度的计算。
(1)max pooling层:对于max pooling,下一层的误差项的值会原封不动的传递到上一层对应区块中的最大值所对应的神经元,而其他神经元的误差项的值都是0;
(2)mean pooling层:对于mean pooling,下一层的误差项的值会平均分配到上一层对应区块中的所有神经元。
5.在全连接层使用SVD分解来减少计算时间
6.模型在各种数据集上的测试效果及对比
7.在迁移学习基础上更新哪些层的参数实验
8.直接输出两个层是否真的有优势,SVM V.S. softmax,输入多种规格的图片,更多训练数据等等