• RCNN
RCNN(Regions with CNN features)是将CNN方法应用到目标检测问题上的一个里程碑,由年轻有为的RBG大神提出,借助CNN良好的特征提取和分类性能,通过RegionProposal方法实现目标检测问题的转化。
算法可以分为四步:
1)候选区域选择
Region Proposal是一类传统的区域提取方法,可以看作不同宽高的滑动窗口,通过窗口滑动获得潜在的目标图像,关于Proposal大家可以看下SelectiveSearch,一般Candidate选项为2k个即可,这里不再详述;
根据Proposal提取的目标图像进行归一化,作为CNN的标准输入。
2)CNN特征提取
标准CNN过程,根据输入进行卷积/池化等操作,得到固定维度的输出;
3)分类与边界回归
实际包含两个子步骤,一是对上一步的输出向量进行分类(需要根据特征训练分类器);二是通过边界回归(bounding-box regression) 得到精确的目标区域,由于实际目标会产生多个子区域,旨在对完成分类的前景目标进行精确的定位与合并,避免多个检出。
RCNN存在三个明显的问题:
1)多个候选区域对应的图像需要预先提取,占用较大的磁盘空间;
2)针对传统CNN需要固定尺寸的输入图像,crop/warp(归一化)产生物体截断或拉伸,会导致输入CNN的信息丢失;
3)每一个ProposalRegion都需要进入CNN网络计算,上千个Region存在大量的范围重叠,重复的特征提取带来巨大的计算浪费。
• SPP-Net
智者善于提出疑问,既然CNN的特征提取过程如此耗时(大量的卷积计算),为什么要对每一个候选区域独立计算,而不是提取整体特征,仅在分类之前做一次Region截取呢?智者提出疑问后会立即付诸实践,于是SPP-Net诞生了。
SPP-Net在RCNN的基础上做了实质性的改进:
1)取消了crop/warp图像归一化过程,解决图像变形导致的信息丢失以及存储问题;
2)采用空间金字塔池化(SpatialPyramid Pooling )替换了 全连接层之前的最后一个池化层(上图top),翠平说这是一个新词,我们先认识一下它。
为了适应不同分辨率的特征图,定义一种可伸缩的池化层,不管输入分辨率是多大,都可以划分成m*n个部分。这是SPP-net的第一个显著特征,它的输入是conv5特征图 以及特征图候选框(原图候选框 通过stride映射得到),输出是固定尺寸(m*n)特征;
还有金字塔呢?通过多尺度增加所提取特征的鲁棒性,这并不关键,在后面的Fast-RCNN改进中该特征已经被舍弃;
最关键的是SPP的位置,它放在所有的卷积层之后,有效解决了卷积层的重复计算问题(测试速度提高了24~102倍),这是论文的核心贡献。
尽管SPP-Net贡献很大,仍然存在很多问题:
1)和RCNN一样,训练过程仍然是隔离的,提取候选框 | 计算CNN特征| SVM分类 | Bounding Box回归独立训练,大量的中间结果需要转存,无法整体训练参数;
2)SPP-Net在无法同时Tuning在SPP-Layer两边的卷积层和全连接层,很大程度上限制了深度CNN的效果;
3)在整个过程中,Proposal Region仍然很耗时。
• Fast-RCNN
问题很多,解决思路同样也非常巧妙,ok,再次感谢 RBG 大神的贡献,直接引用论文原图(描述十分详尽)。Fast-RCNN主要贡献在于对RCNN进行加速,快是我们一直追求的目标(来个山寨版的奥运口号- 更快、更准、更鲁棒),问题在以下方面得到改进:
1)卖点1 - 借鉴SPP思路,提出简化版的ROI池化层(注意,没用金字塔),同时加入了候选框映射功能,使得网络能够反向传播,解决了SPP的整体网络训练问题;
2)卖点2 - 多任务Loss层
A)SoftmaxLoss代替了SVM,证明了softmax比SVM更好的效果;
B)SmoothL1Loss取代Bouding box回归。
将分类和边框回归进行合并(又一个开创性的思路),通过多任务Loss层进一步整合深度网络,统一了训练过程,从而提高了算法准确度。
3)全连接层通过SVD加速
这个大家可以自己看,有一定的提升但不是革命性的。
4)结合上面的改进,模型训练时可对所有层进行更新,除了速度提升外(训练速度是SPP的3倍,测试速度10倍),得到了更好的检测效果(VOC07数据集mAP为70,注:mAP,mean Average Precision)。
接下来分别展开这里面的两大卖点:
其中 为判别函数,为1时表示选中为最大值,0表示被丢弃,误差不需要回传,即对应 权值不需要更新。如下图所示,对于输入 xi 的扩展公式表示为:
(i,r,j) 表示 xi 在第 r 个框的第 j 个节点是否被选中为最大值(对应上图 y0,8 和 y1,0),xi 参数在前向传导时受后面梯度误差之和的影响。
多任务Loss层(全连接层)是第二个核心思路,如上图所示,其中cls_score用于判断分类,bbox_reg计算边框回归,label为训练样本标记。
其中Lcls为分类误差:
px 为对应Softmax分类概率,pl 即为label所对应概率(正确分类的概率),pl = 1时,计算结果Loss为0, 越小,Loss值越大(0.01对应Loss为2)。
即在正确分类的情况下,回归框与Label框之间的误差(Smooth L1), 对应描述边框的4个参数(上下左右or平移缩放),g对应单个参数的差异,|x|>1 时,变换为线性以降低离群噪声:
Ltotal为加权目标函数(背景不考虑回归Loss):
细心的小伙伴可能发现了,我们提到的SPP的第三个问题还没有解决,依然是耗时的候选框提取过程(忽略这个过程,Fast-RCNN几乎达到了实时),那么有没有简化的方法呢?
必须有,搞学术一定要有这种勇气。
• Faster-RCNN
对于提取候选框最常用的SelectiveSearch方法,提取一副图像大概需要2s的时间,改进的EdgeBoxes算法将效率提高到了0.2s,但是这还不够。
候选框提取不一定要在原图上做,特征图上同样可以,低分辨率特征图意味着更少的计算量,基于这个假设,MSRA的任少卿等人提出RPN(RegionProposal Network),完美解决了这个问题,我们先来看一下网络拓扑。
通过添加额外的RPN分支网络,将候选框提取合并到深度网络中,这正是Faster-RCNN里程碑式的贡献。
RPN网络的特点在于通过滑动窗口的方式实现候选框的提取,每个滑动窗口位置生成9个候选窗口(不同尺度、不同宽高),提取对应9个候选窗口(anchor)的特征,用于目标分类和边框回归,与FastRCNN类似。
目标分类只需要区分候选框内特征为前景或者背景。
边框回归确定更精确的目标位置,基本网络结构如下图所示:
训练过程中,涉及到的候选框选取,选取依据:
1)丢弃跨越边界的anchor;
2)与样本重叠区域大于0.7的anchor标记为前景,重叠区域小于0.3的标定为背景;
对于每一个位置,通过两个全连接层(目标分类+边框回归)对每个候选框(anchor)进行判断,并且结合概率值进行舍弃(仅保留约300个anchor), 没有显式地提取任何候选窗口 ,完全使用网络自身完成判断和修正。
从模型训练的角度来看,通过使用共享特征交替训练的方式,达到接近实时的性能,交替训练方式描述为:
1)根据现有网络初始化权值w,训练RPN;
2)用RPN提取训练集上的候选区域,用候选区域训练FastRCNN,更新权值w;
3)重复1、2,直到收敛。
因为Faster-RCNN,这种基于CNN的real-time 的目标检测方法看到了希望,在这个方向上有了进一步的研究思路。至此,我们来看一下RCNN网络的演进,如下图所示:
Faster RCNN的网络结构(基于VGG16):
Faster实现了端到端的检测,并且几乎达到了效果上的最优,速度方向的改进仍有余地,于是YOLO诞生了。
• YOLO
YOLO来自于“YouOnly Look Once”,你只需要看一次,不需要类似RPN的候选框提取,直接进行整图回归就可以了,简单吧?
算法描述为:
1)将图像划分为固定的网格(比如7*7),如果某个样本Object中心落在对应网格,该网格负责这个Object位置的回归;
2)每个网格预测包含Object位置与置信度信息,这些信息编码为一个向量;
3)网络输出层即为每个Grid的对应结果,由此实现端到端的训练。
YOLO算法的问题有以下几点:
1)7*7的网格回归特征丢失比较严重,缺乏多尺度回归依据;
2)Loss计算方式无法有效平衡(不管是加权或者均差),Loss收敛变差,导致模型不稳定。
Object(目标分类+回归)<=等价于=>背景(目标分类)
导致Loss对目标分类+回归的影响,与背景影响一致,部分残差无法有效回传;
整体上YOLO方法定位不够精确,贡献在于提出给目标检测一个新的思路,让我们看到了目标检测在实际应用中真正的可能性。
• SSD
由于YOLO本身采用的SingleShot基于最后一个卷积层实现,对目标定位有一定偏差,也容易造成小目标的漏检。
借鉴Faster-RCNN的Anchor机制,SSD(Single Shot MultiBox Detector)在一定程度上解决了这个问题,我们先来看下SSD的结构对比图。
基于多尺度特征的Proposal,SSD达到了效率与效果的平衡,从运算速度上来看,能达到接近实时的表现,从效果上看,要比YOLO更好。
传统的图像分割方法主要包括以下几种:
1)基于边缘检测
2)基于阈值分割
比如直方图,颜色,灰度等
3)水平集方法
这里我们要说的是语义分割,什么是语义分割呢?先来看张图:
将目标按照其分类进行像素级的区分,比如区分上图的 摩托车 和 骑手,这就是语义分割,语义分割赋予了场景理解更进一步的手段。
我们直接跳过传统的语义分割方法,比如 N-Cut,图割法等,直接进入深度学习。
FCN 的引入
CNN 在图像分割中应用,起源于2015年的这篇影响深远的文章:
Fully Convolutional Networks for Semantic Segmentation 【点击下载】
这里提到的就是全卷积网络,那么这个全卷积是如何理解 和 Work 的呢?来看一个对比:
上图红色部分 对应CNN分类网络的最后三层,也就是 FC 全连接,通过 Softmax 得到一个1000维的向量(基于Imagenet的图像分类),表示1000个不同的分类对应的概率,“tabby cat” 作为概率最高的结果。
下图蓝色部分将 分类网络对应的最后三层全连接 替换成了 卷积。整个网络全部通过卷积连接,so called 全卷积。这么做的目的是什么呢?
● 通过像素分类来定义语义分割
全卷积网络的输出是一张分割图,如何输出这张分割图呢? 通过卷积,图像的分辨率逐渐降低,这里需要 引入一个概念,就是上采样,即将低分辨率的图像放大到和原始图像同分辨率上,这是一个关键点。比如经过5次卷积(pooling)后,图像的分辨率依次缩小了2,4,8,16,32倍。对于最后一层的输出图像,需要进行32倍的上采样,得到原图大小一样的图像。
这个上采样是通过 反卷积(DeConvolution)实现的。来直观看一下反卷积的过程:
加上反卷积过程,整个的网络可以描述成:
由于前面采样部分过大,有时候会导致后面进行反卷积得到的结果分辨率比较低,导致一些细节丢失,解决的一个办法是 将 第 3|4|5 层反卷积结果叠加,结果我们就不贴了,肯定是上采样倍数越小,结果越好,来看叠加示意图(这种方式应该不陌生):
FCN 的改进
虽然 FCN引领了CNN基于语义分割的方向,但仍有很多地方需要改进,比如上采样导致的像素分割不精细,效率也不够快等等,我们相信一定有办法让其 更高效、更精细。这里提到的一个 方法就是结合 CRF。
CRF 全称是 Conditional Random Field,中文叫 “条件随机场”,首先来理解什么是随机场,一堆随机的样本就可以理解为是随机场,假设这些样本之间有关联关系,就成立条件随机场,CRF 最早在深度学习的 NLP 领域有比较多的应用,可以理解为语境的上下文关系,可以参考下面这篇文章:
Introduction to Conditional Random Fields
第一个改进 来自于 UCLA 的 Liang-Chieh Chen,在像素分类后叠加了一个 Fully Connected Conditional Random Fields(全连接的条件随机场)。
论文地址:Semantic image segmentation with deep convolutional nets and fully connected crfs
通过上图示意可以看到,Fully Connected CRF 在前面 FCN 输出的基础上,以全连接的形式,实现了后处理过程,使得像素分割更加细致,具体请参考论文。
接下来的改进有 通过 RNN + CRF 的idea:
参考论文:Conditional random fields as recurrent neural networks
根据实验对比效果来看,相当不错(注:DeepLab 就是上面的 Full connected CRF方法):
针对FCN的改进会在近两年一直持续,作者最关注的还是,Mask-RCNN,将目标检测与分割一起work的方法,接下来在下一篇文章介绍!
“桃李不言,下自成蹊”,FCN 当真是属于这个级别的贡献,引领了在这条道路上的每一次Follow。
实例分割(Instance Segment)
实例分割 与 语义分割的区别是要区分出每个目标(不仅仅是像素),相当于 检测+分割,通过一张图来直观理解一下:
关于 实例分割 的一篇典型论文 MaskRCNN,可以参考【Mask RCNN】,代码实现可以参考【浅入浅出TensorFlow 8 - 行人分割】
相关论文:
Instace-sensitive Fully Convolutional Networks.ECCV 2016【2016.3月上传到arxiv】
R-FCN:Object Detection via Region-based Fully Convolutional Networks.NIPS 2016【2016.7月上传到arxiv】
Fully Convolutional Instance-aware Semantic Segmentation.xxxx 2017【2016年11月上传到arxiv,MSCOCO2016的第一名】
一. Mask-RCNN 介绍
上篇文章介绍了 FCN,这篇文章引入个新的概念 Mask-RCNN,看着比较好理解哈,就是在 RCNN 的基础上添加 Mask。
Mask-RCNN 来自于年轻有为的 Kaiming 大神,通过在 Faster-RCNN 的基础上添加一个分支网络,在实现目标检测的同时,把目标像素分割出来。
论文下载:Mask R-CNN 部分翻译
代码下载:【Github】
Mask-RCNN 的网络结构示意(在作者原图基础上修改了一下):
假设大家对 Faster 已经很熟悉了,不熟悉的同学建议先看下之前的博文:【目标检测-RCNN系列】
其中 黑色部分为原来的 Faster-RCNN,红色部分为在 Faster网络上的修改:
1)将 Roi Pooling 层替换成了 RoiAlign;
2)添加并列的 FCN 层(mask 层);
先来概述一下 Mask-RCNN 的几个特点(来自于 Paper 的 Abstract):
1)在边框识别的基础上添加分支网络,用于 语义Mask 识别;
2)训练简单,相对于 Faster 仅增加一个小的 Overhead,可以跑到 5FPS;
3)可以方便的扩展到其他任务,比如人的姿态估计 等;
4)不借助 Trick,在每个任务上,效果优于目前所有的 single-model entries;
包括 COCO 2016 的Winners。
PS:写到这儿提醒一句,建议大家先读一遍 原 Paper,这样再回来看的话会有第二次理解。
二. RCNN行人检测框架
基于最早的 Faster RCNN 框架,出现不少改进,主要有三篇需要看:
1)作者推荐的这篇
Speed/accuracy trade-offs for modern convolutional object detectors
论文下载【arxiv】
2)ResNet
MSRA也算是作者自己的作品,可以 refer to blog【ResNet残差网络】
论文下载【arxiv】
3)FPN
Feature Pyramid Networks for Object Detection,通过特征金字塔来融合多层特征,实现CNN。
论文下载【arxiv】
来看下 后面两种 RCNN 方法与 Mask 结合的示意图(直接贴原图了):
图中灰色部分是 原来的 RCNN 结合 ResNet or FPN 的网络,下面黑色部分为新添加的并联 Mask层,这个图本身与上面的图也没有什么区别,旨在说明作者所提出的Mask RCNN 方法的泛化适应能力 - 可以和多种 RCNN框架结合,表现都不错。
三. Mask-RCNN 技术要点
● 技术要点1 - 强化的基础网络
通过 ResNeXt-101+FPN 用作特征提取网络,达到 state-of-the-art 的效果。
● 技术要点2 - ROIAlign
采用 ROIAlign 替代 RoiPooling(改进池化操作)。引入了一个插值过程,先通过双线性插值到14*14,再 pooling到7*7,很大程度上解决了仅通过 Pooling 直接采样带来的 Misalignment 对齐问题。
PS: 虽然 Misalignment 在分类问题上影响并不大,但在 Pixel 级别的 Mask 上会存在较大误差。
后面我们把结果对比贴出来(Table2 c & d),能够看到 ROIAlign 带来较大的改进,可以看到,Stride 越大改进越明显。
● 技术要点3 - Loss Function
每个 ROIAlign 对应 K * m^2 维度的输出。K 对应类别个数,即输出 K 个mask,m对应 池化分辨率(7*7)。Loss 函数定义:
Lmask(Cls_k) = Sigmoid (Cls_k), 平均二值交叉熵 (average binary cross-entropy)Loss,通过逐像素的 Sigmoid 计算得到。
Why K个mask?通过对每个 Class 对应一个 Mask 可以有效避免类间竞争(其他 Class 不贡献 Loss )。
通过结果对比来看(Table2 b),也就是作者所说的 Decouple 解耦,要比多分类 的 Softmax 效果好很多。
四. 对比实验效果
另外,作者给出了很多实验分割效果,就不都列了,只贴一张 和 FCIS 的对比图(FCIS 出现了Overlap 的问题):
五. Mask-RCNN 扩展
Mask-RCNN 在姿态估计上的扩展,效果不错,有兴趣的童鞋可以看Paper。