您的位置:首页 > 其它

目标检测算法学习----Fast RCNN

2019-05-14 21:15 211 查看

Fast rcnn

  • RCNN结构
  • 特征提取网络
  • 网络参数训练
  • Fast RCNN的检测
  • https://www.geek-share.com/detail/2671437502.html

    fast rcnn的改进

    主要改进了三个问题:
    问题1:测试速度慢
    RCNN一张图像内候选框之间大量重叠,提取特征操作冗余。
    本文将整张图像归一化后直接送入深度网络。在邻接时,才加入候选框信息,在末尾的少数几层处理每个候选框。
    问题2:训练时速度慢
    原因同上。
    在训练时,本文先将一张图像送入网络,紧接着送入从这幅图像上提取出的候选区域。这些候选区域的前几层特征不需要再重复计算。
    问题3:训练所需空间大

    RCNN很慢的原因主要是因为没有共享计算。SPPNet就通过共享计算提高了速度,它在ConvNet的最后一个卷积层才提取proposal,但是依然有不足之处。和R-CNN一样,它的训练要经过多个阶段,特征也要存在磁盘中,另外,SPP中的微调只更新spp层后面的全连接层,因为卷积特征是线下计算的,从而无法再微调阶段反向传播误差。对很深的网络这样肯定是不行的。

    RCNN中独立的分类器和回归器需要大量特征作为训练样本。
    本文把类别判断和位置精调统一用深度网络实现,不再需要额外存储。

    RCNN结构

    训练过程

    1、网络首先用几个卷积层(conv)和最大池化层处理整个图像以产生conv特征图。
    2、然后,对于每个对象建议框(object proposals ),感兴趣区域(region of interest——RoI)池层从特征图提取固定长度的特征向量。
    3、每个特征向量被输送到分支成两个同级输出层的全连接(fc)层序列中:
    其中一层进行分类,对 目标关于K个对象类(包括全部“背景background”类)产生softmax概率估计,即输出每一个RoI的概率分布;
    另一层进行bbox regression,输出K个对象类中每一个类的四个实数值。每4个值编码K个类中的每个类的精确边界盒(bounding-box)位置,即输出每一个种类的的边界盒回归偏差。整个结构是使用多任务损失的端到端训练(trained end-to-end with a multi-task loss)。

    测试过程

    • 任意size图片输入CNN网络,经过若干卷积层与池化层,得到特征图;
    • 在任意size图片上采用selective search算法提取约2k个建议框;
    • 根据原图中建议框到特征图映射关系,在特征图中找到每个建议框对应的特征框【深度和特征图一致】,并在RoI池化层中将每个特征框池化到H×W【VGG-16网络是7×7】的size;
    • 固定H×W【VGG-16网络是7×7】大小的特征框经过全连接层得到固定大小的特征向量;
    • 上一步所得特征向量经由各自的全连接层【由SVD分解实现】,分别得到两个输出向量:一个是softmax的分类得分,一个是Bounding-box窗口回归;
    • 利用窗口得分分别对每一类物体进行非极大值抑制剔除重叠建议框,最终得到每个类别中回归修正后的得分最高的窗口。

    与SPPNet比较

    • SPP-Net在实现上无法同时tuning在SPP layer两边的卷积层和全连接层。
    • SPP-Net后面的需要将第二层FC的特征放到硬盘上训练SVM,之后再额外训练bbox regressor。

    特征提取网络

    基本结构

    图像归一化为224×224直接送入网络。

    前五阶段是基础的conv+relu+pooling形式,在第五阶段结尾,输入P个候选区域(图像序号×1+几何位置×4,序号用于训练)。

    roi_pool层的测试(forward)

    roi_pool层将每个候选区域均匀分成M×N块,对每块进行max pooling。将特征图上大小不一的候选区域转变为大小统一的数据,送入下一层。

    roi_pool层的训练(backward)

    首先考虑普通max pooling层。设xi为输入层的节点,yj为输出层的节点。


    其中判决函数δ(i,j)表示i节点是否被j节点选为最大值输出。不被选中有两种可能:xi不在yj范围内,或者xi不是最大值。
    对于roi max pooling,一个输入节点可能和多个输出节点相连。设xi为输入层的节点,yrj为第r个候选区域的第j个输出节点。


    判决函数δ(i,r,j)表示i节点是否被候选区域r的第j个节点选为最大值输出。代价对于xi的梯度等于所有相关的后一层梯度之和。

    网络参数训练

    参数初始化

    网络除去末尾部分如下图,在ImageNet上训练1000类分类器。结果参数作为相应层的初始化参数。

    作者实验了三个预训练的ImageNet 网络:CaffeNet,VGG_CNN_M_1024,VGG-16,每个网络有五个最大池层和五到十三个转换层。当预训练网络初始化Fast R-CNN网络时,要经历三个transformations:
    1、最后一个最大池化层由 RoI 池化层代替,该层将 H 和W 设置为与第一个全连接层兼容;
    2、网络最后的全连接层和softmax(被训练用于1000路ImageNet分类)被替换为前面描述的两个同级层:softmax的对K+1个类别的分类层,和bounding box 回归层
    3、网络输入修改为两种数据:一组图片和每张图片的一组RoIs

    分层数据

    在调优训练时,每一个mini-batch中首先加入N张完整图片,而后加入从N张图片中选取的R个候选框。这R个候选框可以复用N张图片前5个阶段的网络特征。
    实际选择N=2, R=128。

    训练数据构成

    作者从对象建议框(object proposal)中选择25%的RoI,这些RoI与ground-truth bbox边界框至少有0.5的部分交叉重叠,也就是正样本,即 u >= 1。其余的RoI选那些IoU重叠区间在[0.1,0.5)的,作为负样本,即 u = 0,大约为75%。之所以选择负样本需要大于0.1的阈值是因为使用启发式的hard example mining(低于0.1的IoU作为难例挖掘的启发式)。在训练期间,图像有0.5的概率水平翻转。

    检测中的微调

    Fast R-CNN用反向传播训练所有网络权重。首先,作者说明了为什么SPPnet无法更新空间金字塔池化层之前的层的权重:当每个训练样本(即RoI)来自不同的图像时,通过SPP层的反向传播非常低效。低效源于每个RoI可能具有非常大的感受野(接收区),通常包括整个输入图像。由于正向传播必须处理整个感受野,训练输入是非常大(通常是整个图像)。
    作者提出了一种更有效的训练方法,利用训练期间的特征共享。在Fast RCNN训练中,随机梯度下降(SGD)小批量计算被分级采样,首先随机取样N张图片,然后每张图片取样 R / N 个RoIs 。关键的是,来自相同图像的RoI在向前和向后传播中共享计算和内存。
    除了分层采样,Fast R-CNN使用一个精简的训练过程,一次微调中联合优化softmax分类器和bbox回归,而不是在三个独立的阶段训练softmax分类器,SVM和回归因子。看似一步,实际包含了:
    多任务损失(multi-task loss)、小批量取样(mini-batch sampling)、RoI pooling层的反向传播(backpropagation through RoI pooling layers)、SGD超参数(SGD hyperparameters)

    多任务损失

    第五阶段的特征输入到两个并行的全连层中(称为multi-task)。

    cls_score层用于分类,输出K+1维数组p,表示属于K类和背景的概率。
    bbox_prdict层用于调整候选区域位置,输出4*K维数组t,表示分别属于K类时,应该平移缩放的参数。也就是说对于每个类别都会训练一个单独的回归器。

    Fast RCNN有两个输出层:

    一个对每个RoI输出离散概率分布:

    一个输出bounding box回归的位移:

    k表示类别的索引,前两个参数是指相对于object proposal尺度不变的平移,后两个参数是指对数空间中相对于object proposal的高与宽。

    每个训练的RoI都被标记了ground-truth类别 u 以及ground-truth边界框回归 v 。在每个标记好的RoI上用multi-task loss 函数来级联的训练分类和bbox边界框回归:

    约定u=0为背景分类,那么[u≥1] 函数表示背景候选区域即负样本不参与回归损失,不需要对候选区域进行回归操作;
    第一项是对于 u 类的分类损失(log loss for true class u)。

    对于分类loss,是一个N+1路的softmax输出,其中的N是类别个数,1是背景。
    第二项是回归损失,是在 u 类的真正边界框回归目标的元组 v 上定义的,是一个 4xN 路输出的regressor,也就是说对于每个类别都会训练一个单独的regressor,评估回归损失代价就是比较真实分类 u 对应的预测平移缩放参数和真实平移缩放参数的差距:

    这里的损失不是L2损失函数,而是smooth L1损失函数,对于离群点不敏感,因为有L2损失的训练可能需要仔细调整学习率,以防止爆炸梯度(控制梯度的量级使得训练时不容易跑飞)。
    公式如下:

    超参数 λ 是用来控制两个损失函数的平衡的。作者对回归目标进行归一化使其具有零均值及单位权方差(zero mean and unit variance)。所有的函数都设置超参数 λ = 1。

    SGD超参数选择

    除了修改增加的层,原有的层参数已经通过预训练方式初始化:
    用于分类的全连接层以均值为0、标准差为0.01的高斯分布初始化;
    用于回归的全连接层以均值为0、标准差为0.001的高斯分布初始化,偏置都初始化为0;

    针对PASCAL VOC 2007和2012训练集,前30k次迭代全局学习率为0.001,每层权重学习率为1倍,偏置学习率为2倍,后10k次迭代全局学习率更新为0.0001;
    动量设置为0.9,权重衰减设置为0.0005。

    尺度不变性

    作者提出了使用两种方式对规模不变的对象进行检测:brute-force(单一尺度)和image pyramids(多尺度,图像金字塔)。

    单一尺度直接在训练和测试阶段将image预先固定好像素大小,直接输入网络训练就好,然后期望在训练过程中网络自己能够学习到尺度不变性scale-invariance;

    多尺度在训练阶段随机从图像金字塔**【缩放图片的scale得到,得到多尺度图片,相当于扩充数据集】**中采样训练,通过一个图像金字塔向网络提供一个近似的尺度不变,在测试阶段图像金字塔用来对每个object proposal近似尺度归一化,训练阶段每次采样一个图像就随机采样一个金字塔尺度。

    作者在5.2节对单一尺度和多尺度分别进行了实验,不管哪种方式下都定义图像短边像素为s,单一尺度下s=600【维持长宽比进行缩放】,长边限制为1000像素;多尺度s={480,576,688,864,1200}【维持长宽比进行缩放】,长边限制为2000像素,生成图像金字塔进行训练测试;实验结果表明AlexNet【S for small】、VGG_CNN_M_1024【M for medium】下单一尺度比多尺度mAP差1.2%~1.5%,但测试时间上却快不少,VGG-16【L for large】下仅单一尺度就达到了66.9%的mAP【由于GPU显存限制多尺度无法实现】,该实验证明了深度神经网络善于直接学习尺度不变形,对目标的scale不敏感。

    第2中方法的表现确实比1好,但是好的不算太多,大概是1个mAP左右,但是时间要慢不少,所以作者实际采用的是第一个策略,也就是single scale。

    Fast RCNN的检测

    一旦Fast R-CNN网络被微调,检测相当于运行正向传播(假设对象建议框object proposal是预先计算的)。
    网络将图像(或图像金字塔,编码为图像列表)和待给得分的 R 对象建议框(object proposal)列表作为输入。
    在测试阶段,R 大约为2K个,当使用图像金字塔的时候,每个RoI被指定尺度使得接近224*224。对于每个测试RoI r,网络输出关于 r 的一个后验概率分布 p 和一系列预测bbox偏移(每个类 [共k个类] 获得自己的精确bbox预测)
    然后使用估计概率

    给 r 赋予关于 k 个对象类的检测置信度。最后给每个类都实施一个非极大值抑制。

    截断SVD----减少检测时间

    图像分类任务中,用于卷积层计算的时间比用于全连接层计算的时间多;


    而在目标检测任务中,要处理的RoI数量比较多,几乎有一半的前向计算时间被用于全连接层(Fig . 2)。就Fast R-CNN而言,RoI池化层后的全连接层需要进行约2k次【每个RoI都要计算】,因此在Fast R-CNN中可以采用SVD分解加速全连接层计算;

    如何实现呢?
    1、物体分类和bbox回归都是通过全连接层实现的,假设全连接层输入数据为X,输出数据为Y,全连接层权值矩阵为W,尺寸为 u × v ,那么该层全连接计算为:
    Y = W × X
    2、若将W进行SVD分解(奇异值分解),并用前t个特征值近似代替,即:

    U是 u × t 的左奇异矩阵,Σt 是 t × t 的对角矩阵 ,V是 v × t 的右奇异矩阵。

    截断SVD将参数量由原来的 u × v 减少到 t × (u + v) ,当 t 远小于 min(u,v) 的时候降低了很大的计算量。
    在实现时,相当于把一个全连接层拆分为两个全连接层,第一个全连接层使用权值矩阵
    (不含偏置),
    第二个全连接层使用矩阵U(含偏置);
    当RoI的数量大时,这种简单的压缩方法有很好的加速。

    实验表明(Fig . 2),SVD分解全连接层能使mAP只下降0.3%的情况下提升30%的速度,同时该方法也不必再执行额外的微调操作。

    内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签: