引言
在 object detection 领域,近 5 年的突破性进展似乎都与一个名字有关系:Ross Girshick。梳理从 R-CNN,Fast R-CNN, Faster R-CNN 到 Mask R-CNN 等各种经典模型,Ross Girshick 都是作者之一,甚至连 YOLO 的作者中也出现了 Ross Girshick 的名字。
这位大神简历如下:
-
2012.04: 芝加哥大学博士,师从 Pedro Felzenszwalb,就是提出 Felzenszwalb and Huttenlocher 图像分割算法的那位 Felzenszwalb。
-
2012.09 - 2014.08: 加州大学伯克利分校博士后。2014 CVPR 会议上作为第一作者提出 R-CNN。另外,他还是深度学习框架 Caffe 的主要贡献者之一。
-
2014.09 - 2015 Fall: 微软雷德蒙德研究院(Microsoft Research Redmond)研究员,期间提出 Fast R-CNN,唯一作者!另外,他还是 Microsoft COCO (Common Objects in COntext) 数据集 的作者之一。
-
2015 Fall 至今: Facebook 人工智能研究院 (FAIR)研究科学家。 Faster R-CNN 作者之一,文中指出大部分工作是在 Microsoft 时完成的。2016年YOLO 算法作者之一。2018年 Mask R-CNN 作者之一。
从算法到实现框架再到数据集,这位大神实现了一条龙的突破~
本文的目的是整理总结 R-CNN 系列算法的发展历程和模型本身的核心思想,不涉及太多技术细节(例如训练数据预处理,超参数设置等)。
参考文献主要是上述各算法的原文以及下列资源:
- 很经典的斯坦福大学计算机视觉课程:http://cs231n.stanford.edu/index.html
- 计算机视觉开源工具集 LUMINOTH 的技术博客:https://tryolabs.com/blog/2018/01/18/faster-r-cnn-down-the-rabbit-hole-of-modern-object-detection/
- medium.com 上若干优秀博客文章,在下边正文中有具体引用。
R-CNN
R-CNN,一般认为全称是 Region-based CNN 或者作者原文中提到的 Regions with CNN features。
概括地说,R-CNN 的步骤如下图所示:
from http://www.robots.ox.ac.uk/~tvg/publications/talks/fast-rcnn-slides.pdf- 输入待检测图片
- 从图片中提取若干子区域 (region proposal)
- 对每个 region 扭曲变形 (warp),得到 CNN 希望的输入图片大小,通过 CNN 进行特征提取,得到该 region 的 feature vector
- 将 region feature vector 送入 SVM 进行 image classification (或者称为 recognition),同时通过线性回归预测 bounding box 的位置调整。
下面详细介绍 R-CNN 中的关键环节。
region proposal
对于输入的图片,首先利用 selective search 算法生成约 2000 个 region。关于 selective search 算法可以参考原文,也可以参考我们之前的博客文章。原文中提到 R-CNN 对各种 region proposal 算法没有偏好,之所以选择 selective search 算法仅仅是为了方便与前人工作做对比。
region feature vector 提取
这一部分的目的是对于每一个 region,通过 CNN (原文选用 AlexNet) 进行特征提取,得到统一长度的 feature vector,以便后续的分类。
由于每个 region 的大小差别比较大,而 AlexNet 默认接收 227×227 pixel 的图片,这里就需要对 region 做一些预处理,主要是 region 大小的转化。
要把一个任意大小的图片转化成 227×227 像素的图片方法有很多,原文中介绍了 4 种方式:
from the original paper分别是:
- 保持原 region 比例,填充周边像素点,再缩放成 227×227,对应上图中(B)列
- 保持原 region 比例,不填充周边像素,缩放成 227×227,对应上图中(C)列
- 直接将原 region 扭曲(warp)缩放成 227 × 227,对应上图中(D)列
- 与 3 相同,但是在周边额外添加了一些像素点(即 padding),使得生成的 227×227 图像中上下左右包含了 16 pixel 的填充,对应上图中第 2 行和第 4 行。
最终作者选择了 warp + padding 的方式,一方面 warp 相对来说是最简单的,直接把任意大小的图片缩放成 227×227 即可,另外 padding 是在原 region 周围稍微添加了一些像素点,从实际效果看提高了检测正确率。
将统一大小的 region 送入 CNN 中,进行特征提取。如何得到这个 CNN 也是一个问题。
针对目标检测的数据集 ILSVRC detection dataset 包含了 200 类物体,PASCAL VOC (Visual Object Classes) 包含了 20 类物体。相对来说带有标签的训练数据比较少,不足以训练一个大型的 CNN,因此采用了 transfer learning 的技术。原文中并没有提到 transfer learning 这个名词,只是说 fine-tuning。
首先借用在 ImageNet 上已经训练好的 CNN 模型(最初的文章中用了 AlexNet,后来 arXiv 上新版文章中用了 VGG,效果提升很明显),然后在 PASCAL 数据集上进行 fine-tuning。这里对 AlexNet 网络结构的改变只是将原本对应 ImageNet 1000 类输出的 classification layer 替换成了对应 N+1 类输出的 classification layer,该层权重随机初始化。对于 PASCAL 数据集 N=20,ILSVRC 数据集 N=200,另外 +1 对应 background 类型。
经过 fine-tuning 之后,CNN softmax layer 之前的 4096 维向量即为该 region 的 feature vector.
classification by SVM
得到 region 的 feature vector 之后,送入 SVM 进行最后的分类。
这里 SVM 的训练是针对不同类型的物体分开进行的,每一类训练一个 SVM,它只给出针对这一类物体的分类结果。之所以最后用 SVM 分类,而不是直接用 CNN 的 softmax 进行分类,原文作者的解释是尝试过 softmax 之后发现效果比 SVM 差一些,但是同时指出如果调整一些训练策略,softmax 和 SVM 之间的差距有可能缩小。这也为后来基于 R-CNN 的改进埋下了伏笔。
得到所有 region 对应的检测结果(即包含某种类型物体的概率 score)之后,还有一步操作:Non-Maximum Suppression (NMS)。如果两个 region 检测到同一类物体,比如都检测到了行人,一个 region score 较高,而另一个 score 较低,当这两个 region 的 IoU (intersection-over-union) 超过某个阈值时,即它们重合较多时,只保留那个 score 较高的 region.
对 bounding box 的调整
object detection 的任务除了检测图中的物体,还要给出定位,即用 bounding box 尽量准确的圈出该物体。前边基于 region 的分类过程可能能够正确辨识出 region 中的物体,但是初始的 region 并不一定是一个合适的 bbox。在 R-CNN 最后又添加了一个线性回归模型,基于 feature vector 来预测正确的 bbox 相对于 region 的位置变换,即预测 bbox 应该如何调整。这个训练过程也是 class-specific 的。
在最终使用时,R-CNN 输出包含两部分:
- 对每个 region 进行分类
- 预测 bbox 位置的调整
理论上来说,更新 bbox 的位置之后,应该在新的 bbox 中重新进行分类,这样准确度可能更高一些,但是原文作者发现实际上并没有明显改进。因此,实际使用中并没有对新的 bbox 重新分类。
Fast R-CNN
总的来说,上述 R-CNN 的训练是分多步走的:先是 fine-tuning 一个 CNN 得到 feature vector,然后训练 SVM 进行分类,最后还要再训练一个线性回归环节预测 bounding box 的调整。
Fast R-CNN 的改进是不再使用独立的 SVM 和线性回归,而是统一用 CNN 将这三个环节整合起来。Fast R-CNN 在训练时间和检测时间方面比当时已有的其他算法快若干数量级。
Fast R-CNN 整体框架如下:
From the original paper基本步骤:
- 输入为一整幅图片,以及 Regions of Interest (RoI)。RoI 在之前的 R-CNN 中称为 region proposals,即通过 selective search 算法得到的原图上的若干 regions;
- 图片经过若干卷积层和 max pooling 层处理之后得到 feature map;
- 对于每一个 RoI 通过 RoI project 找到 feature map 上对应的区域,经过 RoI pooling layer 转化为统一大小的 sub feature map,进而得到统一大小的 feature vector;
- 基于每个 RoI 的 feature vector 有两个输出:用于分类的 softmax layer 和用于预测 bounding box 的 regressor.
在上述各环节中,我认为比较关键的有两个:一是 RoI projection,即将 image 上的 RoI 映射到 feature map 上的 RoI。二是通过 RoI pooling layer 将 feature map 上不同大小的 RoI 转化成统一大小的 sub feature map。而这两个环节都借鉴了 SPPnets,其中 RoI pooling layer 是 SPPnets 中 Spatial Pyramid Pooling layer 的特例。
RoI projection
原本 R-CNN 是在原图上选取若干RoI,然后经过 CNN 处理,最后提取出 feature vector。对于每个图片上不同的 RoI 来说,从输入到输出没有任何共享的东西。
RoI projection 的作用是将 R-CNN 中对 image RoI 的处理推迟到了 feature map 上,这样可以让一个 image 的所有 RoI 共享从 image 到 feature map 的卷积处理过程。这很显然会加速训练和测试过程。至于如何将 image RoI 映射到 feature map RoI,已经有了非常细致的讨论,这里不再赘述。
RoI pooling layer
如何将 feature map 上不同大小的 RoI 转化成统一大小的 sub feature map? 这里有非常直观的动画演示。
概括如下:
假设我们已经得到下面的 feature map (只考虑 2D)
其中 RoI 为黑框部分,大小为 。
我们希望将 RoI 转化成 2×2 大小,可以选择一个 2×2 的窗口如下
from https://deepsense.ai/region-of-interest-pooling-explained/.jpg对每一个格子进行 max pooling 操作,得到如下的 2×2 的 feature map
from https://deepsense.ai/region-of-interest-pooling-explained/.jpg总的来说,如果 RoI 大小为 ,希望得到的 feature map 大小为 ,则窗口中格子数目为 。可以根据具体情况向上或向下取整。
结合实际应用,如果 CNN 网络选用 VGG16,结构如下:
VGG16.jpg将最后一个 max pooling layer 替换为 RoI pooling layer。前部的卷积层对输入图片的大小没有严格限制,这一限制主要是在 fully connected layer,所以为了配合 VGG16 网络结构,要确保每个 RoI 输出的 feature map 依然为 。
对于 VGG16 网络结构的修改还包括:
- 去掉最后的 FC layer 和 softmax layer (原为 ImageNet 对应的 1000 类输出)
- 添加随机参数的 FC layer 和 K+1 输出的 softmax layer,其中 K 为物体种类,+1 对应 background
- 添加随机参数的 FC layer 和 K 个输出,每个输出对应一类物体,输出内容为 bbox 的调整函数,这里与 R-CNN 相同。
Faster R-CNN
在 Fast R-CNN 中,region proposal 是由 CNN 网络之外的算法提供的,例如 selective search。相对于后续的 region recognition 过程,region proposal 这一步实际上是整个算法的速度瓶颈。
Faster R-CNN 之所以 "Faster",就是因为提出了 Region Proposal Network (RPN) ,加速了 region proposal 过程。Faster R-CNN 本质上就是 RPN + Fast R-CNN.
整个 Faster R-CNN 结构如下:
From the original paper或者更加详细的结构如下:
From https://towardsdatascience.com/faster-rcnn-object-detection-f865e5ed7fc4
RPN 和 Fast R-CNN 共享从 image 到最后一层 CNN 输出的 feature map 这一段网络结构。有些文章也将 Faster R-CNN 看做三个模块:用于生成 feature map 的 Feature network,用于生成 region proposal 的 RPN,以及用于最终的 object detection 的 Detection network。我们这里还是采用 RPN + Fast R-CNN 的形式。
Region Proposal Network
RPN 的输入是原始 image,输出是 region proposals。在具体实现中,RPN 是 fully convolutional network (FCN),只包含 convolutional layer,原本在分类/回归中常用的全连通层也由卷积操作替代。
-
原始 image 经过卷积层操作得到 feature map。
-
对 feature map 中每一个 "pixel",找到其在原图中的 receptive field,以此为中心选取不同大小和高宽比的 个 anchors,原文中选择了 3 个 size: , , pixels,3 个 ratio: , , ,不同组合共 个 anchors。之所以称为 anchor (锚),是因为 RPN 输出的 region 是以这些 anchor 为参考/基准进行调整的。如果 feature map 的 size 为 ,相应的 anchors 数目为 。
-
RPN 通过一个 (默认 3×3) 的滑动窗口依次扫过 feature map,每个窗口通过 512 个 3×3 filter (对应 pre-trained CNN 为 VGG16)进行卷积操作得到 1×1×512 feature map (实际上也是 feature vector)。
注意 step 2 和 step 3 是两个层面上的操作:step 3 中是在 feature map 中对每个 3×3 滑动窗口进一步特征提取和降维,step 2 中是在原始图片中与滑动窗口中心 "pixel" 对应的位置选取 9 个不同大小和高宽比的 anchors。这些 anchors 显然不太可能都包含物体,到底那些 anchors 可以作为最后的 region,需要根据 feature map 上滑动窗口中的数据来预测。
-
以 1×1×512 feature map 作为输入, 一方面用 个 1×1 的 filter 做卷积得到 个输出,预测这 个 anchor 中每个 anchor 包含物体和不包含物体的概率,很显然两个概率的和为1;另一方面用 个 1×1 的 filter 做卷积得到 个输出,预测每个 anchor 位置和大小的调整。
有了 region proposals,后边的操作与 Fast R-CNN 是相同的。
Faster R-CNN 训练
原文中采用 alternating training 的方式:
- 先基于 VGG16 fine tuning RPN
- 然后将 RPN 输出的 region proposal 加上原始 image 一起训练 Fast R-CNN,在此过程中 RPN 和 Fast R-CNN 中前部生成 feature map 的 CNN 是独立的,也就说 RPN 和 Fast R-CNN 现在还没有共享的网络结构,两者都是基于 pre-trained VGG-16 fine tuning 的
- 将 Fast R-CNN 训练好的前部 CNN 网络共享给 RPN 并固定,只 fine tuning RPN 后部特有的网络部分
- 固定 RPN 和 Fast R-CNN 共享的前部 CNN 不变,只 fine tuning Fast R-CNN 后部特有的部分
网友评论