Faster R-CNN论文阅读笔记
Faster R-CNN简述
基于卷积神经网络(Convolutional Neural Networks, CNN)的目标检测方法可以分为单一阶段(One-Stage)方法和两阶段(Two-Stage)方法。Two-Stage的方法分为两个步骤:第一步,得到一组图像 I I I上的候选区域(Region of Interest, RoI),每个RoI对应图像 I I I上的一个子区域,这一步通常称为Region Proposal;第二步,对这组RoI逐个进行分类和回归,其中分类用于判断每个RoI中的物体属于哪个类别,回归用于更精准地得到描述物体的方框(Bounding Box, BBox)。
R-CNN系列的方法是Two-Stage方法中的一个代表性的分支。在Faster R-CNN提出以前,有R-CNN和Fast R-CNN两个更早的模型。
最初的R-CNN模型由Ross Girshick等人于2013年提出,该模型在Region Proposal的阶段采用当时非常流行的选择性搜索(Selective Search)方法得到一组候选区域,第二阶段基于这些候选区域(所以称为Region-based CNN,即R-CNN)利用CNN进行计算得到特征映射(Feature Map),再在特征映射的基础上训练支持向量机进行分类。通常CNN模型的最后是全连接层,由于全连接层要求输入是固定的长度,因此整个CNN模型的输入尺寸也需要是固定的。但通过Selective Search得到的这组候选区域的大小、形状均不相同,无法直接作为CNN的输入。R-CNN模型对于这个问题的解决方式是将所有候选区域通过裁减或缩放的方式转化到相同的大小,再输入CNN中。
图1 R-CNN计算过程
Fast R-CNN由于引入了RoI Pooling的思想,使得特征得以共享,大大提升了网络的性能,但其Region Proposal阶段仍使用选择性搜索方式。
Faster R-CNN中的Region Proposal
Fast R-CNN模型的瓶颈在于Region Proposal阶段。由于使用Selective Search方法本身耗时巨大,且无法实现整个训练过程的端到端,无论是训练还是预测,Region Proposal阶段都严重影响了Fast R-CNN模型的效率。Faster R-CNN最重要的工作就是使用Region Proposal Networks(RPN)代替Selective Search方法完成了Region Proposal,大大提升效率,同时也提高了模型的精度。
RPN是一个较小的卷积神经网络,只有卷积层,对于任意尺寸的图像输入,其输出一组矩形候选区域以及每个候选区域的一个物体得分(Objectness Score),Objectness Score用于描述模型对候选区域内存在物体的确信程度。和Fast R-CNN一样,Faster R-CNN也使用预训练的卷积神经网络(ZF-Net、VGG-16等)对原始输入图像进行特征提取,得到一个Feature Map。RPN就是以这个Feature Map为输入得到图像的一组候选区域的。
具体地,从RPN要实现的功能来讲,它首先在预训练网络从原图上提取的Feature Map上以 n × n n \times n n×n大小的窗口进行滑动,每次滑动后把窗口范围内的 n × n × C n \times n \times C n×n×C( C C C为预训练网络提取的Feature Map的通道数)的特征映射作为RPN网络的输入,将其映射成一个更低的维度的特征(相当于一个精简特征的过程),然后连接两个并行的全连接层,一个用于分类,一个用于回归。在论文中,作者给出一个滑窗尺寸的选择是 n = 3 n = 3 n=3,而对于经过RPN后得到的精简特征的维数,在ZF-Net中是256维,在VGG-16中是512维,这个维度是跟这两个预训练网络提取得到的Feature Map的通道数 C C C一致的。这里对论文中的几处作解释:
We use n = 3 n=3 n=3 in this paper, noting that the effective receptive field on the input image is large (171 and 228 pixels for ZF and VGG, respectively).
- 滑窗尺寸 n = 3 n=3 n=3,使用一个较小的数是因为Feature Map提取的特征是经过很多层卷积和池化操作得到的,每一个元素在原始图像上的感受野(Receptive Field)都是相当大的。ZF-Net提取的Feature Map上一个 3 × 3 3 \times 3 3×3的区域对应原始图像上的区域大小为 171 × 171 171 \times 171 171×171,VGG-16的则是 228 × 228 228 \times 228 228×228,这个大小足够涵盖图像中一般的物体。
图2 卷积或池化操作会把输入图像的一个连续区域内的信息经过处理转换为一个像素点的值(但通道可能会逐渐增加),因此经过多次卷积和池化操作后输出的特征映射,其每一个像素点都涵盖了原始输入图像中很大一个区域内的信息,即感受野很大。
Note that because the mini-network operates in a sliding-window fashion, the fully-connected layers are shared across all spatial locations. This architecture is naturally implemented with an n × n n \times n n×n convolutional layer followed by two sibling 1 × 1 1 \times 1 1×1 convolutional layers (for reg and cls, respectively).
- RPN的作用过程的两个步骤其实都可以转化为卷积操作的过程。第一步中使用 n × n n \times n n×n大小的滑窗实际上就是以Feature Map为输入,经过一个 n × n n \times n n×n的卷积层,卷积层中卷积核的数量为输出特征的维数 d d d。这样就得到了一个通道数为 d d d的Feature Map,这个Feature Map上的每个 1 × 1 × d 1 \times 1 \times d 1×1×d的区域就可以看做是对应的 3 × 3 3 \times 3 3×3的输入经过映射后得到的 d d d维特征。第二步将提取出的 d d d维特征输入全连接层得到一个 p p p维的向量(用于分类的全连接层 p = 2 k p=2k p=2k,用于回归的全连接层 p = 4 k p=4k p=4k,其中 k k k为anchor的数量),这等同于以第一步得到的Feature Map为输入,经过一个有 p p p个 1 × 1 1 \times 1 1×1卷积核的卷积层后得到的输出。因此,RPN的结构实际上是一个 n × n n \times n n×n的卷积层接上两个并行的 1 × 1 1 \times 1 1×1的卷积层。全卷积的结构也使得RPN可以接受任意尺寸的输入。
图3 图中假设原图经过特征提取后得到
4
×
8
×
3
4 \times 8 \times 3
4×8×3的特征映射,RPN第一步提取特征维数
d
=
2
d=2
d=2。RPN的第一步中,使用
n
×
n
n \times n
n×n的卷积得到的特征映射中的每个
1
×
1
×
d
1 \times 1 \times d
1×1×d的区域都等同于对应的
n
×
n
n \times n
n×n滑窗内区域经过特征提取得到的
d
d
d维特征向量。第二步中,使用
1
×
1
1 \times 1
1×1卷积得到的4通道特征映射和2通道特征映射,也等同于把
d
×
4
d \times 4
d×4和
d
×
2
d \times 2
d×2的权重矩阵替换为4个
1
×
1
1 \times 1
1×1卷积核和2个
1
×
1
1 \times 1
1×1卷积核得到的结果。
RPN中的Anchor
Anchor在基于卷积神经网络的目标检测领域是一个很重要的概念,在很多模型中都有类似的概念。本节介绍Faster R-CNN中的Anchor。
上文提到,RPN网络其实是一个全卷积神经网络,最终有两个并行的卷积层,对于预训练网络提取的Feature Map上每个 3 × 3 3 \times 3 3×3的区域分别输出 2 k 2k 2k维和 4 k 4k 4k维的结果,这个 k k k就是Anchor的数量。
预训练网络提取的Feature Map上每一个 3 × 3 3 \times 3 3×3区域对应在原始图像上的感受野范围都会有一个中心点,Faster R-CNN中的Anchor本质上是以这个中心点为中心的一个候选区域(一个矩形框)。
直接以每个 3 × 3 3 \times 3 3×3的区域对应在原始图像上的感受野作为候选区域不可以吗?可以但效果会打折扣。一个物体可能会存在于一个候选区域中,也可能会不存在,也可能存在于候选区域中一个更小的部分里,也可能物体的一部分存在于候选区域中。因此,以一个像素点为中心,延伸出多个大小、形状不同的矩形框,更有可能得到较为精确包含一个物体的候选区域,这样也能使得后续分类和回归可能达到更好的精度。
在论文中作者选择了三个不同的尺度和三个不同长宽比的Anchor规格,经过组合得到 k = 9 k=9 k=9种不同的Anchor。
简而言之,Faster R-CNN利用Anchor机制,通过对预训练网络提取的Feature Map进行全卷积操作,利用原始图像上每一个 171 × 171 171 \times 171 171×171或 228 × 228 228 \times 228 228×228的区域得到的高级特征,一次性得到以该区域中心点为中心的一组大小、形状不一的区域内包含物体的可能性以及物体所存在区域的更精确范围。
注意到,论文中提到的:
By default we use 3 3 3 scales and 3 3 3 aspect ratios, yielding k = 9 k = 9 k=9 anchors at each sliding position. For a convolutional feature map of a size W × H W \times H W×H (typically ~2,400), there are W H k WHk WHk anchors in total.
在论文的实验中,输入的原始图片的尺寸约为 1000 × 600 1000 \times 600 1000×600,VGG-16网络提取的特征的尺寸为 1000 / 16 × 600 / 16 × 512 = 62.5 × 37.5 × 512 ≈ 60 × 40 × 512 1000/16 \times 600/16 \times 512 = 62.5 \times 37.5 \times 512 \approx 60 \times 40 \times 512 1000/16×600/16×512=62.5×37.5×512≈60×40×512,故有 “ W × H W \times H W×H (typically ~2,400)”。
Anchor的平移不变性
RPN网络的运行机制,实际上即卷积操作的运行机制,保证了Anchor是平移不变的(Translation-Invariant)。所谓的平移不变,是指如果把图像中的一个物体在图中进行移动,产生的Region Proposal也会随之移动到相应的位置。作为对比,论文举了一个MultiBox方法的例子。MultiBox方法利用K-means方法生成800个Anchor,而K-means方法本身的局限性使其无法保证在物体移动后还有相应的Anchor在对应的位置生成。
另外,平移不变性的特点还有助于减小模型的大小。MultiBox方法最后一层全连接层的神经元个数为 ( 4 + 1 ) × 800 (4+1) \times 800 (4+1)×800,而RPN方法最后一层的维数仅为 ( 4 + 2 ) × 9 (4+2) \times 9 (4+2)×9(在 k = 9 k=9 k=9的情况下)。因此,对于使用VGG-16进行特征提取的RPN网络,输出层共有 512 × ( 4 + 2 ) × 9 ≈ 2.8 × 1 0 4 512 \times (4+2) \times 9 \approx 2.8 \times 10^{4} 512×(4+2)×9≈2.8×104个参数,而使用GoogleNet的MultiBox方法的输出层则有 1536 × ( 4 + 1 ) × 800 ≈ 6.1 × 1 0 6 1536 \times (4+1) \times 800 \approx 6.1 \times 10^{6} 1536×(4+1)×800≈6.1×106个参数,比RPN方法高出两个数量级。
几处注解:
If one translates an object in an image, the proposal should translate and the same function should be able to predict the proposal in either location.
论文对这一句进行了注解: “our network is translation invariant up to the network’s total stride”。这里说明了Anchor的平移不变性是针对预训练网络提取的特征映射相邻元素在原图上感受野的步长决定的。意思就是说物体在图片上以步长的整数倍移动,才能保证有同样的Anchor以相同的方式作用在物体上。
In considering the feature projection layers, our proposal layers still have an order of magnitude fewer parameters than Multibox.
这一句同样在原文中有注解说明结论的计算过程。将特征投影层也考虑进来,RPN方法依旧比MultiBox方法的参数要少,特征投影层指的是把预训练网络提取的特征映射进行特征精简的层,即RPN网络中的第一层。结合两个层的参数来看,RPN方法的参数还是比MultiBox小一个量级,更小的参数量也意味着更不容易在小样本数据集上过拟合。
损失函数
RPN网络候选的 W H k WHk WHk个Anchor,并不是全部都参与训练的,而是根据一定的规则,将一定数量的,符合要求的Anchor标记为正样本或负样本,剩余的Anchor则舍去。在论文的做法中,满足正样本条件的Anchor有两种:
- 跟原图中任意一个ground-truth box(人工标注的框)的交并比(Inersection-over-Union, IoU)最高的Anchor;
- 跟原图中任意一个ground-truth box的IoU高于0.7的Anchor。
通常情况下,第二个条件对找到每个ground-truth box对应的正样本已经是充分的了,而且一个ground-truth box可能会存在多个满足条件的Anchor。但在极个别特殊情况下,可能会有一些ground-truth box无法找到满足第二个条件的Anchor(比如很小的物体,可能完全在一个Anchor当中,但其大小只是Anchor大小的0.5),这种情况下就要用第一个条件来保证每一个ground-truth box必须至少存在一个对应的正样本Anchor。
相对应的,一个Anchor被标记为负样本的条件则是它和图中任何一个ground-truth box的IoU都低于0.3。而剩余的既不满足正样本条件也不满足负样本条件的Anchor则不参与训练。
有了正负样本的定义之后,我们就可以给出RPN网络的损失函数:
L ( { p i } , { t i } ) = 1 N c l s ∑ i L c l s ( p i , p i ∗ ) + λ 1 N r e g ∑ i p i ∗ L r e g ( t i , t i ∗ ) L(\{p_{i}\}, \{t_{i}\}) = \frac{1}{N_{cls}}\sum_{i}L_{cls}(p_{i}, p_{i}^{*}) + \lambda \frac{1}{N_{reg}}\sum_{i}p_{i}^{*}L_{reg}(t_{i}, t_{i}^{*}) L({pi},{ti})=Ncls1i∑Lcls(pi,pi∗)+λNreg1i∑pi∗Lreg(ti,ti∗)
损失分为两部分,前一部分是二分类的损失,即RPN网络判断一个Anchor中是否存在物体的准确性的损失;后一部分是回归的损失,即RPN网络给出的物体存在的区域的坐标参数和ground-truth box的坐标参数之间的差异。
p i p_{i} pi和 t i t_{i} ti分别表示在每个minibatch中第 i i i个Anchor作为输入,RPN网络输出的对应的存在物体的概率以及BBox(物体所在的准确区域)的位置预测。 p i ∗ p_{i}^{*} pi∗和 t i ∗ t_{i}^{*} ti∗则分别是相应的标签。若第 i i iAnchor为正样本,则 p i ∗ p_{i}^{*} pi∗为 1 1 1,否则为 0 0 0。 t i ∗ t_{i}^{*} ti∗表示Anchor中存在的物体的ground-truth box的位置参数,只有标签为正样本的Anchor有 t i ∗ t_{i}^{*} ti∗。 p i p_{i} pi和 p i ∗ p_{i}^{*} pi∗都是一维的标量,表示概率,取值范围是 [ 0 , 1 ] [0,1] [0,1]; t i t_{i} ti和 t i ∗ t_{i}^{*} ti∗则是四维的向量 ( t x , t y , t w , t h ) (t_{x}, t_{y}, t_{w}, t_{h}) (tx,ty,tw,th),分别表示RPN输出的BBox和ground-truth box的中心的横纵坐标以及长和宽(这里的坐标参数并非绝对值,而是相对值,详见下文)。
二分类的部分采用二分类的log损失,即二元交叉熵(Binary Cross-entropy);回归部分采用平滑 L 1 L_{1} L1损失,回归损失部分乘上了一个 p i ∗ p_{i}^{*} pi∗,这使得只有当第 i i i个Anchor为正样本时回归损失的部分才被计算在损失函数中。两个部分分别由 N c l s N_{cls} Ncls和 N r e g N_{reg} Nreg进行标准化,其中 N c l s N_{cls} Ncls为minibatch的大小,即每个minibatch中Anchor的个数;而 N r e g N_{reg} Nreg表示Anchor的位置参数的总数量。 λ \lambda λ的取值默认为 10 10 10,作者在论文中指出实际上训练结果对 λ \lambda λ的取值在一个区间范围内都并不敏感,而且标准化也并非必要的。
下面给出 L c l s ( p i , p i ∗ ) L_{cls}(p_{i}, p_{i}^{*}) Lcls(pi,pi∗)和 L r e g ( t i , t i ∗ ) L_{reg}(t_{i}, t_{i}^{*}) Lreg(ti,ti∗)的具体公式。
-
二分类部分的损失函数为:
L c l s ( p i , p i ∗ ) = − p i ∗ l o g ( p i ) − ( 1 − p i ∗ ) l o g ( 1 − p i ) L_{cls}(p_{i}, p_{i}^{*}) = -p_{i}^{*}log(p_{i}) - (1-p_{i}^{*})log(1-p_{i}) Lcls(pi,pi∗)=−pi∗log(pi)−(1−pi∗)log(1−pi) -
回归部分的损失函数为:
L r e g ( t i , t i ∗ ) = ∑ i ∈ x , y , w , h s m o o t h L 1 ( t i ∗ − t i ) L_{reg}(t_{i}, t_{i}^{*}) = \sum_{i \in {x, y, w, h}} smooth L_{1}(t_{i}^{*} - t_{i}) Lreg(ti,ti∗)=i∈x,y,w,h∑smoothL1(ti∗−ti)
其中平滑 L 1 L_{1} L1的定义为
s m o o t h L 1 ( x ) = { 0.5 x 2 , i f ∣ x ∣ < 1 ∣ x ∣ − 0.5 smooth L_{1}(x) = \left\{ \begin{aligned} & 0.5x^{2}, \ \ \ \ \ \ \ \ if |x| < 1 \\ & |x| - 0.5 \end{aligned} \right. smoothL1(x)={0.5x2, if∣x∣<1∣x∣−0.5
由于每个Anchor的大小不一,直接用像素点的绝对值差异计算损失的话大的物体的预测BBox和ground-truth box之间的差异大概率大于小物体的差异,导致两者对损失函数的贡献不同,因此 t i t_{i} ti和 t i ∗ t_{i}^{*} ti∗中的四个元素都是相对值:
t x = ( x − x a ) / w a , t y = ( y − y a ) / h a , t w = l o g ( w / w a ) , t h = l o g ( h / h a ) , t x ∗ = ( x ∗ − x a ) / w a , t y ∗ = ( y ∗ − y a ) / h a , t w ∗ = l o g ( w ∗ / w a ) , t h ∗ = l o g ( h ∗ / h a ) \begin{aligned} & t_{x} = (x - x_{a}) / w_{a}, & t_{y} = (y - y_{a}) / h_{a}, \\ & t_{w} = log(w / w_{a}), & t_{h} = log(h / h_{a}), \\ & t_{x}^{*} = (x^{*} - x_{a}) / w_{a}, & t_{y}^{*} = (y^{*} - y_{a}) / h_{a}, \\ & t_{w}^{*} = log(w^{*} / w_{a}), & t_{h}^{*} = log(h^{*} / h_{a}) \end{aligned} tx=(x−xa)/wa,tw=log(w/wa),tx∗=(x∗−xa)/wa,tw∗=log(w∗/wa),ty=(y−ya)/ha,th=log(h/ha),ty∗=(y∗−ya)/ha,th∗=log(h∗/ha)
下表为 a a a的表示是Anchor的参数,如 ( x − x a ) / w a (x - x_{a}) / w_{a} (x−xa)/wa表示RPN预测的BBox的中心点到Anchor中心点的横坐标的差异相对于Anchor的宽度的值。
RPN的训练
通常来说,一张图片上满足负样本条件的Anchor远远多于满足正样本条件的Anchor,如果把所有满足条件的Anchor都加入训练,结果可想而知,模型会倾向于把Anchor都判定为不存在物体。因此,对于每一个mini-batch,论文从一张图片中随机选取1:1的正样本和负样本进行训练。每个mini-batch的大小为256,即每次都从一张图片中随机采样128个正样本Anchor和128个负样本Anchor。如果出现正样本Anchor少于128个的情形,再通过随机采样更多的负样本Anchor的方式来补足样本量。
对所有新的层(RPN网络的层)采用0均值、0.01标准差的正态分布初始化。其他的层(预训练网络的层)使用在ImageNet上进行预训练的参数初始化。若预训练网络采用ZF-Net,则全部层都用于训练;若采用VGG网络,则冻结前两个block,从conv3_1到conv5_3的部分用于训练。在PASCAL VOC数据集上训练,前60000个mini-batch使用0.001的学习率,后20000个使用0.0001的学习率,使用0.9的动量和0.0005的权重衰减。
RPN和Fast R-CNN的特征共享
RPN在Faster R-CNN中承担region proposal的工作,而检测部分仍旧是使用Fast R-CNN的检测部分(一下简称为Fast R-CNN)。RPN和Fast R-CNN共享预训练网络在原始图片上提取的特征,他们两者的训练独立,但他们的训练都会更新共享部分,即特征提取部分的卷积层的参数。为此,需要设计一种可以让RPN和Fast R-CNN共同对特征提取网络的参数进行作用的训练方式,而不是分别训练两个网络(这样会得到两个不同权重的特征提取网络)。
论文中讨论了三种不同的训练方式:
- Alternating training,即交替训练。首先训练RPN,然后使用RPN得到的region proposal训练Fast R-CNN,再用Fast R-CNN训练得到的权重参数初始化RPN,循环往复迭代训练。这也是论文中实验部分使用的训练方式。
- Approximate joint training,即联合训练。在这种训练方式中,作者把RPN和Fast-RCNN当做一个整体:前馈过程中把RPN生成的Region Proposal直接传递给Fast-RCNN去使用,而在反向传播的过程中,RPN和Fast-RCNN共同使用到的层的梯度由RPN和Fast-RCNN两部分的损失共同计算得到。这种训练方式很直接,也很好实现,相比Alternating training可以减少25%~50%的训练时间,同时得到的结果很接近。然而这种训练方式毕竟是“approximate”的,因为Fast-RCNN使用的Region Proposal的坐标参数实际上也是输出的一部分,但这些框被当做是训练好的模型输出的,是固定的,所以反向传播回去的梯度是存在一定误差的。
- Non-approximate joint training,这是一种理想化的训练方式,是理论上正确的方法。Fast R-CNN接收的输入实际上是特征提取网络得到的特征映射以及RPN预测的Bounding Boxes(也是输入经过函数变换得到的)两部分,因此反向传播的梯度理应包含这些RPN预测的Bounding Boxes的坐标参数。这需要RoI Pooling层对于坐标参数是可微的。文中提到这是一个非平凡问题,可以用一种叫“RoI warping”的方法处理。
在rbg大神的项目中有一个Alternating training的实现,具体地址https://github.com/rbgirshick/py-faster-rcnn/blob/master/tools/train_faster_rcnn_alt_opt.py,按脚本里的注释大致分为几个阶段:
- Stage 1 RPN, init from ImageNet model
- Stage 1 RPN, generate proposals
- Stage 1 Fast R-CNN using RPN proposals, init from ImageNet model
- Stage 2 RPN, init from stage 1 Fast R-CNN model
- Stage 2 RPN, generate proposals
- Stage 2 Fast R-CNN, init from stage 2 RPN R-CNN model
这里只做了两次交替的训练,实际上原文中也有提到,交替训练的次数对于最终结果并没有较大影响。