在之前的博文中,表达一个想法,就是能不能不要Cell?这个问题其实很难回答。基于滑窗的检测方法卷积化获得速度上的提升,个人认为,这里是关键。

R-CNN中,不要Cell,在获取更高精度的同时,却失去了速度优势。虽然Andrew Ng个人认为YOLO等才是更有发展前景的检测模型,但是从品味上,我个人更欣赏R-CNN系列工作,当然总是希望每个路子的模型都能在速度和精度上达到某种平衡,至于如何平衡,反正不是速度最快且精度最高。

R-CNN的出发点是没毛病的,滑窗存在冗余检测,要去掉冗余,选择的方法是Selective Search,博客中简写为SS且不做关于SS的任何技术上的讨论。虽然去掉了冗余,但是SS引入的时间成本是很高的。这里其实引入了一个很大的问题,如果把SS的时间成本减少,又去掉了冗余,这个事情做得才算干净。

先不谈SS的时间成本问题,围绕去除冗余之后的想法讨论。

这里引入一个概念,叫做Region Proposal,博客中简写为RP。RP就是SS提取的物体,这个物体很特别,不知道物体的具体类别和精确位置,只知道是个物体,且只有轮廓(位置不精确)。讲到这里,很容易得出SS可以做语义分割。要实现检测的目的,接下来做的事情就是确定该物体类别和物体精确位置,也就是需要一个分类器和一个回归器。

问题来了,沿着RP的路子,如何训练一个分类器和回归器?

R-CNN使用SVM作为分类器,使用了一个fine-tune的CNN架构做特征提取器,提取每个RP的特征,OK,这里只剩下标签的问题了。R-CNN将SVM用于二分类,每个类别一个SVM模型,也就是说,训练样本需要针对每类的二类样本,标签为是或者不是该类。因为分类的对象是RP,所以只需要针对每类,确定RP是正或者负。

首先解决RP是正的问题。对每一个RP,选择和该RP的IoU最大且值大于0.5的ground truth对应的类标签作为该RP的标签。因为SS的分割结果,实际上是ground truth的一个近似,IoU最大表明距离最近,能够表明实例对应关系,自然类别对应。IoU的值范围是一个限制条件,防止出现比较离谱的分割结果,划定了这种度量的可信范围。

不满足上述条件的是背景。

经过上述一波比对,得到的是SS之后每个RP的类标签。这样,训练针对每个类别的SVM的正标签有了。其实,这个时候可以构造负标签了,就用其他类的RP作为负标签。

没毛病。但是不妨看一下R-CNN中的负标签具体构造方法。对每一个RP,如何和当前类对应的ground truth的IoU的值小于0.3,认为是针对当前类的负样本。考虑一下正标签,>0.5是正,<0.5是负,首先这里肯定包含背景类;第二,也包含其他类;所以,结果和上文中讨论的一样。不过通过0.3这个值可以控制正负样本的比例和负例的程度(概念比较模糊)。

回顾一下,针对每个类别的RP,有了CNN提取的特征,构建了正负类,选择了模型SVM,可以训了。分类搞定了。

位置的问题需要通过回归的方式解决。回归的标签是什么?当然是和该RP对应的实例的ground truth了,RP和距离最近实例有近似关系。可能还需要一种能够合理控制样本个数的机制,不妨看R-CNN是如何做的,只选那些和实例的IoU大于0.6的RP作为训练样本。显然阈值越高,RP越接近实例,样本质量越高,样本数越少。当阈值为0.5的时候,使用所有RP。实际上,在R-CNN中的回归过程中,学习的是RP到ground truth的水平位移和尺度变换。希望学习什么东西,需要对应的标签构造方式,本质上,一个数学等式的恒等变换,但是从几何意义上来讲,是不同的。

回归的事情搞定了。

跳出来看一看,ground truth到底在分类和回归过程中的角色是什么?用IoU作为距离度量方式,给RP打标签。分类中,直接用ground truth的类别标签作为RP的类别标签;回归中,直接用ground truth的位置标签作为RP的位置标签。

对于YOLO,其实每个Cell的作用等同于RP,只不过YOLO是固定RP数目,这个数目不依赖于真实图片中有多少物体,所以存在冗余。这个Cell对应的标签也是来自于ground truth,Cell和实例建立映射的关系是实例的midpoint是否在Cell中。

总之,个人认为,理解R-CNN的关键点之一在于如何给RP打标签,构造分类和回归的训练数据。

参考:强推一篇博客,DL讲原理的文章写成这样就很棒。