目标检测(Object Detection)2--Fast R-CNN

RCNN的问题

在上一篇文章中,我介绍了经典的RCNN算法,虽然经典,但是不可避免的存在一些问题,主要有3点:
1.使用Selective Search提取候选区域的质量有所欠缺,同时计算量大
2.一张图片形成的多个候选区域,每一个都要单独过一次CNN去获得特征向量,但是实际上很多候选区域存在overlap,因此很多计算是重复的。
3.整个过程包括regional proposal,CNN特征提取,SVM分类多个模块,每个模块都是单独训练,很难进行系统性的优化,无法实现端到端的训练。

Fast R-CNN

对于RCNN存在的问题,Fast RCNN主要解决了2和3,那么具体来说它是怎样解决的呢?我们来具体地看一看。首先,我还是先上图,让大家有一个直观的印象。下图直接取自RBG大神的原论文 Fast R-CNN
在这里插入图片描述
概括一下,其结构可以分为两部分,
1.和RCNN相同,使用SS算法从每张图片中生成多个候选区域。
2.将整张图片作为input放到网络中得到对应的特征图,然后将上面SS算法得到的候选区域投影到特征图上获得对应的特征矩阵。通过这个思路,成功的减少神经网络的运行次数。然后将每个候选区域对应的特征矩阵通过一个叫ROI pooling的池化层缩放到7*7大小的特征图,再展开得到特征向量,接着用这个特征向量分别作分类bbox 回归。通过这个操作,我们成功将分类和回归任务放到一个网络中去进行。
在这里插入图片描述
OK,我们开始具体的说明。

一次性计算整张图特征

这是Fast RCNN相较于RCNN的第一个重要改变,通过这个操作,我们就无需对于每个候选区域分别去过CNN网络,而是通过对整张图的一次特征提取,然后根据候选区域在整张图上的位置去整张图特征的对应位置提取候选区域的特征,避免了一系列的冗余计算,大大提高运算效率。

ROI pooling

ROI(Region of Interests) 的意义在于,因为我们在前面根据映射关系从整张图特征提取候选区域的对应特征时,并没有候选区域的大小,也就是说我们的对应特征矩阵的大小都是不同的,那么这样是无法放到后面的全联接层用于分类或回归的。这里ROI的作用就是不管进来的特征矩阵的shape,都将其等分成77的部分,然后使用池化的思想,使用max pooling,对每一部分都取最大的那一个值,合并形成一个固定的77矩阵。
在这里插入图片描述
通过这个方式,就能保证每个候选区域特征矩阵的尺寸一致了。

接下来,通过对生成的特征矩阵进行flattening操作,展平拉成一个向量,就可以用于后续的分类或回归了。

分类器

不同于RCNN,这里我们不再使用SVM作为分类器,而是直接使用CNN作为多元分类器,借助softmax函数,生成一个(N+1)维的概率输出,其中N代表物体类别数目,1代表背景。每一维对应着当前候选区域属于对应维物体类别的概率。

边界框回归器

这里需要重点解释一下。对应每一个候选区域,我们经过这个回归器的输出维度是(N+1)*4,这里该如何理解呢?就是说,对应每一个可能类别(总共N+1),我们都输出一个边界框对应的调整参数(dx,dy,dw,dh)。如下图
在这里插入图片描述
那么我们具体是如何从我们的候选区域框通过这个回归函数映射到我们的预测框呢?我们通过下面这张图来看一下
在这里插入图片描述
这张图中的黄色框就是我们的初始候选框,而红色框就是根据我们的回归参数调整之后的预测框,而绿色框就是我们的真实物体框(手动标注)。

损失函数

这里我们需要同时考虑上面的分类器以及回归器的损失,因此最终的损失计算是两者之和(multi-task loss)。具体的公式如下:
在这里插入图片描述
这里我直接从原文中拷贝下来,总的损失也就是公式的左边项,等于分类器的损失 L_cls(p,u)和 回归器的损失L_loc(tu,v),中间的lambda是一个超参数,用来控制两个任务的平衡,而 [u>=1]叫做艾弗森括号,本质上就是一个indicator function,当u>=1时取1,其他情况取0。

OK,我们先来看一下第一项,分类器的损失,这里原文中作者使用的是交叉熵函数,相信了解机器学习尤其是分类任务的朋友对这个损失函数肯定不陌生。这里我大概解释一下,希望对于那些对交叉熵不了解的朋友有帮助。首先,当我们面对一个多元分类问题的时候,我们的softmax的产出是一个N维的向量p,其中每一个维度对应一个物体类别,值就是分类器给出的物体属于这个类别的概率,总和为1(softmax 保证这一点)。那么我们再思考一下,真实的u应该是怎么样的呢?自然是一个one-hot encoding,类似这种[0,0,1,0,0,…], 只有真实的那个类别标1,其余均为0。那么我们如何去衡量两者之间的‘距离’呢?交叉熵就出来了,具体的公式如下:
在这里插入图片描述
因为时间原因没有找到和我上面解释标注一样的公式,就用上面这个凑合用一下了,图中的o就是我解释中的p,oi就是第i维。
在原文中作者直接给出的损失是
在这里插入图片描述
也就是只取了真实标签那一维的p(pu), 其实非常好理解,因为求和项的其他均为0([0,0,1,0,0,…]),因此最后只剩下真实标签1对应的pu这一项(1*logpu)。
上面我解释完了分类器的损失,下面我们来看一下回归器的部分。
先上原文图片
在这里插入图片描述
在计算回归损失的时候,作者用到的损失函数叫做smoothL1,总的是由x,y,w,h四个部分的损失求和得到的。这里再讲一下前面的艾弗森括号,上面我已经解释了它的含义,那么为什么需要添加这一项呢?因为我们需要明确的一点是我们回归的目的是去调整我们候选框接近我们的真实框,但是一个前提是对于这个类别而言,它必须是一个正样本,也就是说首先我们确定候选框是某个物体类别的一个正样本,然后再在次基础上去对它进行位置的微调。
OK,以上就是完整的损失函数以及Fast R-CNN的全部内容了,通过Fast R-CNN,成功解决了开篇提到的R-CNN的两个问题。但是尽管如此,Fast R-CNN依然使用了Selective search算法来提取候选框,这个算法依然非常低效,也就是意味着Fast R-CNN依然有提升空间,在下一篇文章中,我会介绍它的升级版Faster R-CNN以及它是如何将SS融入到CNN中的。

参考:Fast RCNN https://arxiv.org/pdf/1504.08083.pdf
https://www.bilibili.com/video/BV1af4y1m7iL?p=2

猜你喜欢

转载自blog.csdn.net/weixin_44607838/article/details/109453919