转载请注明作者: 梦里茶
Faster RCNN 在 Fast RCNN 上更进一步, 将 Region Proposal 也用神经网络来做, 如果说 Fast RCNN 的最大贡献是 ROI pooling layer 和 Multi task, 那么 RPN(Region Proposal Networks)就是 Faster RCNN 的最大亮点了使用 RPN 产生的 proposals 比 selective search 要少很多(300vs2000), 因此也一定程度上减少了后面 detection 的计算量
Introduction
Fast RCNN 之后, detection 的计算瓶颈就卡在了 Region Proposal 上一个重要原因就是, Region Proposal 是用 CPU 算的, 但是直接将其用 GPU 实现一遍也有问题, 许多提取规则其实是可以重用的, 因此有必要找一种能够共享算力的 GPU 版 Region Proposal
Faster RCNN 则是专门训练了一个卷积神经网络来回归 bounding box, 从而代替 region proposal 这个网络完全由卷积操作实现, 并且引入 anchor 以应对对象形状尺寸各异的问题, 测试速度与 Fast RCNN 相比速度极快
这个网络叫做 region proposal layer.
RPN
训练数据就是图片和 bounding box
输入任意尺寸的图片, 缩放到 800×600
输入到一个基础卷积神经网络, 比如 ZF 或者 VGG, 以 ZF 为例, 得到一个 51×39 的 feature map
用一个小的网络在 feature map 上滑窗, 算每个 3x3 窗口的 feature, 输出一个长度为 256 的向量, 这个操作很自然就是用 3×3 卷积来实现, 于是可以得到一个 51×39×256 的 feature map
每个 256 向量跟 feature map 上一个 3×3 窗口对应, 也跟 800×600 的原图上 9 个区域相对应, 具体讲一下这个 9 个区域:
卷积后 feature map 上的每个 3x3 的区域对应原图上一个比较大的感受野, 用 ZF 做前面的卷积层, 感受野为 171×171, 用 VGG 感受野为 228×228
我们想用 feature map 来判断它的感受野是否是前景, 但是对象并不总是正方形的, 于是我们需要对感受野做一个替换
我们让每个 3x3 的区域 (图中橙色方格) 和原图上九个区域相对应, 这九个区域的中心 (灰色方格) 就是 3x3 对应原图区域的中心
九个区域有九种尺寸分别是
- 128x128 128x64 64x128
- 256x256 256x128 128x256
- 512x512 512x256 256x512
这九个区域我们也成为 9 个 anchor, 或者 9 个 reference box
如此, 每个特征就能和原图上形状和尺寸各异的区域对应起来了
回到刚刚的 256 向量, 将这个向量输入一个 FC, 得到 2x9 个输出, 代表 9 个 anchor 为前景还是背景的概率
学习用的标签设置: 如果 anchor 与真实 bounding box 重叠率大于 0.7, 就当做是前景, 如果小于 0.3, 就当做背景
将 256 向量输入另一个 FC, 得到 4x9 个输出, 代表 9 个 anchor 的修正后的位置信息(x,y,w,h)
学习用的标签就是真实的 bounding box, 用的还是之 s 前 Faster RCNN 的 bounding box regression
两个 FC 在实现的时候是分别用两个 1x1 卷积实现的
以橙色为例, 256 向量和 W1 矩阵相乘, 得到长度为 18 的向量, 这样的操作在 51x39 个 feature 都要做一遍, 实现起来就很自然变成了用一个 1x1 的卷积核在 feature map 上做卷积啦, 这样也暗含了一个假设, 不同位置的 slide window 对于 anchor 的偏好是相同的, 是一个参数数量与精度的权衡问题
于是我们会得到图片上 51x39x920K 个 anchor 为前景的概率, 以及修正后的位置
上面这个过程可以完全独立地训练, 得到一个很好的 Region Proposal Network
理论上我们可以用上面这个流程去训练 RPN, 但训练 RPN 的时候, 一个 batch 会直接跑 20K 个 anchor 开销太大了
因此每个 batch 是采一张图里的 256 个 anchor 来训练全连接层和卷积层;
这 256 个 anchor 里正负样本比例为 1:1, 正样本 128 个, 负样本 128 个,
如果正样本不足 128 个, 用负样本填充, 这也意味着并非所有的背景 anchor 都会拿来训练 RPN, 因为前景的 anchor 会远少于背景的 anchor, 丢掉一些背景 anchor 才能保证样本平衡, 丢背景 anchor 的时候
具体实现上, 先算所有 anchor, 再算所有 anchor 与 bounding box 的重叠率, 然后选择 batch 中的 256 个 anchor, 参与训练同一张图会多次参与训练, 直到图中的正 anchor 用完
因此最终的一个 mini batch 的训练损失函数为:
其中,
pi 是一个 batch 中的多个 anchor 属于前景 / 后景的预测概率向量, ti 是一个 batch 中正 anchor 对应的 bounding box 位置向量
Lcls 是 softmax 二分类损失
Lreg 跟 Fast RCNN 中的 bounding box regression loss 一样, 乘一个 pi*, 意味着只有前景计算 bounding box regression loss
论文中说 Ncls 为 256, 也就是 mini-batch size,Nreg 约为 256*9=2304(论文中说约等于 2400), 这意味着一对 p 对应 9 个 t, 这种对应关系也体现在全连接层的输出个数上, 由于两个 task 输出数量差别比较大, 所以要做一下归一化
但这就意味着 loss 中的 mini-batch size 是以 3x3 的 slide window 为单位的, 因为只有 slide window 和 anchor 的个数才有这种 1:9 的关系, 而挑选训练样本讲的 mini-batch size 却是以 anchor 为单位的, 所以我猜实际操作是这样的:
先选 256 个 anchor,
然后找它们对应的 256 个 slide window,
然后再算这 256 个 slide window 对应的 256×9 个 anchor 的 loss, 每个 slide window 对应一个 256 特征, 有一个 Lcls, 同时对应 9 个 anchor, 有 9 个 Lreg
论文这里讲得超级混乱:
Proposal layer
其实这也可以算是 RPN 的一部分, 不过这部分不需要训练, 所以单独拉出来讲
接下来我们会进入一个 proposal layer, 根据前面得到的这些信息, 挑选 region 给后面的 fast rcnn 训练
图片输入 RPN 后, 我们手头的信息: anchor,anchor score,anchor location to fix
用全连接层的位置修正结果修正 anchor 位置
将修正后的 anchor 按照前景概率从高到底排序, 取前 6000 个
边缘的 anchor 可能超出原图的范围, 将严重超出边缘的 anchor 过滤掉
对 anchor 做非极大抑制, 跟 RCNN 一样的操作
再次将剩下的 anchor 按照 anchor score 从高到低排序(仍然可能有背景 anchor 的), 取前 300 个作为 proposals 输出, 如果不足 300 个就也没啥关系, 比如只有 100 个就 100 个来用, 其实不足 300 个的情况很少的, 你想 Selective Search 都有 2000 个
Fast RCNN
接下来就是按照 Fast RCNN 的模式来训练了, 我们可以为每张图前向传播从 proposal_layer 出来得到 300 个 proposals, 然后
取一张图的 128 个 proposal 作为样本, 一张图可以取多次, 直到 proposal 用完
喂给 Fast RCNN 做分类和 bounding box 回归, 这里跟 RPN 很像, 但又有所不同,
BB regressor: 拟合 proposal 和 bounding box, 而非拟合 anchor 和 bounding box
Classifier:Object 多分类, 而非前景背景二分类
迭代训练
RPN 和 Fast RCNN 其实是很像的, 因此可以一定程度上共享初始权重, 实际训练顺序如下(MATLAB 版):
先用 ImageNet pretrain ZF 或 VGG
训练 RPN
用 RPN 得到的 proposal 去训练 Fast RCNN
用 Fast RCNN 训练得到的网络去初始化 RPN
冻结 RPN 与 Fast RCNN 共享的卷积层, Fine tune RPN
冻结 RPN 与 Fast RCNN 共享的卷积层, Fine tune Fast RCNN
论文中还简单讲了一下另外两种方法:
将整个网络合起来一块训练, 而不分步, 但由于一开始训练时 RPN 还不稳定, 所以训练 Fast RCNN 用的 proposal 是固定的 anchor, 最后效果差不多, 训练速度也快
整个网络合起来一起训练, 不分步, 训练 Fast RCNN 用的 proposals 是 RPN 修正后的 anchor, 但这种动态的 proposal 数量不好处理, 用的是一种 RoI warping layer 来解决, 这又是另一篇论文的东西了
SUMMARY
网络结构和训练过程都介绍完了, 实验效果也是依样画葫芦, 就不再介绍了, 整体来说, Faster RCNN 这篇论文写得很乱, 很多重要的细节都要去看代码才能知道是怎么回事, 得亏是效果好才能中 NIPS
来源: https://www.cnblogs.com/hellocwh/p/8671029.html