Fast R-CNN

Fast R-CNN为了解决R-CNN和SPP-net的多步骤训练、耗时及存储问题,提出了一步训练过程,使用多任务损失函数,能更新所有网络层参数,并且不需存储特征。其通过RoI pooling层将RoIs映射为固定长度特征向量,进行分类和bounding box regression。训练时采用小batch采样策略,提升了训练效率和检测性能。
摘要由CSDN通过智能技术生成

    看这篇论文之前需要先对R-CNN和SPP-net有所了解,可以参考博客R-CNN:Rich feature hierarchies for accurate object detection and semantic segmentation 以及博客SPP-net:Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition 了解相关知识,这对阅读和理解Fast R-CNN有极大的好处。另外值得一提的是,Fast R-CNN的文献版本有多个,建议阅读发布在ICCV会议上的版本,相对更仔细一点也更容易理解一点。
    首先谈为什么有了R-CNN和SPP-net,作者又新提出了Fast R-CNN,原因很简单,那一定是R-CNN和SPP-net有一些缺点和不足的地方有待改进。那么我们就先从这个方面入手,看看R-CNN和SPP-net都有哪些缺点。
    R-CNN的不足之处:
    [1]训练过程是一个多步骤的过程(multi-stage pipline),正如前面博客所讲,R-CNN的训练过程主要有以下三个阶段: 分别是有监督的预训练、针对特定的图片进行调优(fine tune)以及训练一个线性的SVM分类器,对warped voc windows进行分类。 事实上后面还有一个bounding box regression的步骤用来精确目标所在的位置。我们肯定希望训练通过一个步骤就可以完成。
    [2]训练过程耗费时间和存储资源,在R-CNN中,每张图片要提取2k个proposals,每个proposal都要通过网络进行前向传播并提取特征并存到磁盘中供svm分类器的训练使用中,这导致无论是训练时间还是所占用的磁盘容量都是非常大的。
    [3]测试阶段或者说检测阶段的速度也是非常慢的,原因同上,在测试阶段一个图片要提取2k个proposals并分别送入网络和svm分类器以及bounding box regression,这是非常耗时的。
    SPP-net的不足之处:
    [1]训练过程是一个多步骤的过程。
    [2]训练过程耗费时间和存储资源。
    [3]在网络的调优(fine tune)阶段,只能给更新SPP layer之后的层(主要都是一些全连接层),前面的卷积层参数无法得到更新。这对于VGG等大型网络而言,这样的调优限制会使得网络无法达到它最好的性能。
    为了有个对比,先看看Fast R-CNN有哪些优点吧。
    [1]更高的mAP(mean average precision),这是衡量一个检测算法好坏的最直接的标准。
    [2]使用了多任务的损失函数(分类的损失函数和定位的损失函数),训练是一个一步完成的过程,这就和R-CNN以及SPP-net有明显区别了。
    [3]训练的时候可以更新所有网络层的参数,这和SPP-net的不足也形成了对比。
    [4]没有使用磁盘存储空间来存储特征。因为整个训练过程是一步完成的,所以特征只要存在显存或内存中即可。而不用像R-CNN和SPP-net一样特征存储到磁盘中,然后SVM分类器再从磁盘读取这些特征进行训练。
    接下来看一下Fast R-CNN的结构如下图所示:
这里写图片描述
    整体的流程如下:首先一个输入的图片经过多个卷积层和最大池化层形成在最后一层卷积层后面的feature maps,然后由于知道proposals在图片的位置是知道的,所以可以推算出proposals在feature maps中的位置,这些对应在feature map中的映射我们称之为RoI,然后对于每一个RoI,使用RoI pooling的策略将其映射成固定长度的特征向量,之后特征向量经过数个全连接层后得到全连接层的输出,全连接层的输出被输入到两个“兄弟层”(sibling layer),这两个层分别输出proposal的类别和bounding box的偏移量。RoI pooling的策略是通过RoI pooling layer实现的,这个layer其实是SPP layer的简化版本,读者可以查看SPP-net的那篇博客了解SPP是啥。
    以上便是Fast R-CNN网络的整体流程了。下面将如何训练这些网络的。
    [1]用在ImageNet上训练过的用作分类的网络参数初始化这里Fast R-CNN的网络参数,但是有三点是有所改变的。第一是最后一个卷积层后面的最大池化层变为了RoI pooling层,第二是网络的全连接层和最后用作1000类分类的softmax层被这里的“兄弟层”替换了,第三是网络的输入从一张图片变为了一张图片和这张图片中的RoIs了(或者称为proposals,因为前面约定feature maps中的才叫RoI)。
    [2]在新的训练集上调优(比如Pascal VOC)。前面在讲SPP-net的缺点的时候提到过SPP-net“在网络的调优(fine tune)阶段,只能给更新SPP layer之后的层(主要都是一些全连接层),前面的卷积层参数无法得到更新。这对于VGG等大型网络而言,这样的调优限制会使得网络无法达到它最好的性能。“针对此,文章解释了SPP-net不能调优SPP layer之前的参数的根本原因是由于R-CNN和SPP-net在训练过程中,RoI来自于各个不同的图片,而RoI的感受野又非常大,往往是覆盖了整个图片的,所以对于一个RoI的训练,就要去更新几乎涉及整个图片的网络参数,这无疑是非常耗计算资源的,所以导致很难训练SPP layer之前的参数。针对SPP-net的这个缺点,作者提出了一种更为高效的训练方法,在Fast R-CNN的调优训练中,每进行一次随机梯度下降法(SGD),采用一个小的batch,这个batch是有层次的筛选的,首先选出N张图片,然后对每张图片选出R/N个RoIs,R是一次SGD要采用的RoIs的数量。典型的,采用N=2,R=128。这样一来,128个RoI其实就来自于2张图片,每张图片的卷积参数是相同的,也就是说64个RoI共享了卷积参数,这样就达到了加快训练速度的目的了。这点相当于前文谈到的Fast R-CNN的优点[3],Fast R-CNN另外一个优点[2]表明它的fine tune过程是一气呵成的,这个fine tune的过程包括了以下几个重要的部分,分别是定义多任务的损失函数、小batch采样的策略、经过RoI pooling layer进行反向传播以及SGD的超参数选择,下面将分别讲解。
    [2.1]多任务损失函数
    首先看网络最后输出的是什么,之前提到,网络有两个“兄弟层”,一个层用于分类,以Pascal的20类为例,这层输出21个概率,分别表示一个RoI是背景或者是属于这20类中某一类的概率,记为这里写图片描述,此处K等于20。另一个”兄弟层”是用来做bounding box regression的,也就是说对于一个RoI,输出对于将其预测为每一个类别的对应的回归参数tk。具体这里的回归参数tk以及后面的v是什么含义,论文中说的是在R-CNN的论文中可以找到,而在R-CNN的论文中说的是在补充材料中,最后还是没找到,目前见到有这个博客提及这个回归参数,但讲的不细,仅供参考。
