@改进1:RFCN
论文:R-FCN: Object Detection via Region-based Fully Convolutional Networks 【点击下载】
MXNet代码:【Github】
一. 背景介绍
RCNN 在目标检测上取得了很大的成功,比如 SPPnet、Fast R-CNN、Faster R-CNN 等,这些方法的典型特征都是 一个二分网络,以 ROI Pooling 为界,前面子网络用于特征提取,后面子网络用于 目标检测(Per ROI),带来的问题是 后面的子网络需要对每一个 ROI(Candidate)进行重复计算。
这种模式的形成是有原因的:Detection 来自于前期的分类网络(如 AlexNet、VGG),最后一个 Spatial Pooling 层直观对应到 RoI Pooling,这算是一个历史问题。
新提出的几个网络(ResNet、GoogLeNets)原生就是全卷积网络,因此也就将这种结构天然的对应到 Detection 问题上,想在 ResNet 上实现Detection,需要增加一个 ROI Pooling 层,但插入的位置很关键(每个 ROI 候选框对应一次计算,对应 后面子网的计算量 x N):
PS:减少 Proposal(ROI)的数量也是一个好办法,这对 Proposal 的要求会比较高(根据得分排序),先不讨论这种思路。
通过上面 可选的方案对比,可以看到 R-CNN 直接输入 Proposal,因此整个网络都用作检测,Faster 保留了后面10层用于检测,而作者新提出的方法则是 将 101 层全部用于共享,那么这种方案的可行性是怎么来保证的呢?
二. 提出框架
作者首先分析了 分类/检测 这两类问题的区别:
● 分类问题 - 具有平移不变性(Translation Invariance);
● 检测问题 - 在一定程度上具有平移敏感性 (Translation Variance);
通过 RoI pooling 的插入,打破了原卷积网络的平移不变性,但这种做法牺牲了训练和测试效率(Region-Wise)。
针对上述问题,作者提出了 一种新的卷积层 - Position Sensitive 的 Score Map,Score Map 包含了位置信息,如下图所示:
有两个关键层:
1)包含多个 Score Map 的卷积层;
把目标分割成了 k*k 个部分(比如3*3),每个部分映射到一张 Score Map 上,每个 Score Map 对应目标的一部分(如上图中的 top-left 左上角的 1/9)。
最终得到 k*k 个Score Map,每一个 Map通道数为 分类个数 C+1。
2)一个 ROI Pooling 层;
这个 ROI 层仅针对上面的其中一个 Score Map 执行 Pooling 操作,重新排列成 k*k,通道数为 C+1。
ROI Pooling 层通过 k*k 个 Part 进行投票,得到分类结果。
Score Map 和 ROI Pooling 层的工作方式示意如下:
三. 网络结构
R-FCN 沿用了 Faster RCNN 的网络结构,通过 RPN 生成 Proposal,RPN 层与 Detection 共享前面的特征层:
R-FCN 的基础网络部分是基于 ResNet101 的修改:
1)共享卷积子网
去掉了最后的 average pooling 层和全连接层,并新增了一个卷积层进行降维,共101个卷积层。
2)RPN 子网
与 Faster 一致,没有变化。
3)检测分类子网
1个 Score Maps层 + 1个 ROI Pooling层,上一节提到的两个关键层,与 RPN 并联。
> Scores Map & ROI 具体过程:
Scores Maps 的组合是卷积层的关键部分,描述了目标的 Score 信息,每一个 Score Map 对应目标的一部分,比如 上图中黄色 Map 始终表示左上角,其 C+1 维通道表示了 分类类别(C个类别+1个背景)。
Pooling 过程:结合 ROI (W‘,H’)来看,bin(Pool之后得到的9个不同的颜色块) 的尺寸描述为 (W‘/k,H’/k),对于上面的 3*3 的情况,每一个 bin 用公式来描述:
其中 i,j 取值为[0,k),理解为在 ROI 对应的其中一个 Map 上,采样其中的 1/9,上图中黄色 Map的采样范围始终为左上角,最右侧浅蓝色始终采样右下角。
投票过程是(每个类单独计算)通过多个 bin 求和得到 一个类的 Score,并通过 Softmax 进行分类,Loss 函数定义为:
分类 Loss 和 回归 Loss 通过一个参数 λ 加权平均,Lreg 同样采用 L1 Smooth。
四. 实验结果
在 VOC07,VOC12,MS COCO 上的测试对比结果,具体的配置和细节可以参考原文,R-FCN 与 Faster R-CNN 的对比,效果几乎相同,但效率有了成倍的提升。
@改进2:RON
论文:RON: Reverse Connection with Objectness Prior Networks for Object Detection 【点击下载】
Caffe代码:【Github】
一. 背景介绍
论文首先阐述了 Region-Based 方法在精确度上的优点,以及 Region-Free 方法在效果上的表现,想结合这两类方法,提出一种新的方法。
该方法包括三个方面:1)提出一种新的全卷积网络 RON;
第一,通过 Reverse Connection 为前一层 Feature 提供更多语义信息,第二,Objectness Prior 有效约束了目标搜索区域,最后,通过多任务 Loss 让整个网络实现 end-to-end 训练。
2)引入 Negative example mining(副样本挖掘) 和 data augmentation(数据增强),有效提高检测效果;
3)有效节约 计算时间 和 计算资源,1.5G显存+15fps,比 Faster R-CNN快3倍;
另外,我们还拓展了更多的设计选择,像不同层的合并,可选的Objectness Prior ,and so on。
这里面只有 1)算是文章创新,也是本文的核心;
2)顶多算是引入了别人的 Trick,不用考虑;
3)把功能性能搞混了吧,搞学术的童鞋凑数的本领强!
二. 算法框架
基础框架为 VGG16,将其中的 FC6,FC7 替换为卷积层,并通过 2*2的卷积核(stride=2)将 FC7 的分辨率减半,FC8 未使用。
特征图尺寸(基于 input 的缩放比例)分别为:1/8 (conv 4_3), 1/16 (conv 5_3), 1/32 (conv 6) , 1/64 (conv 7)。
Follow 论文组织结构往下看:
1)Reverse Connection(反向连接)
与作者之前的 HyperNet 一样,采用 反卷积(Deconv)将当前层的语义信息反馈到上层,通过一个上采样与之前层进行 融合。
多尺度信息能够对小目标有更好的检测精度,这一点都有共识了,通过 conv4、5、6、7 各特征层分别进行检测。
2)Reference Boxes(参考框)
参考框的提出与 Faster RCNN 里的 Anchor 类似,这里采用的是 2个尺度,5种长宽比 {1/3,1/2,1,2,3},对应 10个 Anchor。
尺度公式描述为:
Smin 取值为 Input 尺寸的 1/10,对于 1000*1000的 image,Smin = 100,对应每个特征图 k 得到:
k=1, S1 = (100,200)
k=2, S2 = (300,400)
k=3, S3 = (500,600)
k=4, S4 = (700,800)
3)Objectness Prior(目标先验)
对应上一节提出的 参考框(default boxes),只有很少一部分框包含目标,其余大部分都是无效的背景,Region-Based 方法能够通过预计算来解决这个问题,有效避免每个 Region 带来的重复计算。作者提出的方法与之不同:
用一个3x3x2的卷积 加 一个 Softmax 来表示每个 Box 里面是否存在目标。
PS:与 RPN 的区别在于这里只有一个 2位的 Score(目标Score,背景Score),没有位置偏移。
下图是 Prior 的一个可视化效果(很明显地反映有无目标):
图中对10个目标先验特征图沿通道方向取了平均。
4)Detection and Bounding Box Regression(检测和边框回归)
与 Objectness Prior 不同,这里要把目标分为 K+1个类:对应 VOC(20+1) COCO(80+1)。
这里引入了 inception 模块,看图说话:
5)Combining Objectness Prior with Detection(结合目标先验和检测)
训练网络时,首先为每个候选区域指定一个二进制 Label。如果候选区域包含目标,就再指定一个 特定类别 Label。
i)对每一个 Ground Truth Box,找到和它重叠面积最大的候选区域;
ii)对每个候选区域,找到和它重叠面积大于0.5的 Ground Truth;
这种匹配策略保证每一个 Ground Truth 至少有一个候选框与之关联,重叠比例小于0.3的作为负样本。
这样,每一个 Box 有两个 Label,Objectness(是否为目标) Label,Class Label。训练的时候网络会根据 Objectness Prior 动态更新 Class Label。
> 前向传播时,网络首先产生目标先验,并进行类别检测。
> 反向传播时,网络首先会产生目标先验,然后对于检测,只会在 Objectness 得分大于某个阈值的区域内进行目标检测,如下图所示。
额外的计算仅仅在于为反向传播选择训练样本。当选择合适的阈值时(我们选择阈值为0.03),样本的数量减少了,这样反向传播的时间就缩短了。
三. 训练及测试结果
● Loss函数:
先来看 Loss 函数定义:
将 目标检测Loss、定位Loss、分类Loss 组成一个加权 Loss 函数,原文 3个项都为 1/3。
● 训练过程:
a)对于 Objectness Prior,选择全部的正样本,随机选取负样本,保证正负样本的比例为1:3;
b)对于 Detection,首先通过 Objectness Prior Score 减少样本数量,然后选择全部的正样本,随机选取负样本,保证正负样本的比例为1:3;
Faster RCNN 和 RFCN 常常用 Multi Stage 训练 做联合优化,相比之下,我们这种端到端的训练方法更有效率。训练初期,目标先验是一片吵杂。随着训练的进行,目标先验图越来越集中在目标附近。(这一点确实不敢苟同,Multi Stage 的作用保证的是更快收敛)。
● 数据增强:
使用了如下策略:
1)使用 原始/翻转 的Image 做 Input;
2)按照比例 { 0.4, 0.5, 0.6, 0.7, 0.8, 0.9 } 从原图中 Crop Patch,保证每个 Patch 中包含目标中心;
这些方法可以有效增加大目标数量,对小目标没有帮助。
针对小目标,通过 Scale 将某个尺度下的大目标变成 较小的尺度下的小目标,这个训练策略可以避免对特定目标尺寸的过拟合。
● 预测:
每个 Box 的类置信度表示为:
这个得分包含两部分,一是 Objectness 的概率,二是目标的类别概率。得到目标 Score之后,通过边框回归调整 Box位置,最后用 NMS 得到最终检测结果。
● 效果对比:
作者分别在 VOC07,VOC12,COCO 数据集上给出了测试结果,我们只贴出来 VOC12 的效果对比:
其他数据集 测试结果都差不多,总体上效果还是不错的,大家可以跑代码之后对比。