目标检测(4)-Fast R-CNN

原文地址:https://zhuanlan.zhihu.com/p/27582096


RCNN通过卷积神经网络提取图像特征,第一次将目标检测引入了深度学习领域。SPPNet通过空间金字塔池化,避免了对于同一幅图片多次提取特征的时间花费。但是无论是RCNN还是SPPNet,其训练都是多阶段的。首先通过ImageNet预训练网络模型,然后通过检测数据集微调模型提取每个区域候选的特征,之后通过SVM分类每个区域候选的种类,最后通过区域回归,精细化每个区域的具体位置。为了避免多阶段训练,同时在单阶段训练中提升识别准确率,Fast RCNN提出了多任务目标函数,将SVM分类以及区域回归的部分纳入了卷积神经网络中。

论文链接:arxiv.org/pdf/1504.0808

源码链接:rbgirshick/fast-rcnn

RCNN链接:目标检测(2)-RCNN - 知乎专栏

SPPNet链接:目标检测(3)-SPPNet - 知乎专栏

网络结构


类似于RCNN,Fast RCNN首先通过Selective Search产生一系列的区域候选,然后通过通过CNN提取每个区域候选的特征,之后训练分类网络以及区域回归网络。对比SPPNet,我们可以看出Fast RCNN的区别所在,首先是将SPP换成了ROI Poling。ROI Poling可以看作是空间金字塔池化的简化版本,它通过将区域候选对应的卷积层特征还分为H*W个块,然后在每个块上进行最大池化就好了。每个块的划分也简单粗暴,直接使用卷积特征尺寸除块的数目就可以了。空间金字塔池化的特征是多尺寸的,而ROI Pooling是单一尺度的。而对于H*W的设定也是参照网络Pooling层的,例如对于VGG-19,网络全连接层输入是7*7*512,因此对应于我们的H,W就分别设置为7,7就可以了。另外一点不同在于网络的输出端,无论是SPPNet还是RCNN,CNN网络都是仅用于特征提取,因此输出端只有网络类别的概率。而Fast RCNN的网络输出是包含区域回归的。

  • 网络初始化

网络初始化当然还是经典的方法啦,首先更改网络的结构,将最后一层池化层替换为ROI Pooling层,然后设置ROI Pooling层的参数,也就是使得H,W匹配全连接层的输入要求。然后将网络的输出改为两个子网络,一个用以分类一个用于回归。最后更改网络的输入,网络的输入是图片集合以及ROI的集合。
  • 为什么SPPNet的误差不能够反向传播到池化层之前的卷积等层?

主要原因是SPPNet在训练时每个批次的样本是来自于不同的图像,而空间金字塔池化的感受野又特别的大,一般是整幅图片,因此无论是前向传播还是反向传播误差都要经过一整副图片,效率特别慢,也无法进行权重更新。而本文使用的方法是对于同一批次的图片,尽量选用来自同一幅图片的不同区域。比如每个批大小为128,其中64副来自同一幅图片。这样做的好处是相比于SPPNet,我们的训练速度大约能提高64倍。为什么以前这些网络都不这样干呢?如果做过深度学习的调参就能知道,如果一个批次里的图片都来自同一个类,网络的收敛速度会很慢。而作者发现,他们这样干,收敛速度也很快。我觉得一方面原因是因为BatchSize挺大的,本文将BatchSize设置为128,相当于我们将BatchSize设置为2啊。另一方面,同一幅图片的不同区域候选很可能来在不同的类别,比如网络示意图中的图片,包含了马、人、帽子等等。
  • 多任务损失函数

Fast RCNN将分类与回归做到了一个网络里面,因此损失函数必定是多任务的:



其中分类任务还是我们常用的对数损失, t^{u} 的定义方式与RCNN中一致,为中心区域坐标,以及区域宽度及高度。但是使用的损失函数不同,Fast RCNN使用的损失函数为鲁棒性的L1损失函数,而非RCNN中试用的L2损失函数,而且训练的过程也简单很多,需要注意的每个区域候选对于每个类都有区域回归训练。


  • Mini-Batch 采样

Mini-Batch的设置基本上与SPPNet是一致的,不同的在于128副图片中,仅来自于两幅图片。其中25%的样本为正样本,也就是IOU大于0.5的,其他样本为负样本,同样使用了困难负样本挖掘的方法,也就是负样本的IOU区间为[0.1,0.5),负样本的u=0, [u\geq 1] 函数为艾弗森指示函数,意思是如果是背景的话我们就不进行区域回归了。在训练的时候,每个区域候选都有一个正确的标签以及正确的位置作为监督信息。
  • ROI Pooling的反向传播

不同于SPPNet,我们的ROI Pooling是可以反向传播的,让我们考虑下正常的Pooling层是如何反向传播的,以Max Pooling为例,根据链式法则,对于最大位置的神经元偏导数为1,对于其他神经元偏导数为0。ROI Pooling 不用于常规Pooling,因为很多的区域建议的感受野可能是相同的或者是重叠的,因此在一个Batch_Size内,我们需要对于这些重叠的神经元偏导数进行求和,然后反向传播回去就好啦。
  • 多尺度训练

这一点和SPPNet都是相同的,主要是对图片进行放缩,使得短边在一个区间内,然后对于每一个ROI,找到使其对应的原始图像面积接近224*224个像素的尺寸。
  • 那些层是需要学习的?

由于我们使用了更深的网络VGG16,因此作者觉得仅仅是微调最后的全连接层是不够的,因此尝试去微调其他的网络层,并进行了对比试验。发现,卷积层2_1之前一般是通用任务相关的,不需要再去学习了,而学习卷积层2_1之后的其他网络层显得至关重要,将识别准确率从61.4提高到了67.2。

  • SVM与SoftMax的比较

此前在RCNN中,我们了解到了不能够使用CNN中的样本定义方式去训练SVM,是因为两个分类器对于样本的需求是不同的。因此直接使用Fast RCNN的训练样本去训练SVM也是不公平的,因此作者通过RCNN中SVM的训练方式和参数设计对比SVM和SoftMax的结果,发现softMax结果优于SVM 0.1-0.8,也就是说将分类及回归放到一个网络中去做,并没有影响到网络的精度。
  • 识别结果对比

首先是速度上的优势,相比于SPPNet,Fast RCNN训练速度快3倍,测试速度快10倍,精度更高。相比于RCNN,Fast RCNN训练速度快9倍,测试速度快213倍。




在速度提高的同时,精度也是不俗的表现哦,可以看到Fast RCNN在VOC 2007库上取得了68.1的MAP,相比于SPPNet的66.0提高2.1%。

  • 存在的不足

现在的Fast RCNN模型已经接近完美了,识别检测全部放到了卷积神经网络的框架里面,速度也是相当的快。美中不足的是,区域建议网络还是Selective Search,网络其他部分都能在GPU中运行,而这部分需要在CPU中运行,有点拖后腿啊。接下来的Faster RCNN已经弥补了这个问题,下期见咯~



猜你喜欢

转载自blog.csdn.net/u010417185/article/details/79718030