这里写图片描述
    对于每一个RoI,都带有一个真值的类别标签u和一个真值的回归参数v,使用的多任务的损失函数如下:
这里写图片描述
其中
这里写图片描述
这里写图片描述这里写图片描述
    [2.2]小batch(mini-batch)采样策略。在SGD的每一次迭代训练中,随机抽取两张图片,每张选取64个RoI,构成了一个mini-batch。在这个batch中,25%的RoI对应的proposals和真正包含了物体的矩形有着至少50%的交并比(IoU),这些物体的类别标签(class label)是在K个类别之中的。剩余75%的RoIs则最多和真正包含了物体的矩形的IoU不会超过一个阈值,这个阈值是可以人为在[0.1,0.5)之间选定的,因为不同的阈值可能导致不同的检测精度的,需要实验才能确定最优的参数。他们的类别标签(class label)都被设为0。在训练的时候还以50%的概率对样本进行水平翻转(horizontally flip)来增加样本的数量,这种行为也叫做数据增广(data augmentation)。
    [2.3]为了描述的简洁性,令每次训练只采样一张图片,即N=1。令x_i是输入到RoI pooling layer的第i个输入,y_rj表示第r个RoI的第j个输出。RoI pooling layer计算这个y_rj的方式是令这里写图片描述,其中这里写图片描述,其中R(i,j)每个RoI窗口的子窗口的索引。损失函数对x_i的偏导数求取方式如下:
这里写图片描述
    [2.4]SGD的超参数选择用于分类和回归的的全连接层分别以0均值,标准差为0,01和0均值、标准差为0.001的高斯分布初始化。偏置都设为0,全局学习率为0.001,对于每一层的权重是在全局学习率上乘以2,而对于偏置项乘以1。训练VOC2007和VOC2012的时候,跑了30k次的SGD,每次输入一个mini-batch的数据,然后把学习率降到0.0001运行10k次SGD。momentum设为0.9,decay设为0.0005。
    [3]为了实现尺度不变性,采用了两种不同的方法,一种是暴力法(brute force),一种是使用图像金字塔(image pyramids)。暴力法直接将image设置为某种scale,直接输入网络训练,期望网络自己适应这个scale。而图像金字塔法在训练的时候随机采取不同尺度的图像进行训练,而在测试的时候将图像的RoI缩放到面积最接近于224*224的尺度上进行输入。
    后面,作者还对全连接层的参数进行了SVD分解,目的是加速测试的时间。因为在检测任务中时间很多是花费在全连接层的传播过程,因此对其进行SVD分解可以帮助提高检测速度。再后面就是Fast R-CNN在一些公开测试集上取得的一些测试结果了,在当时都是state of art的,随后作者还对网络的结构和调参进行了一些深入的讨论,建议读者去阅读论文,这篇博客只是一个简单的介绍和自己的阅读记录。

公平的席位分配惯例法(Fair Seat Allocation Tradition,简称FSAT)是一种用于解决席位分配问题的算法,可以用来公平地分配固定数量的席位给多个参与者。以下是一个使用MATLAB实现FSAT算法的示例代码: ```matlab % 输入参数:num_seats表示席位数量,num_participants表示参与者数量 % 返回值:seat_allocation表示每个参与者分配到的席位号 function seat_allocation = fsat(num_seats, num_participants) % 初始化每个参与者的优先级矩阵 priority_matrix = zeros(num_participants, num_seats); for i = 1:num_participants for j = 1:num_seats priority_matrix(i,j) = rand(); % 随机生成优先级 end end % 对每个参与者的优先级矩阵进行排序 for i = 1:num_participants [~, idx] = sort(priority_matrix(i,:), 'descend'); priority_matrix(i,:) = idx; end % 分配席位 seat_allocation = zeros(1, num_participants); for i = 1:num_seats for j = 1:num_participants if seat_allocation(j) == 0 && ~isempty(find(priority_matrix(j,:) == i, 1)) seat_allocation(j) = i; break; end end end end ``` 该函数首先生成一个随机的优先级矩阵,然后对每个参与者的优先级矩阵进行排序。接下来,它按顺序分配席位,对于每个席位,依次遍历参与者,如果该参与者在当前席位的优先级矩阵中排名第一并且尚未分配到席位,则将该席位分配给该参与者。 需要注意的是,由于该算法涉及随机数生成,因此每次运行的结果可能会不同。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值