R-CNN三部曲(二):空间金字塔池化与Fast R-CNN

SPPNet、Fast R-CNN是R-CNN的改进版本,这里我不打算单独介绍他们,而是注重介绍他们的改进方法。

首先来回顾一下R-CNN有哪些缺点,第一,我们在用CNN对图像进行处理之前,需要处理图像使得他们保持同样的尺寸,一般可以选择扭曲图像或者直接裁剪,不论怎么做都有可能造成图像信息的丢失。

第二,R-CNN需要对每个候选框进行一次CNN计算,计算之后还需要用SVM验证。

第三,模型包含多个阶段的训练,一个是对CNN的fine tuning,一个是SVM,一个是边界框回归器。

针对R-CNN的第一个缺点,回想一下,为什么CNN需要固定尺寸的输入呢,实质上不是CNN需要固定尺寸的输入,因为卷积运算和池化运算都是可以针对任意尺寸的输入得到相应输出的,但最后做分类的时候,我们用到了MLP,这就需要输入的尺寸统一了。

针对这个问题的解决方法就是空间金字塔池化,它是一种池化方法,主要实现了针对不同尺寸的输入,也能得到固定的输出,具体是怎么实现的呢,首先我们回想一下传统的池化过程,比如最大池化,就是用一个比如33的框,遍历整个特征图,计算每个区域的最大值,而空间金字塔池化,它则是把整个特征图分成33,一共九个部分,计算每个部分的最大值,这样,不论输入尺寸多大,都能得到同样尺寸的输出了。

R-CNN三部曲(二):空间金字塔池化与Fast R-CNN
上图也可以更清晰地反映出空间金字塔池化的思想,一般来说,我们会对特征图进行多个划分,比如11、22、4*4,这样就可以计算出21个特征值,如果想要更多的特征值,就进行更多的划分。

空间金字塔池化会对一个输入进行不同尺度的池化,而ROI(region of interest)池化,本质上就是空间金字塔池化的简化版本,只进行单一尺度的池化(比如只使用2*2划分)。实验证明,其实多个尺度的池化带来的模型效果的提升并不显著,所以目前更多偏向于使用ROI池化。

针对R-CNN的第二个缺点,其实我们只需要改一下计算顺序就能解决了,也就是说,先对输入图像计算CNN得到特征图(feature map),再根据region proposals挑选出特征图对应的部分,因为特征图比原输入尺寸变小了,所以要注意region proposals坐标也要进行相应的缩放,之后,再利用前面的ROI池化层,把提取出来的局部特征图进行池化处理统一尺寸,最后再进行分类和边界框回归。

针对R-CNN的第三个缺点,也就是模型包含多阶段训练,多阶段训练最大的缺点就是特征复用,原来R-CNN中,最后我们用CNN的feature map做完分类又做边界框回归,这就叫特征复用,而在fast r-cnn中则提出,直接用一个mlp对feature map进行处理,在mlp中再分为两个分支进行分类和边界框回归:

R-CNN三部曲(二):空间金字塔池化与Fast R-CNN
上图可以更清晰地反映出,ROI池化层后接多层神经网络,神经网路中途分成两个分支,一部分通过softmax处理计算分类结果,另一部分进行边界框回归,所以模型的损失函数是一个多任务损失函数(multi-task loss):

L(p,u,tu,v)=Lcls(p,u)+λ[u1]Lloc(tu,v)L(p,u,t^u,v)=L_{cls}(p,u) + \lambda[u \leq 1] L_{loc}(t^u,v)

说到底不论是分类还是边界框回归,得到的结果也是几个数值(分类得分加上边界框回归值),所以像这样把两个问题的结果融合到一个模型中进行训练也是确实可行的。

上面提到的所有内容,就构成了Fast R-CNN。

在github写的自然语言处理入门教程,持续更新:NLPBeginner

在github写的机器学习入门教程,持续更新:MachineLearningModels

想浏览更多关于数学、机器学习、深度学习的内容,可浏览本人博客