做者:chen_h
微信号 & QQ:862251340
微信公众号:coderpai
个人博客:请点击这里git
自从 Alex Krizhevsky, Geoff Hinton, and Ilya Sutskever 成为了 ImageNet 2012 冠军以后,CNN 已经变成了图像分割的标配。实际上,从那时起,CNN 已经在 ImageNet 挑战上面打败了人类。github
虽然这些分类结果使人印象深入,可是比真实的人类视觉理解仍是要简单不少。算法
在分类中,一般咱们会把图像中一个单一对象做为分类焦点,也就是说主要去识别焦点的物体(好比上面的狗狗)。可是,当咱们环顾咱们周围世界的时候,咱们面对的是一个更加复杂的问题。spring
咱们看到场景是一个很是复杂的场景,并且是多个目标进行重叠的背景,咱们不只须要分类这些不一样的对象,并且须要识别他们的边界和彼此的关联。windows
CNN 能够帮助咱们实现这样复杂的任务吗?也就是说,咱们给出更复杂的图像,能够利用 CNN 来识别图像中的不一样物体之间的边界吗?这个问题,在过去几年里,已经由 Ross Girshick 和他的同事向咱们证实了,答案是确定的。微信
经过这篇文章,咱们将介绍一些用于对象检测和分割的主要技术手段,而且了解他们是如何从上一个模型演变到下一个模型的。具体来讲,咱们将介绍 R-CNN(Regional CNN),一个最先利用CNN解决这个问题的模型,以及其后期的 Fast R-CNN 模型和 Faster R-CNN 模型。最后,咱们将介绍 Mask R-CNN 模型,这个模型是由 Facebook Research 最近发布的一篇文章,这篇文章提供了像素级别的分割。如下是各个模型的文章:网络
R-CNN: arxiv.org/abs/1311.25…架构
Fast R-CNN: arxiv.org/abs/1504.08…app
Faster R-CNN: arxiv.org/abs/1506.01…框架
Mask R-CNN: arxiv.org/abs/1703.06…
.](upload-images.jianshu.io/upload_imag…
受 Hinton 实验室的启发,UCB 的 Jitendra Malik 的团队问了这样一个问题:
对象检测到底能如何泛化?
对象检测是找到图像中的不一样对象而且进行分类的任务(如上图所示)。由 Ross Girshick,Jeff Donahue 和 Trevor Darrel 组成的团队发现这个问题能够用 Krizhevsky 的方法在 PASCAL VOC Challenge 上面进行实现,他们写道:
本文首先显示,与基于 HOG 类特征的简单系统相比,CNN 能够显著提升 PASCAL VOC 上的对象检测性能。
如今让咱们来了解一下 R-CNN 的架构,以及它是如何工做的。
R-CNN 模型的目标是根据拍摄的图像,正确识别图像中主要对象(经过边框)的位置。
输入:image
输出:物体边框 + 每一个对象的标签
可是咱们如何找出这些边框的位置呢?R-CNN 的作法就是按照人类的直观理解来作的 —— 咱们先从图像里把一些物体给框出来,而后来肯定这个物体是什么对象。
R-CNN 使用一种称为选择性搜索的技术来建立这些边界框,更多的细节你能够阅读这篇文章。更高层次来讲,选择性搜索(如上图所示)是经过不一样大小的窗口来查看图像,而且对于每一个大小不一样的窗口,尝试经过文理,颜色或强度将相邻像素分组在一块儿以识别对象。
一旦这些边框肯定以后,R-CNN 就会将该区域转变到一个标准的平方尺寸,并将其传送到 AlexNet 的一个变体中,如上图所示。
在 CNN 的最后一层,R-CNN 添加了一个支持向量机(SVM),它简单的分类这是不是一个对象,也就是图中的第四步。
如今,咱们已经得到了物体的大体边框,那么咱们能够将这个边框缩小以适应物体自己真实的尺寸吗?答案是能够的,这是 R-CNN的最后一步。R-CNN 对区域进行一个简单的线性回归,以生成更紧密的边界框坐标以得到结果。如下是回归模型的输入和输出:
输入:与物体对应图像的子区域。
输出:子区域中对象的新边界框坐标。
最后,总结一下 R-CNN 的几个步骤:
给图像生成一组边界框。
经过预先训练的 AlexNet 运行边框中的图像,最后经过 SVM 来进行分类。
一旦对象被分类,边界框经过运行线性回归模型输出更加紧密的边框坐标。
R-CNN 能够很好的工做,可是基于如下几个理由,它很是慢:
‘
’它须要 CNN(AlexNet)针对每一个图像区域进行运行分类(每一个图像大约 2000 次前向传递)。
它须要分别训练三种不一样的模型 —— CNN生成图像特征,SVM来预测分类,最后经过线性回归来收紧边界框。这样设计使得数据管道很是难设计。
2015年,R-CNN 的第一做者 Ross Girshick 解决了这两个问题,也就诞生了第二个算法 —— Fast R-CNN。如今,让咱们来看看它的主要思路:
对于 CNN 的前向传播,Girshick 意识到,对于每一个图像,图像的许多分割区域都是重叠的,这就使得咱们一次又一次地运行相同的 CNN 计算(大约 2000 次)。他的想法很简单,就是让CNN运行一次图像,而后找到一种共享计算的方法,来区分这 2000 个区域。
这正是 Fast R-CNN 被称之为 PolPool(Region of Interest Pooling)的核心技术,该技术能分享 CNN 在其次区域的前向传递。在上图中,请注意每一个 CNN 特征图是从一个原来的大特征图中进行选取的。而后,区域中的特征都被进行合并(通常是采用最大池)。因此须要咱们计算的是一个原始图片,而不是那个 2000 次区域。
Fast R-CNN 的第二个改进是在单一模型中同时训练了 CNN,分类器和边界回归。早期的模型咱们使用 CNN 来进行图像特征提取,SVM 来进行分类,最后用线性回归来进行边框收紧。Fast R-CNN 使用一个模型来同时达到这三个模型的效果。
上图展现的就是这个联合模型。Fast R-CNN 用 CNN 顶部的 softmax 层来替代 SVM 分类器的输出分类。它还添加了与 softmax 层平行的线性回归层用来输出边界框坐标。这样,全部咱们须要模型的输出都是来自于单一的网络。整个网络模型的输入和输出以下:
输入:带有区域目的的图像。
输出:每一个区域的对象分类以及更紧密的边界框。
即便取得了这些进步,Fast R-CNN 仍然存在一个瓶颈 —— 区域检测。正如咱们所看到的,检测对象位置的第一步是产生一对潜在的边界框和区域进行测试。在 Fast R-CNN 中,这些边界框是采用选择性搜索建立的,这是一个至关缓慢的过程,被认为是整个流程额瓶颈。
在2015年中期,一个微软研究员的团队 Shaoqing Ren,Kaiming He,Ross Girshick 和 Jian Sun,找到了一个方法来解决这个瓶颈问题,他们将这个方法命名为 Faster R-CNN。
Faster R-CNN 的一个重大改进是,在 CNN 第一步分类的时候,后续步骤重用那些相同的 CNN 结构,而不是单独运行选择性搜索算法。
的确,这正是 Faster R-CNN 团队所取得的成就。在上图中,你能够看到如何使用单个 CNN 来对区域进行处理和分类。这样,咱们只须要一个 CNN 进行训练,而其余的区域均可以从这个 CNN 网络中获取,做者这样写道:
咱们的观测结果是,用于区域检查(如 Fast R-CNN)的卷积特征图也能够用于区域生成,从而实现几乎无成本的区域生成。
一下是其模型的输入和输出:
输入:图像(注意不须要区域提案)。
输出:图像中对象的分类和边界框坐标。
接下来,让咱们来看看 Faster R-CNN 是如何从 CNN 特征图中来生成区域。Faster R-CNN 在网络上添加了一个彻底卷积网络,建立了一个所谓的区域生成网络。
区域生成网络经过在 CNN 特征图上面的滑动窗口,并在每一个窗口中输出 k 个潜在的边界框和分数,以便预测哪些框是最好的。那么,k 个框是表明什么呢?
直观地,咱们知道图像中的对象应该符合某些常见的比例和大小。例如,咱们知道咱们想要的一些相似于人类形状的边框比例和大小。一样,咱们知道咱们看到的不少的盒子厚度都不会很薄。以这种方式,咱们能够建立 k 个这样的盒子,咱们称之为锚盒(anchor boxes)。对于每一个这样的锚盒,咱们在图像中输出一个边界框和每一个位置的得分。
考虑到这些锚盒,咱们来看看这个区域生成网络的输入和输出:
输入:CNN 特征图。
输出:每一个锚盒对应的边界框和该边界框中图像会是某个对象的可能性分数。
而后,咱们将每一个这样的可能对象边界框传递到 Fast R-CNN 中,以生成分类结果和收紧边界框。
到目前为止,咱们已经看到咱们如何使用 CNN 特征图去有效地定位图像中不一样对象的边界框。
咱们能够将这些技术进一步扩展,并定位每一个对象的精确像素,而不是仅限于边框。这个像素级别的图像分割问题被 Kaiming He 等科学家解决,这个框架被称为 Mask R-CNN。
Fast R-CNN 和 Faster R-CNN 都能很好的工做,那么咱们能不能将模型进行扩展,使得他们在像素级别进行分割?
Mask R-CNN 经过向 Faster R-CNN 添加一个分支来输出一个二进制掩码,说明给定像素是不是对象的一部分。如上所述,分支(在上图中的白色部分)仅仅是基于 CNN 特征图的彻底卷积网络,一下是它的输入和输出:
输入:CNN特征图
输出:在像素属于对象的全部位置上标记为 1,其余地方标记为 0(这个称为二进制掩码)。
可是 Mask R-CNN 的做者不得不对模型进行一个小的调整,使这个管道能够按预期工做。
咱们须要对原始的 Faster R-CNN 架构进行修改,Mask R-CNN 的做者发现 RoIPool 选择的特征图的区域与原始图形的区域略有一点不对气。因为图像分割须要作到像素级,这与边框分割不一样,因此必然致使不许确。
做者能够经过巧妙的调整 RoIPool 网络来解决这个问题,调整好的模型被称为 RoIAlign。
想象一下,咱们有一个大小为 128
咱们知道原始图像中的每一个像素对应于特征图中大约 25/128 像素。要从原始图像中选择 15 像素,因此咱们只是选择了 15*25/128 ~= 2.93 像素。
在 RoIPool 中,咱们会将小数点舍去,从而选择 2 个像素,这样就会致使轻微的错位。然而,在 RoIAlign 中,咱们避免了这种四舍五入。相反的,咱们使用双线性差值来精确地了解像素 2.93 中的全部内容。这在很大程度上让咱们避免 RoIPool 所形成的错位。
一旦这些掩码生成,Mask R-CNN 将它们与来自 Faster R-CNN 的分类和边界框组合起来,以产生如此奇妙的精确分割:
若是你有兴趣本身尝试这些算法,这里有一些相关的库:
Caffe: github.com/rbgirshick/…
PyTorch: github.com/longcw/fast…
MatLab: github.com/ShaoqingRen…
PyTorch: github.com/felixgwu/ma…
TensorFlow: github.com/CharlesShan…
CoderPai 是一个专一于算法实战的平台,从基础的算法到人工智能算法都有设计。若是你对算法实战感兴趣,请快快关注咱们吧。加入AI实战微信群,AI实战QQ群,ACM算法微信群,ACM算法QQ群。详情请关注 “CoderPai” 微信号(coderpai)。