R-CNN学习笔记
1.总体框架
R-CNN目标检测模型总体上分为三大模块:1.区域提议,2.CNN特征提取,3.SVM判别。
- 区域提议:也可以理解为候选框提取。通过某种方法从原始输入图像中提取出与类别无关的大约2k个候选框。
- CNN特征提取:经过第1步提取到2k个候选框之后,分别利用CNN对这些候选框进行特征提取。
- SVM判别,利用第2步提取到的特征,分别对每种类别训练一个SVM二分类器,判断输入是为该类目标。其中背景也算作一类。
2.详细介绍
2.1. selective search区域提议
区域提议通过selective search方法,从输入图像中提取出与类别无关的大约2k个候选框。 selective search方法大概可以解释为:先初始化一堆小的区域,然后根据小区域的像素、色彩、纹理等特征的相似性进行区域合并,并循环逐渐合并成大的区域,直到最后合并为完整的原始输入(类似于哈夫曼树的构造过程),将出现过的区域作为目标检测的候选框。这种根据区域特征相似性来获取候选框的方法,要优于使用滑动窗口的暴力方法。
2.2. 微调预训练的CNN进行特征提取
使用CNN对2k个候选框进行特征提取。由于数据集的大小经常有限,而且由头到尾训练一个复杂的CNN模型也需耗费很多的时间,因此R-CNN使用预训练的CNN网络(如Alexnet)进行微调(fine-tuning)。最终,每个候选框提取出维度相同的向量(4096维)。
如何训练?将Alexnet最后一个全连接层的1000维输出,换成自己数据集目标类别数+1(N+1)维,“+1”是将背景也考虑成一个类别。疑问:训练的时候,是不是卷积层的参数的都冻结了,而只修改全连接层的参数?
哪个作为提取到的特征?应该是倒数第二层全连接层的那4096个输出?不太确定。
训练数据的选取?正样本:所有与ground-truth box(就是手工标记的那个目标框)的交并比(IoU)>= 0.5的候选框。负样本:正样本之外的为负样本。在每次SGD迭代中,一个batch的大小为128,其中有32个正样本和96个负样本。之所以这么采样,是因为正样本比较少。
2.3. SVM判别
经过CNN,每个候选框都提取到长度为4096的特征。然后对于每一个目标检测类别,单独训练一个SVM二分类器,判读输入的特征所代表的候选框是否属于该类别的可能性是多少。然后将可能性高于某个阈值的的候选框视为真,其他的候选框视为假,并且抛弃掉。
训练数据的选取?正样本:直接是 ground-truth box(实际上就是要求IoU=1)。负样本:所有与ground-truth box交并比< 0.3的候选框。(注意:训练CNN和训练SVM的数据集选取方式是不同的)
2.4. NMS(non-maximum suppression)
经过第3步SVM判别之后,可能会出现一些判定为真的候选框堆叠、交织在一起,这种现象可能是:若干个候选框都分别包括了检测目标的一部分,或者两个判定为真的候选框其中一个包含在另一个之中。所以很多已经判定为真的候选框其实是多余的,因此需要通过某种方法去除掉这些候选框。这种方法就是NMS,它是一种贪心的做法(以下讨论的候选框都是已经判定为真的):对于两个IoU大于某个阈值的候选框,去除掉可能性小的一个候选框而保留可能性大的候选框,以此循环迭代,直到不能再去除候选框。
2.5. 边框回归
经过第4步NMS之后,我们已经筛选出相对比较好的候选框,但是这些这些候选框其实大多数都不太精确,因为回想一下这些候选框最初是怎么提取出来的?是用selective search方法通过特征相似性来合并小区域得来的,而且是无关类别。而某一类别一般都有相对固定的形状或者长宽比例,因此,为了进一步得到更加精确的边框(对候选边框进行调优),需要进行边框回顾,学习某一特定类别的边框属性。
做法就是:每个类别都分别训练一个线性回归模型,该模型的输入(P,G),P =(Px,Py,Pw,Ph),G =(Px,Py,Pw,Ph)。P代表着候选框,(Px,Py)是候选框的中心位置,Pw、Ph分别是候选框的宽和高。而G则是ground-truth box(即目标框)。(后面没看懂,待定……)
3.细节问题
3.1. CNN特征提取和SVM分类的数据集选择问题?
训练CNN时,正样本:所有与ground-truth box(就是手工标记的那个目标框)的交并比(IoU)>= 0.5的候选框。负样本:正样本之外的为负样本。
训练SVM时,正样本:ground-truth box(实际上就是要求IoU=1)。负样本:所有与ground-truth box交并比< 0.3的候选框。
可以看得出CNN的训练集要比SVM训练集大,为什么要这样选择?因为CNN容易过拟合,所以必须要多一点数据来训练,以防止过拟合。而SVM适用于小数据集,而且这个小数据集显然更加精准,因为IoU设置得更加严格。
3.2. 为何不直接CNN进行特征提取+分类?而要拆成CNN特征提取+SVM分类?
因为再单独训练一个SVM用于分类,要比直接使用CNN的softmax分类的效果要好,有两个原因造成的。
(1)在微调CNN时,为了防止过拟合,需要比较多的训练数据,因此对于训练数据的IoU设置得比较松,从而得到比较多的训练数据,但这样的代价是:训练数据的精确度降低了,就比如原本IoU=1时才算作正样本,现在IoU=0.5都算的话,就意味着框住0.5个检测目标也当成正样本,这就显然降低了训练数据的质量。所以为了分类的精确度,就需要保证训练数据的质量,因此单独将分类问题拿出来,交由SVM解决。
(2)分类问题单独拿出来时,因为训练时是每个类别对应一个SVM分类器,因为在挑选负样本时,除了能够选到背景之外,还能够选到其他类别的目标,因此能够增强分类器的识别能力。若使用CNN的softmax作为分类,因训练数据的负样本选择的是背景,所以识别能力相对弱了一点。