目标检测综述

本文做者 刘畅,公众号计算机视觉life编辑成员javascript

前言

图片分类任务咱们已经熟悉了,就是算法对其中的对象进行分类。而今天咱们要了解构建神经网络的另外一个问题,即目标检测问题。这意味着,咱们不只要用算法判断图片中是否是一辆汽车, 还要在图片中标记出它的位置, 用边框或红色方框把汽车圈起来, 这就是目标检测问题。 其中“定位”的意思是判断汽车在图片中的具体位置。
img
近几年来,目标检测算法取得了很大的突破。比较流行的算法能够分为两类,一类是基于Region Proposal的R-CNN系算法(R-CNN,Fast R-CNN, Faster R-CNN等),它们是two-stage的,须要先算法产生目标候选框,也就是目标位置,而后再对候选框作分类与回归。而另外一类是Yolo,SSD这类one-stage算法,其仅仅使用一个卷积神经网络CNN直接预测不一样目标的类别与位置。第一类方法是准确度高一些,可是速度慢,可是第二类算法是速度快,可是准确性要低一些。这能够在下图中看到。
img
本文对常见目标检测算法进行简要综述,并最后总结了目标检测算法方向的一些大V方便你们学习查看。java

1. R-CNN

目标检测有两个主要任务:物体分类和定位,为了完成这两个任务,R-CNN借鉴了滑动窗口思想, 采用对区域进行识别的方案,具体是:web

  1. 输入一张图片,经过指定算法从图片中提取 2000 个类别独立的候选区域(可能目标区域)
  2. 对于每一个候选区域利用卷积神经网络来获取一个特征向量
  3. 对于每一个区域相应的特征向量,利用支持向量机SVM 进行分类,并经过一个bounding box regression调整目标包围框的大小

1.1. 提取候选区域

R-CNN目标检测首先须要获取2000个目标候选区域,可以生成候选区域的方法不少,好比:面试

  1. objectness
  2. selective search
  3. category-independen object proposals
  4. constrained parametric min-cuts(CPMC)
  5. multi-scale combinatorial grouping
  6. Ciresan
    R-CNN 采用的是 Selective Search 算法。简单来讲就是经过一些传统图像处理方法将图像分红不少小尺寸区域,而后根据小尺寸区域的特征合并小尺寸获得大尺寸区域,以实现候选区域的选取。

1.2. 提取特征向量

对于上述获取的候选区域,需进一步使用CNN提取对应的特征向量,做者使用模型AlexNet (2012)。(须要注意的是 Alexnet 的输入图像大小是 227x227,而经过 Selective Search 产生的候选区域大小不一,为了与 Alexnet 兼容,R-CNN 采用了很是暴力的手段,那就是无视候选区域的大小和形状,统一变换到 227x227 的尺寸)。
那么,该网络是如何训练的呢?训练过程以下:算法

  1. 有监督预训练:训练网络参数
    • 样本:ImageNet
    • 这里只训练和分类有关的参数,由于ImageNet数据只有分类,没有位置标注
    • 图片尺寸调整为227x227
    • 最后一层:4097维向量->1000向量的映射。
  2. 特定样本下的微调 :训练网络参数
    • 样本:
      RCNN样本
    • 采用训练好的AlexNet模型进行PASCAL VOC 2007样本集下的微调,学习率=0.001(PASCAL VOC 2007样本集上既有图像中物体类别标签,也有图像中物体位置标签)
    • mini-batch为32个正样本和96个负样本(因为正样本太少)
    • 修改了原来的1000为类别输出,改成21维【20类+背景】输出。

1.3. SVM分类

经过上述卷积神经网络获取候选区域的特征向量,进一步使用SVM进行物体分类,关键知识点以下:编程

  1. 使用了一个SVM进行分类:向SVM输入特征向量,输出类别得分
  2. 用于训练多个SVM的数据集是ImageNet数据
  3. 将2000×4096维特征(2000个候选框,每一个候选框得到4096的特征向量)与20个SVM组成的权值矩阵4096×20相乘(20种分类,SVM是二分类器,每一个种类训练一个SVM,则有20个SVM),得到2000×20维矩阵表示每一个建议框是某个物体类别的得分
  4. 分别对上述2000×20维矩阵中每列即每一类进行非极大值抑制剔除重叠建议框,获得该列即该类中得分最高的一些候选框;
    RCNN分类
    SVM训练:
  • 样本:segmentfault

    RCNN-SVM训练

  • 因为SVM是二分类器,须要为每一个类别训练单独的SVM;网络

  • SVM训练时,输入正负样本是在AlexNet CNN网络输出的4096维特征向量,输出为该类的得分框架

  • 因为负样本太多,采用hard negative mining的方法在负样本中选取有表明性的负样本ide

1.4 边框修正

使用一个回归器进行边框回归:输入为卷积神经网络pool5层的4096维特征向量,输出为x、y方向的缩放和平移,实现边框的修正。在进行测试前仍需回归器进行训练。
回归器训练

  • 样本:

    RCNN边框回归样本
    在2014年R-CNN横空出世的时候,颠覆了以往的目标检测方案,精度大大提高。对于R-CNN的贡献,能够主要分为两个方面:

    1. 使用了卷积神经网络进行特征提取
    2. 使用bounding box regression进行目标包围框的修正
      可是,咱们来看一下,R-CNN有什么问题:
    3. 耗时的selective search,对一张图像,须要花费2s
    4. 耗时的串行式CNN前向传播,对于每个候选框,都需通过一个AlexNet提取特征,为全部的候选框提取特征大约花费47s
    5. 三个模块(CNN特征提取、SVM分类和边框修正)是分别训练的,而且在训练的时候,对于存储空间的消耗很大

2. Fast R-CNN

面对R-CNN的缺陷,Ross在2015年提出的Fast R-CNN进行了改进,下面咱们来概述一下Fast R-CNN的解决方案:

img

  1. 首先仍是采用selective search提取2000个候选框RoI
  2. 使用一个卷积神经网络对全图进行特征提取
  3. 使用一个RoI Pooling Layer在全图特征上摘取每个RoI对应的特征
  4. 分别通过为21和84维的全链接层(并列的,前者是分类输出,后者是回归输出)
    Fast R-CNN经过CNN直接获取整张图像的特征图,再使用RoI Pooling Layer在特征图上获取对应每一个候选框的特征,避免了R-CNN中的对每一个候选框串行进行卷积(耗时较长)。

2.1 RoI Pooling Layer

对于每一个RoI而言,须要从共享卷积层获取的特征图上提取对应的特征,而且送入全链接层进行分类。所以,RoI Pooling主要作了两件事,第一件是为每一个RoI选取对应的特征,第二件事是为了知足全链接层的输入需求,将每一个RoI对应的特征的维度转化成某个定值。RoI Pooling示意图以下所示:ROI-POOLING

如上图所示,对于每个RoI,RoI Pooling Layer将其映射到特征图对应位置,获取对应特征。另外,因为每个RoI的尺度各不相同,因此提取出来的特征向量region proposal维度也不尽相同,所以须要某种特殊的技术来作保证输入后续全链接层的特征向量维度相同。ROI Pooling的提出即是为了解决这一问题的。其思路以下:

  • 将region proposal划分为目标H×W大小的分块

  • 对每个分块中作MaxPooling(每一个分块中含有多个网格,每一个分块获取一个特征值)

  • 将全部输出值组合起来便造成固定大小为H×W的feature map

    pooling_sections
    out
    Fast R-CNN的贡献能够主要分为两个方面:

  1. 取代R-CNN的串行特征提取方式,直接采用一个CNN对全图提取特征(这也是为何须要RoI Pooling的缘由)。
  2. 除了selective search,其余部分均可以合在一块儿训练。
    Fast R-CNN也有缺点,体如今耗时的selective search仍是依旧存在。

3. Faster R-CNN

Faster R-CNN 取代selective search,直接经过一个Region Proposal Network (RPN)生成待检测区域,这么作,在生成RoI区域的时候,时间也就从2s缩减到了10ms。下图是Faster R-CNN总体结构。

img
由上图可知,Faster R-CNN由共享卷积层、RPN、RoI pooling以及分类和回归四部分组成:

  1. 首先使用共享卷积层为全图提取特征feature maps
  2. 将获得的feature maps送入RPN,RPN生成待检测框(指定RoI的位置),并对RoI的包围框进行第一次修正
  3. RoI Pooling Layer根据RPN的输出在feature map上面选取每一个RoI对应的特征,并将维度置为定值
  4. 使用全链接层(FC Layer)对框进行分类,而且进行目标包围框的第二次修正。
    尤为注意的是,Faster R-CNN真正实现了端到端的训练(end-to-end training)。Faster R-CNN最大特点是使用了RPN取代了SS算法来获取RoI,如下对RPN进行分析。

3.1 RPN

经典的检测方法生成检测框都很是耗时,如OpenCV adaboost使用滑动窗口+图像金字塔生成检测框;或如R-CNN使用SS(Selective Search)方法生成检测框。而Faster R-CNN则抛弃了传统的滑动窗口和SS方法,直接使用RPN生成检测框,这也是Faster R-CNN的巨大优点,能极大提高检测框的生成速度。
首先来看看RPN的工做原理:

img
上图展现了RPN网络的具体结构。能够看到RPN网络实际分为2条支线,上面一条支线经过softmax来分类anchors得到前景foreground和背景background(检测目标是foreground),下面一条支线用于计算anchors的边框偏移量,以得到精确的proposals。而最后的proposal层则负责综合foreground anchors和偏移量获取proposals,同时剔除过小和超出边界的proposals。其实整个网络到了Proposal Layer这里,就完成了至关于目标定位的功能。
anchor:
简单地说,RPN依靠一个在共享特征图上滑动的窗口,为每一个位置生成9种预先设置好长宽比与面积的目标框(即anchor)。这9种初始anchor包含三种面积(128×128,256×256,512×512),每种面积又包含三种长宽比(1:1,1:2,2:1)。示意图以下所示:

img
因为共享特征图的大小约为40×60,因此RPN生成的初始anchor的总数约为20000个(40×60×9)。其实RPN最终就是在原图尺度上,设置了密密麻麻的候选anchor。进而去判断anchor究竟是前景仍是背景,意思就是判断这个anchor到底有没有覆盖目标,以及为属于前景的anchor进行第一次坐标修正。

img
判断前景或背景:
对于全部的anchors,首先须要判断anchor是是否为前景。对于第一个问题,RPN的作法是使用SoftmaxLoss直接训练,在训练的时候排除掉了超越图像边界的anchor;
边框修正:
如图绿色表示的是飞机的实际框标签(ground truth),红色的表示的其中一个候选区域(foreground anchor),即被分类器识别为飞机的区域,可是因为红色区域定位不许确,这张图至关于没有正确检测出飞机,因此咱们但愿采用一种方法对红色的框进行微调,使得候选区域和实际框更加接近:

img
对于目标框通常使用四维向量来表示(x,y,w,h)(x,y,w,h) ,分别表示目标框的中心点坐标、宽、高,咱们使用AA 表示原始的foreground anchor,使用GG 表示目标的ground truth,咱们的目标是寻找一种关系,使得输入原始的Anchor AA 通过映射到一个和真实框GG 更接近的回归窗口G′G′ ,即:

  • 给定:

  • 寻找一种变换FF ,使得



    img
    那么如何去计算F 呢?这里咱们能够经过平移和缩放实现

  • 平移:

  • 缩放:


    上面公式中,咱们须要学习四个参数,分别是


    其中


    表示的两个框中心距离的偏移量
    当输入的anchor A与G相差较小时,能够认为这种变换是一种线性变换, 那么就能够用线性回归来建模对目标框进行微调(注意,只有当anchors A和G比较接近时,才能使用线性回归模型,不然就是复杂的非线性问题了)。
    接下来就是如何经过线性回归得到


    线性回归就是给定输入的特征向量X ,学习一组参数W,使得线性回归的输出WX和真实值Y 的差很小。对于该问题,输入X是特征图,咱们使用ϕ 表示,同时训练时还须要A到G变换的真实参数值:


    输出是


    那么目标函数能够表示为:


    其中ϕ(A) 是对应anchor的特征图组成的特征向量,ww 是须要学习的参数,d(A) 是获得预测值(表示x*,y,w,*h,也就是每个变换对应一个上述目标函数),为了让预测值和真实值差距最小,代价函数以下:


    函数优化目标为:


    须要说明,只有在G和A比较接近时,才可近似认为上述线性变换成立,下面对于原文中,A与G之间的平移参数和尺度因子为:


    在获得每个候选区域anchor A的修正参数以后,咱们就能够计算出精确的anchor,而后按照物体的区域得分从大到小对获得的anchor排序,而后提出一些宽或者高很小的anchor(获取其它过滤条件),再通过非极大值抑制抑制,取前Top-N的anchors,而后做为proposals(候选框)输出,送入到RoI Pooling层。
    那么,RPN怎么实现呢?这个问题经过RPN的本质很好求解,RPN的本质是一个树状结构,树干是一个3×3的卷积层,树枝是两个1×1的卷积层,第一个1×1的卷积层解决了先后景的输出,第二个1×1的卷积层解决了边框修正的输出。来看看在代码中是怎么作的:



    从如上代码中能够看到,对于RPN输出的特征图中的每个点,一个1×1的卷积层输出了18个值,由于是每个点对应9个anchor,每一个anchor有一个前景分数和一个背景分数,因此9×2=18。另外一个1×1的卷积层输出了36个值,由于是每个点对应9个anchor,每一个anchor对应了4个修正坐标的值,因此9×4=36。那么,要获得这些值,RPN网络须要训练。在训练的时候,就须要对应的标签。那么,如何断定一个anchor是前景仍是背景呢?文中作出了以下定义:若是一个anchor与ground truth的IoU在0.7以上,那这个anchor就算前景(positive)。相似地,若是这个anchor与ground truth的IoU在0.3如下,那么这个anchor就算背景(negative)。在做者进行RPN网络训练的时候,只使用了上述两类anchor,与ground truth的IoU介于0.3和0.7的anchor没有使用。在训练anchor属于前景与背景的时候,是在一张图中,随机抽取了128个前景anchor与128个背景anchor。

3.3. 分类和定位

Faster R-CNN中的RoI Pooling Layer与 Fast R-CNN中原理同样。在RoI Pooling Layer以后,就是Faster R-CNN的分类器和RoI边框修正训练。分类器主要是分这个提取的RoI具体是什么类别(人,车,马等),一共C+1类(包含一类背景)。RoI边框修正和RPN中的anchor边框修正原理同样,一样也是SmoothL1 Loss,值得注意的是,RoI边框修正也是对于非背景的RoI进行修正,对于类别标签为背景的RoI,则不进行RoI边框修正的参数训练。对于分类器和RoI边框修正的训练,能够损失函数描述以下:


上式中u>=1表示RoI边框修正是对于非背景的RoI而言的,实验中,上式的λ取1。
在训练分类器和RoI边框修正时,步骤以下所示:

  1. 首先经过RPN生成约20000个anchor(40×60×9)。
  2. 对20000个anchor进行第一次边框修正,获得修订边框后的proposal。
  3. 对超过图像边界的proposal的边进行clip,使得该proposal不超过图像范围。
  4. 忽略掉长或者宽过小的proposal。
  5. 将全部proposal按照前景分数从高到低排序,选取前12000个proposal。
  6. 使用阈值为0.7的NMS算法排除掉重叠的proposal。
  7. 针对上一步剩下的proposal,选取前2000个proposal进行分类和第二次边框修正。
    总的来讲,Faster R-CNN的loss分两大块,第一大块是训练RPN的loss(包含一个SoftmaxLoss和SmoothL1Loss),第二大块是训练Faster R-CNN中分类器的loss(包含一个SoftmaxLoss和SmoothL1Loss),Faster R-CNN的总的loss函数描述以下:

4. Mask R-CNN

Mask R-CNN能够分解为以下的3个模块:Faster-RCNN、RoI Align和Mask。算法框架以下:

img
图6 Mask R-CNN算法框架
算法步骤:

  • 首先,输入一幅你想处理的图片,而后进行对应的预处理操做,或者预处理后的图片;

  • 而后,将其输入到一个预训练好的神经网络中(ResNeXt等)得到对应的feature map;

  • 接着,对这个feature map中的每一点设定预约个的RoI,从而得到多个候选RoI;

  • 接着,将这些候选的RoI送入RPN网络进行二值分类(前景或背景)和BB回归,过滤掉一部分候选的ROI;

  • 接着,对这些剩下的RoI进行RoIAlign操做(即先将原图和feature map的pixel对应起来,而后将feature map和固定的feature对应起来);

  • 最后,对这些RoI进行分类(N类别分类)、BB回归和MASK生成(在每个ROI里面进行FCN操做)。
    Mask R-CNN是一个很是灵活的框架,能够增长不一样的分支完成不一样的任务,能够完成目标分类、目标检测、语义分割、实例分割、人体姿式识别等多种任务,以下图所示。

    imgimg

4.1. ROI Align

Mask R-CNN使用RoIAlign取代了Faster RCNN中的RoIPooling,故下文对RoIPooling和RoIAlign进行分析与比较

img
如上图所示,RoI Pooling和RoIAlign最大的区别是:前者使用了两次量化操做,然后者并无采用量化操做,使用了线性插值算法,具体的解释以下所示。
RoI Pooling

img
如上图所示,为了获得固定大小(7X7)的feature map,咱们须要作两次量化操做:1)图像坐标 — feature map坐标,2)feature map坐标 — RoI feature坐标。咱们来讲一下具体的细节,如图咱们输入的是一张800x800的图像,在图像中有两个目标(猫和狗),狗的BB大小为665x665,通过VGG16网络后,咱们能够得到对应的feature map,若是咱们对卷积层进行Padding操做,咱们的图片通过卷积层后保持原来的大小,可是因为池化层的存在,咱们最终得到feature map 会比原图缩小必定的比例,这和Pooling层的个数和大小有关。在该VGG16中,咱们使用了5个池化操做,每一个池化操做都是2x2Pooling,所以咱们最终得到feature map的大小为800/32 x 800/32 = 25x25(是整数),可是将狗的BB对应到feature map上面,咱们获得的结果是665/32 x 665/32 = 20.78 x 20.78,结果是浮点数,含有小数,可是咱们的像素值可没有小数,那么做者就对其进行了量化操做(即取整操做),即其结果变为20 x 20,在这里引入了第一次的量化偏差;然而咱们的feature map中有不一样大小的ROI,可是咱们后面的网络却要求咱们有固定的输入,所以,咱们须要将不一样大小的ROI转化为固定的ROI feature,在这里使用的是7x7的ROI feature,那么咱们须要将20 x 20的ROI映射成7 x 7的ROI feature,其结果是 20 /7 x 20/7 = 2.86 x 2.86,一样是浮点数,含有小数点,咱们采起一样的操做对其进行取整吧,在这里引入了第二次量化偏差。其实,这里引入的偏差会致使图像中的像素和特征中的像素的误差,即将feature空间的ROI对应到原图上面会出现很大的误差。缘由以下:好比用咱们第二次引入的偏差来分析,原本是2,86,咱们将其量化为2,这期间引入了0.86的偏差,看起来是一个很小的偏差呀,可是你要记得这是在feature空间,咱们的feature空间和图像空间是有比例关系的,在这里是1:32,那么对应到原图上面的差距就是0.86 x 32 = 27.52。这个差距不小吧,这仍是仅仅考虑了第二次的量化偏差。这会大大影响整个检测算法的性能,所以是一个严重的问题。
RoIAlign

img
如上图所示,为了获得为了获得固定大小(7X7)的feature map,RoIAlign技术并无使用量化操做,即咱们不想引入量化偏差,好比665 / 32 = 20.78,咱们就用20.78,不用什么20来替代它,好比20.78 / 7 = 2.97,咱们就用2.97,而不用2来代替它。这就是RoIAlign的初衷。那么咱们如何处理这些浮点数呢,咱们的解决思路是使用“双线性插值”算法。双线性插值是一种比较好的图像缩放算法,它充分的利用了原图中虚拟点(好比20.56这个浮点数,像素位置都是整数值,没有浮点值)四周的四个真实存在的像素值来共同决定目标图中的一个像素值,便可以将20.56这个虚拟的位置点对应的像素值估计出来。以下图所示,蓝色的虚线框表示卷积后得到的feature map,黑色实线框表示ROI feature,最后须要输出的大小是2x2,那么咱们就利用双线性插值来估计这些蓝点(虚拟坐标点,又称双线性插值的网格点)处所对应的像素值,最后获得相应的输出。这些蓝点是2x2Cell中的随机采样的普通点,做者指出,这些采样点的个数和位置不会对性能产生很大的影响,你也能够用其它的方法得到。而后在每个橘红色的区域里面进行max pooling或者average pooling操做,得到最终2x2的输出结果。咱们的整个过程当中没有用到量化操做,没有引入偏差,即原图中的像素和feature map中的像素是彻底对齐的,没有误差,这不只会提升检测的精度,同时也会有利于实例分割。

img

4.2. Mask

下图阐述了Mask R-CNN的Mask branch:


在Mask R-CNN中的RoI Align以后有一个"head"部分,主要做用是将RoI Align的输出维度扩大,这样在预测Mask时会更加精确。在Mask Branch的训练环节,做者没有采用FCN式的SoftmaxLoss,反而是输出了K个Mask预测图(为每个类都输出一张),并采用average binary cross-entropy loss训练,固然在训练Mask branch的时候,输出的K个特征图中,也只是对应ground truth类别的那一个特征图对Mask loss有贡献。
Mask R-CNN的训练损失函数能够描述为:

5. Yolo

以上目标检测模型都是two-stage算法,针对于two-stage目标检测算法广泛存在的运算速度慢的缺点,Yolo创造性的提出了one-stage,也就是将物体分类和物体定位在一个步骤中完成。Yolo直接在输出层回归bounding box的位置和bounding box所属类别,从而实现one-stage。经过这种方式,Yolo可实现45帧每秒的运算速度,彻底能知足实时性要求(达到24帧每秒,人眼就认为是连续的)。整个系统以下图所示。img

前言

图片分类任务咱们已经熟悉了,就是算法对其中的对象进行分类。而今天咱们要了解构建神经网络的另外一个问题,即目标检测问题。这意味着,咱们不只要用算法判断图片中是否是一辆汽车, 还要在图片中标记出它的位置, 用边框或红色方框把汽车圈起来, 这就是目标检测问题。 其中“定位”的意思是判断汽车在图片中的具体位置。
img
近几年来,目标检测算法取得了很大的突破。比较流行的算法能够分为两类,一类是基于Region Proposal的R-CNN系算法(R-CNN,Fast R-CNN, Faster R-CNN等),它们是two-stage的,须要先算法产生目标候选框,也就是目标位置,而后再对候选框作分类与回归。而另外一类是Yolo,SSD这类one-stage算法,其仅仅使用一个卷积神经网络CNN直接预测不一样目标的类别与位置。第一类方法是准确度高一些,可是速度慢,可是第二类算法是速度快,可是准确性要低一些。这能够在下图中看到。
img
本文对常见目标检测算法进行简要综述,并最后总结了目标检测算法方向的一些大V方便你们学习查看。

1. R-CNN

目标检测有两个主要任务:物体分类和定位,为了完成这两个任务,R-CNN借鉴了滑动窗口思想, 采用对区域进行识别的方案,具体是:

  1. 输入一张图片,经过指定算法从图片中提取 2000 个类别独立的候选区域(可能目标区域)
  2. 对于每一个候选区域利用卷积神经网络来获取一个特征向量
  3. 对于每一个区域相应的特征向量,利用支持向量机SVM 进行分类,并经过一个bounding box regression调整目标包围框的大小

1.1. 提取候选区域

R-CNN目标检测首先须要获取2000个目标候选区域,可以生成候选区域的方法不少,好比:

  1. objectness
  2. selective search
  3. category-independen object proposals
  4. constrained parametric min-cuts(CPMC)
  5. multi-scale combinatorial grouping
  6. Ciresan
    R-CNN 采用的是 Selective Search 算法。简单来讲就是经过一些传统图像处理方法将图像分红不少小尺寸区域,而后根据小尺寸区域的特征合并小尺寸获得大尺寸区域,以实现候选区域的选取。

1.2. 提取特征向量

对于上述获取的候选区域,需进一步使用CNN提取对应的特征向量,做者使用模型AlexNet (2012)。(须要注意的是 Alexnet 的输入图像大小是 227x227,而经过 Selective Search 产生的候选区域大小不一,为了与 Alexnet 兼容,R-CNN 采用了很是暴力的手段,那就是无视候选区域的大小和形状,统一变换到 227x227 的尺寸)。
那么,该网络是如何训练的呢?训练过程以下:

  1. 有监督预训练:训练网络参数
    • 样本:ImageNet
    • 这里只训练和分类有关的参数,由于ImageNet数据只有分类,没有位置标注
    • 图片尺寸调整为227x227
    • 最后一层:4097维向量->1000向量的映射。
  2. 特定样本下的微调 :训练网络参数
    • 样本:
      RCNN样本
    • 采用训练好的AlexNet模型进行PASCAL VOC 2007样本集下的微调,学习率=0.001(PASCAL VOC 2007样本集上既有图像中物体类别标签,也有图像中物体位置标签)
    • mini-batch为32个正样本和96个负样本(因为正样本太少)
    • 修改了原来的1000为类别输出,改成21维【20类+背景】输出。

1.3. SVM分类

经过上述卷积神经网络获取候选区域的特征向量,进一步使用SVM进行物体分类,关键知识点以下:

  1. 使用了一个SVM进行分类:向SVM输入特征向量,输出类别得分
  2. 用于训练多个SVM的数据集是ImageNet数据
  3. 将2000×4096维特征(2000个候选框,每一个候选框得到4096的特征向量)与20个SVM组成的权值矩阵4096×20相乘(20种分类,SVM是二分类器,每一个种类训练一个SVM,则有20个SVM),得到2000×20维矩阵表示每一个建议框是某个物体类别的得分
  4. 分别对上述2000×20维矩阵中每列即每一类进行非极大值抑制剔除重叠建议框,获得该列即该类中得分最高的一些候选框;
    RCNN分类
    SVM训练:
  • 样本:

    RCNN-SVM训练

  • 因为SVM是二分类器,须要为每一个类别训练单独的SVM;

  • SVM训练时,输入正负样本是在AlexNet CNN网络输出的4096维特征向量,输出为该类的得分

  • 因为负样本太多,采用hard negative mining的方法在负样本中选取有表明性的负样本

1.4 边框修正

使用一个回归器进行边框回归:输入为卷积神经网络pool5层的4096维特征向量,输出为x、y方向的缩放和平移,实现边框的修正。在进行测试前仍需回归器进行训练。
回归器训练

  • 样本:

    RCNN边框回归样本
    在2014年R-CNN横空出世的时候,颠覆了以往的目标检测方案,精度大大提高。对于R-CNN的贡献,能够主要分为两个方面:

    1. 使用了卷积神经网络进行特征提取
    2. 使用bounding box regression进行目标包围框的修正
      可是,咱们来看一下,R-CNN有什么问题:
    3. 耗时的selective search,对一张图像,须要花费2s
    4. 耗时的串行式CNN前向传播,对于每个候选框,都需通过一个AlexNet提取特征,为全部的候选框提取特征大约花费47s
    5. 三个模块(CNN特征提取、SVM分类和边框修正)是分别训练的,而且在训练的时候,对于存储空间的消耗很大

2. Fast R-CNN

面对R-CNN的缺陷,Ross在2015年提出的Fast R-CNN进行了改进,下面咱们来概述一下Fast R-CNN的解决方案:

img

  1. 首先仍是采用selective search提取2000个候选框RoI
  2. 使用一个卷积神经网络对全图进行特征提取
  3. 使用一个RoI Pooling Layer在全图特征上摘取每个RoI对应的特征
  4. 分别通过为21和84维的全链接层(并列的,前者是分类输出,后者是回归输出)
    Fast R-CNN经过CNN直接获取整张图像的特征图,再使用RoI Pooling Layer在特征图上获取对应每一个候选框的特征,避免了R-CNN中的对每一个候选框串行进行卷积(耗时较长)。

2.1 RoI Pooling Layer

对于每一个RoI而言,须要从共享卷积层获取的特征图上提取对应的特征,而且送入全链接层进行分类。所以,RoI Pooling主要作了两件事,第一件是为每一个RoI选取对应的特征,第二件事是为了知足全链接层的输入需求,将每一个RoI对应的特征的维度转化成某个定值。RoI Pooling示意图以下所示:ROI-POOLING

如上图所示,对于每个RoI,RoI Pooling Layer将其映射到特征图对应位置,获取对应特征。另外,因为每个RoI的尺度各不相同,因此提取出来的特征向量region proposal维度也不尽相同,所以须要某种特殊的技术来作保证输入后续全链接层的特征向量维度相同。ROI Pooling的提出即是为了解决这一问题的。其思路以下:

  • 将region proposal划分为目标H×W大小的分块

  • 对每个分块中作MaxPooling(每一个分块中含有多个网格,每一个分块获取一个特征值)

  • 将全部输出值组合起来便造成固定大小为H×W的feature map

    pooling_sections
    out
    Fast R-CNN的贡献能够主要分为两个方面:

  1. 取代R-CNN的串行特征提取方式,直接采用一个CNN对全图提取特征(这也是为何须要RoI Pooling的缘由)。
  2. 除了selective search,其余部分均可以合在一块儿训练。
    Fast R-CNN也有缺点,体如今耗时的selective search仍是依旧存在。

3. Faster R-CNN

Faster R-CNN 取代selective search,直接经过一个Region Proposal Network (RPN)生成待检测区域,这么作,在生成RoI区域的时候,时间也就从2s缩减到了10ms。下图是Faster R-CNN总体结构。

[外链图片转存失败(img-aWtAvx5g-1562678877759)(https://ae01.alicdn.com/kf/UTB8tV72OwQydeJk43PUq6AyQpXak.jpg)]
由上图可知,Faster R-CNN由共享卷积层、RPN、RoI pooling以及分类和回归四部分组成:

  1. 首先使用共享卷积层为全图提取特征feature maps
  2. 将获得的feature maps送入RPN,RPN生成待检测框(指定RoI的位置),并对RoI的包围框进行第一次修正
  3. RoI Pooling Layer根据RPN的输出在feature map上面选取每一个RoI对应的特征,并将维度置为定值
  4. 使用全链接层(FC Layer)对框进行分类,而且进行目标包围框的第二次修正。
    尤为注意的是,Faster R-CNN真正实现了端到端的训练(end-to-end training)。Faster R-CNN最大特点是使用了RPN取代了SS算法来获取RoI,如下对RPN进行分析。

3.1 RPN

经典的检测方法生成检测框都很是耗时,如OpenCV adaboost使用滑动窗口+图像金字塔生成检测框;或如R-CNN使用SS(Selective Search)方法生成检测框。而Faster R-CNN则抛弃了传统的滑动窗口和SS方法,直接使用RPN生成检测框,这也是Faster R-CNN的巨大优点,能极大提高检测框的生成速度。
首先来看看RPN的工做原理:

img
上图展现了RPN网络的具体结构。能够看到RPN网络实际分为2条支线,上面一条支线经过softmax来分类anchors得到前景foreground和背景background(检测目标是foreground),下面一条支线用于计算anchors的边框偏移量,以得到精确的proposals。而最后的proposal层则负责综合foreground anchors和偏移量获取proposals,同时剔除过小和超出边界的proposals。其实整个网络到了Proposal Layer这里,就完成了至关于目标定位的功能。
anchor:
简单地说,RPN依靠一个在共享特征图上滑动的窗口,为每一个位置生成9种预先设置好长宽比与面积的目标框(即anchor)。这9种初始anchor包含三种面积(128×128,256×256,512×512),每种面积又包含三种长宽比(1:1,1:2,2:1)。示意图以下所示:

img
因为共享特征图的大小约为40×60,因此RPN生成的初始anchor的总数约为20000个(40×60×9)。其实RPN最终就是在原图尺度上,设置了密密麻麻的候选anchor。进而去判断anchor究竟是前景仍是背景,意思就是判断这个anchor到底有没有覆盖目标,以及为属于前景的anchor进行第一次坐标修正。

img
判断前景或背景:
对于全部的anchors,首先须要判断anchor是是否为前景。对于第一个问题,RPN的作法是使用SoftmaxLoss直接训练,在训练的时候排除掉了超越图像边界的anchor;
边框修正:
如图绿色表示的是飞机的实际框标签(ground truth),红色的表示的其中一个候选区域(foreground anchor),即被分类器识别为飞机的区域,可是因为红色区域定位不许确,这张图至关于没有正确检测出飞机,因此咱们但愿采用一种方法对红色的框进行微调,使得候选区域和实际框更加接近:

img
对于目标框通常使用四维向量来表示(x,y,w,h)(x,y,w,h) ,分别表示目标框的中心点坐标、宽、高,咱们使用AA 表示原始的foreground anchor,使用GG 表示目标的ground truth,咱们的目标是寻找一种关系,使得输入原始的Anchor AA 通过映射到一个和真实框GG 更接近的回归窗口G′G′ ,即:

  • 给定:

  • 寻找一种变换FF ,使得



    img
    那么如何去计算F 呢?这里咱们能够经过平移和缩放实现

  • 平移:

  • 缩放:


    上面公式中,咱们须要学习四个参数,分别是


    其中


    表示的两个框中心距离的偏移量
    当输入的anchor A与G相差较小时,能够认为这种变换是一种线性变换, 那么就能够用线性回归来建模对目标框进行微调(注意,只有当anchors A和G比较接近时,才能使用线性回归模型,不然就是复杂的非线性问题了)。
    接下来就是如何经过线性回归得到

    [外链图片转存失败(img-63l5Z6W6-1562678877766)(https://pic.superbed.cn/item/5d08b6a3451253d178dd9fe3.gif)]
    线性回归就是给定输入的特征向量X ,学习一组参数W,使得线性回归的输出WX和真实值Y 的差很小。对于该问题,输入X是特征图,咱们使用ϕ 表示,同时训练时还须要A到G变换的真实参数值:


    输出是


    那么目标函数能够表示为:


    其中ϕ(A) 是对应anchor的特征图组成的特征向量,ww 是须要学习的参数,d(A) 是获得预测值(表示x*,y,w,*h,也就是每个变换对应一个上述目标函数),为了让预测值和真实值差距最小,代价函数以下:


    函数优化目标为:


    须要说明,只有在G和A比较接近时,才可近似认为上述线性变换成立,下面对于原文中,A与G之间的平移参数和尺度因子为:


    在获得每个候选区域anchor A的修正参数以后,咱们就能够计算出精确的anchor,而后按照物体的区域得分从大到小对获得的anchor排序,而后提出一些宽或者高很小的anchor(获取其它过滤条件),再通过非极大值抑制抑制,取前Top-N的anchors,而后做为proposals(候选框)输出,送入到RoI Pooling层。
    那么,RPN怎么实现呢?这个问题经过RPN的本质很好求解,RPN的本质是一个树状结构,树干是一个3×3的卷积层,树枝是两个1×1的卷积层,第一个1×1的卷积层解决了先后景的输出,第二个1×1的卷积层解决了边框修正的输出。来看看在代码中是怎么作的:



    从如上代码中能够看到,对于RPN输出的特征图中的每个点,一个1×1的卷积层输出了18个值,由于是每个点对应9个anchor,每一个anchor有一个前景分数和一个背景分数,因此9×2=18。另外一个1×1的卷积层输出了36个值,由于是每个点对应9个anchor,每一个anchor对应了4个修正坐标的值,因此9×4=36。那么,要获得这些值,RPN网络须要训练。在训练的时候,就须要对应的标签。那么,如何断定一个anchor是前景仍是背景呢?文中作出了以下定义:若是一个anchor与ground truth的IoU在0.7以上,那这个anchor就算前景(positive)。相似地,若是这个anchor与ground truth的IoU在0.3如下,那么这个anchor就算背景(negative)。在做者进行RPN网络训练的时候,只使用了上述两类anchor,与ground truth的IoU介于0.3和0.7的anchor没有使用。在训练anchor属于前景与背景的时候,是在一张图中,随机抽取了128个前景anchor与128个背景anchor。

3.3. 分类和定位

Faster R-CNN中的RoI Pooling Layer与 Fast R-CNN中原理同样。在RoI Pooling Layer以后,就是Faster R-CNN的分类器和RoI边框修正训练。分类器主要是分这个提取的RoI具体是什么类别(人,车,马等),一共C+1类(包含一类背景)。RoI边框修正和RPN中的anchor边框修正原理同样,一样也是SmoothL1 Loss,值得注意的是,RoI边框修正也是对于非背景的RoI进行修正,对于类别标签为背景的RoI,则不进行RoI边框修正的参数训练。对于分类器和RoI边框修正的训练,能够损失函数描述以下:


上式中u>=1表示RoI边框修正是对于非背景的RoI而言的,实验中,上式的λ取1。
在训练分类器和RoI边框修正时,步骤以下所示:

  1. 首先经过RPN生成约20000个anchor(40×60×9)。
  2. 对20000个anchor进行第一次边框修正,获得修订边框后的proposal。
  3. 对超过图像边界的proposal的边进行clip,使得该proposal不超过图像范围。
  4. 忽略掉长或者宽过小的proposal。
  5. 将全部proposal按照前景分数从高到低排序,选取前12000个proposal。
  6. 使用阈值为0.7的NMS算法排除掉重叠的proposal。
  7. 针对上一步剩下的proposal,选取前2000个proposal进行分类和第二次边框修正。
    总的来讲,Faster R-CNN的loss分两大块,第一大块是训练RPN的loss(包含一个SoftmaxLoss和SmoothL1Loss),第二大块是训练Faster R-CNN中分类器的loss(包含一个SoftmaxLoss和SmoothL1Loss),Faster R-CNN的总的loss函数描述以下:

4. Mask R-CNN

Mask R-CNN能够分解为以下的3个模块:Faster-RCNN、RoI Align和Mask。算法框架以下:

img
图6 Mask R-CNN算法框架
算法步骤:

  • 首先,输入一幅你想处理的图片,而后进行对应的预处理操做,或者预处理后的图片;

  • 而后,将其输入到一个预训练好的神经网络中(ResNeXt等)得到对应的feature map;

  • 接着,对这个feature map中的每一点设定预约个的RoI,从而得到多个候选RoI;

  • 接着,将这些候选的RoI送入RPN网络进行二值分类(前景或背景)和BB回归,过滤掉一部分候选的ROI;

  • 接着,对这些剩下的RoI进行RoIAlign操做(即先将原图和feature map的pixel对应起来,而后将feature map和固定的feature对应起来);

  • 最后,对这些RoI进行分类(N类别分类)、BB回归和MASK生成(在每个ROI里面进行FCN操做)。
    Mask R-CNN是一个很是灵活的框架,能够增长不一样的分支完成不一样的任务,能够完成目标分类、目标检测、语义分割、实例分割、人体姿式识别等多种任务,以下图所示。

    img
    img

4.1. ROI Align

Mask R-CNN使用RoIAlign取代了Faster RCNN中的RoIPooling,故下文对RoIPooling和RoIAlign进行分析与比较

img
如上图所示,RoI Pooling和RoIAlign最大的区别是:前者使用了两次量化操做,然后者并无采用量化操做,使用了线性插值算法,具体的解释以下所示。
RoI Pooling

img
如上图所示,为了获得固定大小(7X7)的feature map,咱们须要作两次量化操做:1)图像坐标 — feature map坐标,2)feature map坐标 — RoI feature坐标。咱们来讲一下具体的细节,如图咱们输入的是一张800x800的图像,在图像中有两个目标(猫和狗),狗的BB大小为665x665,通过VGG16网络后,咱们能够得到对应的feature map,若是咱们对卷积层进行Padding操做,咱们的图片通过卷积层后保持原来的大小,可是因为池化层的存在,咱们最终得到feature map 会比原图缩小必定的比例,这和Pooling层的个数和大小有关。在该VGG16中,咱们使用了5个池化操做,每一个池化操做都是2x2Pooling,所以咱们最终得到feature map的大小为800/32 x 800/32 = 25x25(是整数),可是将狗的BB对应到feature map上面,咱们获得的结果是665/32 x 665/32 = 20.78 x 20.78,结果是浮点数,含有小数,可是咱们的像素值可没有小数,那么做者就对其进行了量化操做(即取整操做),即其结果变为20 x 20,在这里引入了第一次的量化偏差;然而咱们的feature map中有不一样大小的ROI,可是咱们后面的网络却要求咱们有固定的输入,所以,咱们须要将不一样大小的ROI转化为固定的ROI feature,在这里使用的是7x7的ROI feature,那么咱们须要将20 x 20的ROI映射成7 x 7的ROI feature,其结果是 20 /7 x 20/7 = 2.86 x 2.86,一样是浮点数,含有小数点,咱们采起一样的操做对其进行取整吧,在这里引入了第二次量化偏差。其实,这里引入的偏差会致使图像中的像素和特征中的像素的误差,即将feature空间的ROI对应到原图上面会出现很大的误差。缘由以下:好比用咱们第二次引入的偏差来分析,原本是2,86,咱们将其量化为2,这期间引入了0.86的偏差,看起来是一个很小的偏差呀,可是你要记得这是在feature空间,咱们的feature空间和图像空间是有比例关系的,在这里是1:32,那么对应到原图上面的差距就是0.86 x 32 = 27.52。这个差距不小吧,这仍是仅仅考虑了第二次的量化偏差。这会大大影响整个检测算法的性能,所以是一个严重的问题。
RoIAlign

img
如上图所示,为了获得为了获得固定大小(7X7)的feature map,RoIAlign技术并无使用量化操做,即咱们不想引入量化偏差,好比665 / 32 = 20.78,咱们就用20.78,不用什么20来替代它,好比20.78 / 7 = 2.97,咱们就用2.97,而不用2来代替它。这就是RoIAlign的初衷。那么咱们如何处理这些浮点数呢,咱们的解决思路是使用“双线性插值”算法。双线性插值是一种比较好的图像缩放算法,它充分的利用了原图中虚拟点(好比20.56这个浮点数,像素位置都是整数值,没有浮点值)四周的四个真实存在的像素值来共同决定目标图中的一个像素值,便可以将20.56这个虚拟的位置点对应的像素值估计出来。以下图所示,蓝色的虚线框表示卷积后得到的feature map,黑色实线框表示ROI feature,最后须要输出的大小是2x2,那么咱们就利用双线性插值来估计这些蓝点(虚拟坐标点,又称双线性插值的网格点)处所对应的像素值,最后获得相应的输出。这些蓝点是2x2Cell中的随机采样的普通点,做者指出,这些采样点的个数和位置不会对性能产生很大的影响,你也能够用其它的方法得到。而后在每个橘红色的区域里面进行max pooling或者average pooling操做,得到最终2x2的输出结果。咱们的整个过程当中没有用到量化操做,没有引入偏差,即原图中的像素和feature map中的像素是彻底对齐的,没有误差,这不只会提升检测的精度,同时也会有利于实例分割。

img

4.2. Mask

下图阐述了Mask R-CNN的Mask branch:


在Mask R-CNN中的RoI Align以后有一个"head"部分,主要做用是将RoI Align的输出维度扩大,这样在预测Mask时会更加精确。在Mask Branch的训练环节,做者没有采用FCN式的SoftmaxLoss,反而是输出了K个Mask预测图(为每个类都输出一张),并采用average binary cross-entropy loss训练,固然在训练Mask branch的时候,输出的K个特征图中,也只是对应ground truth类别的那一个特征图对Mask loss有贡献。
Mask R-CNN的训练损失函数能够描述为:

5. Yolo

以上目标检测模型都是two-stage算法,针对于two-stage目标检测算法广泛存在的运算速度慢的缺点,Yolo创造性的提出了one-stage,也就是将物体分类和物体定位在一个步骤中完成。Yolo直接在输出层回归bounding box的位置和bounding box所属类别,从而实现one-stage。经过这种方式,Yolo可实现45帧每秒的运算速度,彻底能知足实时性要求(达到24帧每秒,人眼就认为是连续的)。整个系统以下图所示。img

主要分为三个部分:卷积层,目标检测层,NMS筛选层

5.1 卷积层

采用Google inceptionV1网络,对应到上图中的第一个阶段,共20层。这一层主要是进行特征提取,从而提升模型泛化能力。但做者对inceptionV1进行了改造,他没有使用inception module结构,而是用一个1x1的卷积,并联一个3x3的卷积来替代。(能够认为只使用了inception module中的一个分支,应该是为了简化网络结构)

5.2 目标检测层

先通过4个卷积层和2个全链接层,最后生成7x7x30的输出。先通过4个卷积层的目的是为了提升模型泛化能力。Yolo将一副448x448的原图分割成了7x7个网格,而后每一个单元格负责去检测那些中心点落在该格子内的目标,以下图所示,能够看到狗这个目标的中心落在左下角一个单元格内,那么该单元格负责预测这个狗。每一个单元格会预测 个边界框(bounding box)以及边界框的置信度(confidence score)。所谓置信度其实包含两个方面,一是这个边界框含有目标的可能性大小,二是这个边界框的准确度。前者记为 ,当该边界框是背景时(即不包含目标),此时 [外链图片转存失败(img-gwKmfXrN-1562678877779)(https://pic1.superbed.cn/item/5d08bb50451253d178de1286.gif)] 。而当该边界框包含目标时, 。边界框的准确度能够用预测框与实际框(ground truth)的IOU(intersection over union,交并比)来表征,记为 [外链图片转存失败(img-WETDar5g-1562678877780)(https://pic.superbed.cn/item/5d08bb66451253d178de1463.gif)] 。所以置信度能够定义为 。不少人可能将Yolo的置信度当作边界框是否含有目标的几率,可是其实它是两个因子的乘积,预测框的准确度也反映在里面。边界框的大小与位置能够用4个值来表征: [外链图片转存失败(img-l1vC1QDp-1562678877781)(https://pic.superbed.cn/item/5d08bb7b451253d178de161b.gif)] ,其中 是边界框的中心坐标,而 是边界框的宽与高。还有一点要注意,中心坐标的预测值 是相对于每一个单元格左上角坐标点的偏移值,而且单位是相对于单元格大小的,单元格的坐标定义如图6所示。而边界框的 预测值是相对于整个图片的宽与高的比例,这样理论上4个元素的大小应该在 范围。这样,每一个边界框的预测值实际上包含5个元素: ,其中前4个表征边界框的大小与位置,而最后一个值是置信度。

img

  1. bounding box坐标: 如上图,7x7网格内的每一个grid(红色框),对应两个大小形状不一样的bounding box(黄色框)。每一个box的位置坐标为(x,y,w,h), x和y表示box中心点坐标,w和h表示box宽度和高度。经过与训练数据集上标定的物体真实坐标(Gx,Gy,Gw,Gh)进行对比训练,能够计算出初始bounding box平移和伸缩获得最终位置的模型。

  2. bounding box置信度confidence:这个置信度只是为了表达box内有无物体的几率,并不表达box内物体是什么。

前言

图片分类任务咱们已经熟悉了,就是算法对其中的对象进行分类。而今天咱们要了解构建神经网络的另外一个问题,即目标检测问题。这意味着,咱们不只要用算法判断图片中是否是一辆汽车, 还要在图片中标记出它的位置, 用边框或红色方框把汽车圈起来, 这就是目标检测问题。 其中“定位”的意思是判断汽车在图片中的具体位置。
img
近几年来,目标检测算法取得了很大的突破。比较流行的算法能够分为两类,一类是基于Region Proposal的R-CNN系算法(R-CNN,Fast R-CNN, Faster R-CNN等),它们是two-stage的,须要先算法产生目标候选框,也就是目标位置,而后再对候选框作分类与回归。而另外一类是Yolo,SSD这类one-stage算法,其仅仅使用一个卷积神经网络CNN直接预测不一样目标的类别与位置。第一类方法是准确度高一些,可是速度慢,可是第二类算法是速度快,可是准确性要低一些。这能够在下图中看到。
img
本文对常见目标检测算法进行简要综述,并最后总结了目标检测算法方向的一些大V方便你们学习查看。

1. R-CNN

目标检测有两个主要任务:物体分类和定位,为了完成这两个任务,R-CNN借鉴了滑动窗口思想, 采用对区域进行识别的方案,具体是:

  1. 输入一张图片,经过指定算法从图片中提取 2000 个类别独立的候选区域(可能目标区域)
  2. 对于每一个候选区域利用卷积神经网络来获取一个特征向量
  3. 对于每一个区域相应的特征向量,利用支持向量机SVM 进行分类,并经过一个bounding box regression调整目标包围框的大小

1.1. 提取候选区域

R-CNN目标检测首先须要获取2000个目标候选区域,可以生成候选区域的方法不少,好比:

  1. objectness
  2. selective search
  3. category-independen object proposals
  4. constrained parametric min-cuts(CPMC)
  5. multi-scale combinatorial grouping
  6. Ciresan
    R-CNN 采用的是 Selective Search 算法。简单来讲就是经过一些传统图像处理方法将图像分红不少小尺寸区域,而后根据小尺寸区域的特征合并小尺寸获得大尺寸区域,以实现候选区域的选取。

1.2. 提取特征向量

对于上述获取的候选区域,需进一步使用CNN提取对应的特征向量,做者使用模型AlexNet (2012)。(须要注意的是 Alexnet 的输入图像大小是 227x227,而经过 Selective Search 产生的候选区域大小不一,为了与 Alexnet 兼容,R-CNN 采用了很是暴力的手段,那就是无视候选区域的大小和形状,统一变换到 227x227 的尺寸)。
那么,该网络是如何训练的呢?训练过程以下:

  1. 有监督预训练:训练网络参数
    • 样本:ImageNet
    • 这里只训练和分类有关的参数,由于ImageNet数据只有分类,没有位置标注
    • 图片尺寸调整为227x227
    • 最后一层:4097维向量->1000向量的映射。
  2. 特定样本下的微调 :训练网络参数
    • 样本:
      RCNN样本
    • 采用训练好的AlexNet模型进行PASCAL VOC 2007样本集下的微调,学习率=0.001(PASCAL VOC 2007样本集上既有图像中物体类别标签,也有图像中物体位置标签)
    • mini-batch为32个正样本和96个负样本(因为正样本太少)
    • 修改了原来的1000为类别输出,改成21维【20类+背景】输出。

1.3. SVM分类

经过上述卷积神经网络获取候选区域的特征向量,进一步使用SVM进行物体分类,关键知识点以下:

  1. 使用了一个SVM进行分类:向SVM输入特征向量,输出类别得分
  2. 用于训练多个SVM的数据集是ImageNet数据
  3. 将2000×4096维特征(2000个候选框,每一个候选框得到4096的特征向量)与20个SVM组成的权值矩阵4096×20相乘(20种分类,SVM是二分类器,每一个种类训练一个SVM,则有20个SVM),得到2000×20维矩阵表示每一个建议框是某个物体类别的得分
  4. 分别对上述2000×20维矩阵中每列即每一类进行非极大值抑制剔除重叠建议框,获得该列即该类中得分最高的一些候选框;
    RCNN分类
    SVM训练:
  • 样本:

    RCNN-SVM训练

  • 因为SVM是二分类器,须要为每一个类别训练单独的SVM;

  • SVM训练时,输入正负样本是在AlexNet CNN网络输出的4096维特征向量,输出为该类的得分

  • 因为负样本太多,采用hard negative mining的方法在负样本中选取有表明性的负样本

1.4 边框修正

使用一个回归器进行边框回归:输入为卷积神经网络pool5层的4096维特征向量,输出为x、y方向的缩放和平移,实现边框的修正。在进行测试前仍需回归器进行训练。
回归器训练

  • 样本:

    RCNN边框回归样本
    在2014年R-CNN横空出世的时候,颠覆了以往的目标检测方案,精度大大提高。对于R-CNN的贡献,能够主要分为两个方面:

    1. 使用了卷积神经网络进行特征提取
    2. 使用bounding box regression进行目标包围框的修正
      可是,咱们来看一下,R-CNN有什么问题:
    3. 耗时的selective search,对一张图像,须要花费2s
    4. 耗时的串行式CNN前向传播,对于每个候选框,都需通过一个AlexNet提取特征,为全部的候选框提取特征大约花费47s
    5. 三个模块(CNN特征提取、SVM分类和边框修正)是分别训练的,而且在训练的时候,对于存储空间的消耗很大

2. Fast R-CNN

面对R-CNN的缺陷,Ross在2015年提出的Fast R-CNN进行了改进,下面咱们来概述一下Fast R-CNN的解决方案:

img

  1. 首先仍是采用selective search提取2000个候选框RoI
  2. 使用一个卷积神经网络对全图进行特征提取
  3. 使用一个RoI Pooling Layer在全图特征上摘取每个RoI对应的特征
  4. 分别通过为21和84维的全链接层(并列的,前者是分类输出,后者是回归输出)
    Fast R-CNN经过CNN直接获取整张图像的特征图,再使用RoI Pooling Layer在特征图上获取对应每一个候选框的特征,避免了R-CNN中的对每一个候选框串行进行卷积(耗时较长)。

2.1 RoI Pooling Layer

对于每一个RoI而言,须要从共享卷积层获取的特征图上提取对应的特征,而且送入全链接层进行分类。所以,RoI Pooling主要作了两件事,第一件是为每一个RoI选取对应的特征,第二件事是为了知足全链接层的输入需求,将每一个RoI对应的特征的维度转化成某个定值。RoI Pooling示意图以下所示:ROI-POOLING

如上图所示,对于每个RoI,RoI Pooling Layer将其映射到特征图对应位置,获取对应特征。另外,因为每个RoI的尺度各不相同,因此提取出来的特征向量region proposal维度也不尽相同,所以须要某种特殊的技术来作保证输入后续全链接层的特征向量维度相同。ROI Pooling的提出即是为了解决这一问题的。其思路以下:

  • 将region proposal划分为目标H×W大小的分块

  • 对每个分块中作MaxPooling(每一个分块中含有多个网格,每一个分块获取一个特征值)

  • 将全部输出值组合起来便造成固定大小为H×W的feature map

    pooling_sections
    out
    Fast R-CNN的贡献能够主要分为两个方面:

  1. 取代R-CNN的串行特征提取方式,直接采用一个CNN对全图提取特征(这也是为何须要RoI Pooling的缘由)。
  2. 除了selective search,其余部分均可以合在一块儿训练。
    Fast R-CNN也有缺点,体如今耗时的selective search仍是依旧存在。

3. Faster R-CNN

Faster R-CNN 取代selective search,直接经过一个Region Proposal Network (RPN)生成待检测区域,这么作,在生成RoI区域的时候,时间也就从2s缩减到了10ms。下图是Faster R-CNN总体结构。

img
由上图可知,Faster R-CNN由共享卷积层、RPN、RoI pooling以及分类和回归四部分组成:

  1. 首先使用共享卷积层为全图提取特征feature maps
  2. 将获得的feature maps送入RPN,RPN生成待检测框(指定RoI的位置),并对RoI的包围框进行第一次修正
  3. RoI Pooling Layer根据RPN的输出在feature map上面选取每一个RoI对应的特征,并将维度置为定值
  4. 使用全链接层(FC Layer)对框进行分类,而且进行目标包围框的第二次修正。
    尤为注意的是,Faster R-CNN真正实现了端到端的训练(end-to-end training)。Faster R-CNN最大特点是使用了RPN取代了SS算法来获取RoI,如下对RPN进行分析。

3.1 RPN

经典的检测方法生成检测框都很是耗时,如OpenCV adaboost使用滑动窗口+图像金字塔生成检测框;或如R-CNN使用SS(Selective Search)方法生成检测框。而Faster R-CNN则抛弃了传统的滑动窗口和SS方法,直接使用RPN生成检测框,这也是Faster R-CNN的巨大优点,能极大提高检测框的生成速度。
首先来看看RPN的工做原理:

img
上图展现了RPN网络的具体结构。能够看到RPN网络实际分为2条支线,上面一条支线经过softmax来分类anchors得到前景foreground和背景background(检测目标是foreground),下面一条支线用于计算anchors的边框偏移量,以得到精确的proposals。而最后的proposal层则负责综合foreground anchors和偏移量获取proposals,同时剔除过小和超出边界的proposals。其实整个网络到了Proposal Layer这里,就完成了至关于目标定位的功能。
anchor:
简单地说,RPN依靠一个在共享特征图上滑动的窗口,为每一个位置生成9种预先设置好长宽比与面积的目标框(即anchor)。这9种初始anchor包含三种面积(128×128,256×256,512×512),每种面积又包含三种长宽比(1:1,1:2,2:1)。示意图以下所示:

img
因为共享特征图的大小约为40×60,因此RPN生成的初始anchor的总数约为20000个(40×60×9)。其实RPN最终就是在原图尺度上,设置了密密麻麻的候选anchor。进而去判断anchor究竟是前景仍是背景,意思就是判断这个anchor到底有没有覆盖目标,以及为属于前景的anchor进行第一次坐标修正。

img
判断前景或背景:
对于全部的anchors,首先须要判断anchor是是否为前景。对于第一个问题,RPN的作法是使用SoftmaxLoss直接训练,在训练的时候排除掉了超越图像边界的anchor;
边框修正:
如图绿色表示的是飞机的实际框标签(ground truth),红色的表示的其中一个候选区域(foreground anchor),即被分类器识别为飞机的区域,可是因为红色区域定位不许确,这张图至关于没有正确检测出飞机,因此咱们但愿采用一种方法对红色的框进行微调,使得候选区域和实际框更加接近:

img
对于目标框通常使用四维向量来表示(x,y,w,h)(x,y,w,h) ,分别表示目标框的中心点坐标、宽、高,咱们使用AA 表示原始的foreground anchor,使用GG 表示目标的ground truth,咱们的目标是寻找一种关系,使得输入原始的Anchor AA 通过映射到一个和真实框GG 更接近的回归窗口G′G′ ,即:

  • 给定:

  • 寻找一种变换FF ,使得



    img
    那么如何去计算F 呢?这里咱们能够经过平移和缩放实现

  • 平移:

  • 缩放:


    上面公式中,咱们须要学习四个参数,分别是


    其中


    表示的两个框中心距离的偏移量
    当输入的anchor A与G相差较小时,能够认为这种变换是一种线性变换, 那么就能够用线性回归来建模对目标框进行微调(注意,只有当anchors A和G比较接近时,才能使用线性回归模型,不然就是复杂的非线性问题了)。
    接下来就是如何经过线性回归得到


    线性回归就是给定输入的特征向量X ,学习一组参数W,使得线性回归的输出WX和真实值Y 的差很小。对于该问题,输入X是特征图,咱们使用ϕ 表示,同时训练时还须要A到G变换的真实参数值:


    输出是


    那么目标函数能够表示为:


    其中ϕ(A) 是对应anchor的特征图组成的特征向量,ww 是须要学习的参数,d(A) 是获得预测值(表示x*,y,w,*h,也就是每个变换对应一个上述目标函数),为了让预测值和真实值差距最小,代价函数以下:


    函数优化目标为:


    须要说明,只有在G和A比较接近时,才可近似认为上述线性变换成立,下面对于原文中,A与G之间的平移参数和尺度因子为:


    在获得每个候选区域anchor A的修正参数以后,咱们就能够计算出精确的anchor,而后按照物体的区域得分从大到小对获得的anchor排序,而后提出一些宽或者高很小的anchor(获取其它过滤条件),再通过非极大值抑制抑制,取前Top-N的anchors,而后做为proposals(候选框)输出,送入到RoI Pooling层。
    那么,RPN怎么实现呢?这个问题经过RPN的本质很好求解,RPN的本质是一个树状结构,树干是一个3×3的卷积层,树枝是两个1×1的卷积层,第一个1×1的卷积层解决了先后景的输出,第二个1×1的卷积层解决了边框修正的输出。来看看在代码中是怎么作的:



    从如上代码中能够看到,对于RPN输出的特征图中的每个点,一个1×1的卷积层输出了18个值,由于是每个点对应9个anchor,每一个anchor有一个前景分数和一个背景分数,因此9×2=18。另外一个1×1的卷积层输出了36个值,由于是每个点对应9个anchor,每一个anchor对应了4个修正坐标的值,因此9×4=36。那么,要获得这些值,RPN网络须要训练。在训练的时候,就须要对应的标签。那么,如何断定一个anchor是前景仍是背景呢?文中作出了以下定义:若是一个anchor与ground truth的IoU在0.7以上,那这个anchor就算前景(positive)。相似地,若是这个anchor与ground truth的IoU在0.3如下,那么这个anchor就算背景(negative)。在做者进行RPN网络训练的时候,只使用了上述两类anchor,与ground truth的IoU介于0.3和0.7的anchor没有使用。在训练anchor属于前景与背景的时候,是在一张图中,随机抽取了128个前景anchor与128个背景anchor。

3.3. 分类和定位

Faster R-CNN中的RoI Pooling Layer与 Fast R-CNN中原理同样。在RoI Pooling Layer以后,就是Faster R-CNN的分类器和RoI边框修正训练。分类器主要是分这个提取的RoI具体是什么类别(人,车,马等),一共C+1类(包含一类背景)。RoI边框修正和RPN中的anchor边框修正原理同样,一样也是SmoothL1 Loss,值得注意的是,RoI边框修正也是对于非背景的RoI进行修正,对于类别标签为背景的RoI,则不进行RoI边框修正的参数训练。对于分类器和RoI边框修正的训练,能够损失函数描述以下:


上式中u>=1表示RoI边框修正是对于非背景的RoI而言的,实验中,上式的λ取1。
在训练分类器和RoI边框修正时,步骤以下所示:

  1. 首先经过RPN生成约20000个anchor(40×60×9)。
  2. 对20000个anchor进行第一次边框修正,获得修订边框后的proposal。
  3. 对超过图像边界的proposal的边进行clip,使得该proposal不超过图像范围。
  4. 忽略掉长或者宽过小的proposal。
  5. 将全部proposal按照前景分数从高到低排序,选取前12000个proposal。
  6. 使用阈值为0.7的NMS算法排除掉重叠的proposal。
  7. 针对上一步剩下的proposal,选取前2000个proposal进行分类和第二次边框修正。
    总的来讲,Faster R-CNN的loss分两大块,第一大块是训练RPN的loss(包含一个SoftmaxLoss和SmoothL1Loss),第二大块是训练Faster R-CNN中分类器的loss(包含一个SoftmaxLoss和SmoothL1Loss),Faster R-CNN的总的loss函数描述以下:

4. Mask R-CNN

Mask R-CNN能够分解为以下的3个模块:Faster-RCNN、RoI Align和Mask。算法框架以下:

img
图6 Mask R-CNN算法框架
算法步骤:

  • 首先,输入一幅你想处理的图片,而后进行对应的预处理操做,或者预处理后的图片;

  • 而后,将其输入到一个预训练好的神经网络中(ResNeXt等)得到对应的feature map;

  • 接着,对这个feature map中的每一点设定预约个的RoI,从而得到多个候选RoI;

  • 接着,将这些候选的RoI送入RPN网络进行二值分类(前景或背景)和BB回归,过滤掉一部分候选的ROI;

  • 接着,对这些剩下的RoI进行RoIAlign操做(即先将原图和feature map的pixel对应起来,而后将feature map和固定的feature对应起来);

  • 最后,对这些RoI进行分类(N类别分类)、BB回归和MASK生成(在每个ROI里面进行FCN操做)。
    Mask R-CNN是一个很是灵活的框架,能够增长不一样的分支完成不一样的任务,能够完成目标分类、目标检测、语义分割、实例分割、人体姿式识别等多种任务,以下图所示。

    img
    img

4.1. ROI Align

Mask R-CNN使用RoIAlign取代了Faster RCNN中的RoIPooling,故下文对RoIPooling和RoIAlign进行分析与比较

img
如上图所示,RoI Pooling和RoIAlign最大的区别是:前者使用了两次量化操做,然后者并无采用量化操做,使用了线性插值算法,具体的解释以下所示。
RoI Pooling

img
如上图所示,为了获得固定大小(7X7)的feature map,咱们须要作两次量化操做:1)图像坐标 — feature map坐标,2)feature map坐标 — RoI feature坐标。咱们来讲一下具体的细节,如图咱们输入的是一张800x800的图像,在图像中有两个目标(猫和狗),狗的BB大小为665x665,通过VGG16网络后,咱们能够得到对应的feature map,若是咱们对卷积层进行Padding操做,咱们的图片通过卷积层后保持原来的大小,可是因为池化层的存在,咱们最终得到feature map 会比原图缩小必定的比例,这和Pooling层的个数和大小有关。在该VGG16中,咱们使用了5个池化操做,每一个池化操做都是2x2Pooling,所以咱们最终得到feature map的大小为800/32 x 800/32 = 25x25(是整数),可是将狗的BB对应到feature map上面,咱们获得的结果是665/32 x 665/32 = 20.78 x 20.78,结果是浮点数,含有小数,可是咱们的像素值可没有小数,那么做者就对其进行了量化操做(即取整操做),即其结果变为20 x 20,在这里引入了第一次的量化偏差;然而咱们的feature map中有不一样大小的ROI,可是咱们后面的网络却要求咱们有固定的输入,所以,咱们须要将不一样大小的ROI转化为固定的ROI feature,在这里使用的是7x7的ROI feature,那么咱们须要将20 x 20的ROI映射成7 x 7的ROI feature,其结果是 20 /7 x 20/7 = 2.86 x 2.86,一样是浮点数,含有小数点,咱们采起一样的操做对其进行取整吧,在这里引入了第二次量化偏差。其实,这里引入的偏差会致使图像中的像素和特征中的像素的误差,即将feature空间的ROI对应到原图上面会出现很大的误差。缘由以下:好比用咱们第二次引入的偏差来分析,原本是2,86,咱们将其量化为2,这期间引入了0.86的偏差,看起来是一个很小的偏差呀,可是你要记得这是在feature空间,咱们的feature空间和图像空间是有比例关系的,在这里是1:32,那么对应到原图上面的差距就是0.86 x 32 = 27.52。这个差距不小吧,这仍是仅仅考虑了第二次的量化偏差。这会大大影响整个检测算法的性能,所以是一个严重的问题。
RoIAlign

img
如上图所示,为了获得为了获得固定大小(7X7)的feature map,RoIAlign技术并无使用量化操做,即咱们不想引入量化偏差,好比665 / 32 = 20.78,咱们就用20.78,不用什么20来替代它,好比20.78 / 7 = 2.97,咱们就用2.97,而不用2来代替它。这就是RoIAlign的初衷。那么咱们如何处理这些浮点数呢,咱们的解决思路是使用“双线性插值”算法。双线性插值是一种比较好的图像缩放算法,它充分的利用了原图中虚拟点(好比20.56这个浮点数,像素位置都是整数值,没有浮点值)四周的四个真实存在的像素值来共同决定目标图中的一个像素值,便可以将20.56这个虚拟的位置点对应的像素值估计出来。以下图所示,蓝色的虚线框表示卷积后得到的feature map,黑色实线框表示ROI feature,最后须要输出的大小是2x2,那么咱们就利用双线性插值来估计这些蓝点(虚拟坐标点,又称双线性插值的网格点)处所对应的像素值,最后获得相应的输出。这些蓝点是2x2Cell中的随机采样的普通点,做者指出,这些采样点的个数和位置不会对性能产生很大的影响,你也能够用其它的方法得到。而后在每个橘红色的区域里面进行max pooling或者average pooling操做,得到最终2x2的输出结果。咱们的整个过程当中没有用到量化操做,没有引入偏差,即原图中的像素和feature map中的像素是彻底对齐的,没有误差,这不只会提升检测的精度,同时也会有利于实例分割。

img

4.2. Mask

下图阐述了Mask R-CNN的Mask branch:


在Mask R-CNN中的RoI Align以后有一个"head"部分,主要做用是将RoI Align的输出维度扩大,这样在预测Mask时会更加精确。在Mask Branch的训练环节,做者没有采用FCN式的SoftmaxLoss,反而是输出了K个Mask预测图(为每个类都输出一张),并采用average binary cross-entropy loss训练,固然在训练Mask branch的时候,输出的K个特征图中,也只是对应ground truth类别的那一个特征图对Mask loss有贡献。
Mask R-CNN的训练损失函数能够描述为:

5. Yolo

以上目标检测模型都是two-stage算法,针对于two-stage目标检测算法广泛存在的运算速度慢的缺点,Yolo创造性的提出了one-stage,也就是将物体分类和物体定位在一个步骤中完成。Yolo直接在输出层回归bounding box的位置和bounding box所属类别,从而实现one-stage。经过这种方式,Yolo可实现45帧每秒的运算速度,彻底能知足实时性要求(达到24帧每秒,人眼就认为是连续的)。整个系统以下图所示。img


主要分为三个部分:卷积层,目标检测层,NMS筛选层

5.1 卷积层

采用Google inceptionV1网络,对应到上图中的第一个阶段,共20层。这一层主要是进行特征提取,从而提升模型泛化能力。但做者对inceptionV1进行了改造,他没有使用inception module结构,而是用一个1x1的卷积,并联一个3x3的卷积来替代。(能够认为只使用了inception module中的一个分支,应该是为了简化网络结构)

5.2 目标检测层

先通过4个卷积层和2个全链接层,最后生成7x7x30的输出。先通过4个卷积层的目的是为了提升模型泛化能力。Yolo将一副448x448的原图分割成了7x7个网格,而后每一个单元格负责去检测那些中心点落在该格子内的目标,以下图所示,能够看到狗这个目标的中心落在左下角一个单元格内,那么该单元格负责预测这个狗。每一个单元格会预测 个边界框(bounding box)以及边界框的置信度(confidence score)。所谓置信度其实包含两个方面,一是这个边界框含有目标的可能性大小,二是这个边界框的准确度。前者记为 ,当该边界框是背景时(即不包含目标),此时 。而当该边界框包含目标时, 。边界框的准确度能够用预测框与实际框(ground truth)的IOU(intersection over union,交并比)来表征,记为 。所以置信度能够定义为 。不少人可能将Yolo的置信度当作边界框是否含有目标的几率,可是其实它是两个因子的乘积,预测框的准确度也反映在里面。边界框的大小与位置能够用4个值来表征: ,其中 是边界框的中心坐标,而 是边界框的宽与高。还有一点要注意,中心坐标的预测值 是相对于每一个单元格左上角坐标点的偏移值,而且单位是相对于单元格大小的,单元格的坐标定义如图6所示。而边界框的 预测值是相对于整个图片的宽与高的比例,这样理论上4个元素的大小应该在 范围。这样,每一个边界框的预测值实际上包含5个元素: ,其中前4个表征边界框的大小与位置,而最后一个值是置信度。

img

  1. bounding box坐标: 如上图,7x7网格内的每一个grid(红色框),对应两个大小形状不一样的bounding box(黄色框)。每一个box的位置坐标为(x,y,w,h), x和y表示box中心点坐标,w和h表示box宽度和高度。经过与训练数据集上标定的物体真实坐标(Gx,Gy,Gw,Gh)进行对比训练,能够计算出初始bounding box平移和伸缩获得最终位置的模型。

  2. bounding box置信度confidence:这个置信度只是为了表达box内有无物体的几率,并不表达box内物体是什么。


    其中前一项表示有无人工标记的物体落入了网格内,若是有则为1,不然为0。第二项表明bounding box和真实标记的box之间的重合度。它等于两个box面积交集,除以面积并集。值越大则box越接近真实位置。
    每一个网格还须要预测它属于20分类中每个类别的几率。分类信息是针对每一个网格的,而不是bounding box。故只须要20个,而不是40个。而confidence则是针对bounding box的,它只表示box内是否有物体,而不须要预测物体是20分类中的哪个,故只须要2个参数。虽然分类信息和confidence都是几率,但表达含义彻底不一样。

5.3 NMS筛选层

筛选层是为了在多个结果中(多个bounding box)筛选出最合适的几个,这个方法和faster R-CNN 中基本相同。都是先过滤掉score低于阈值的box,对剩下的box进行NMS非极大值抑制,去除掉重叠度比较高的box(NMS具体算法能够回顾上面faster R-CNN小节)。这样就获得了最终的最合适的几个box和他们的类别。

5.4 Yolo损失函数

yolo的损失函数包含三部分,位置偏差,confidence偏差,分类偏差。具体公式以下

img
偏差均采用了均方差算法,其实我认为,位置偏差应该采用均方差算法,而分类偏差应该采用交叉熵。因为物体位置只有4个参数,而类别有20个参数,他们的累加和不一样。若是赋予相同的权重,显然不合理。故Yolo中位置偏差权重为5,类别偏差权重为1。因为咱们不是特别关心不包含物体的bounding box,故赋予不包含物体的box的置信度confidence偏差的权重为0.5,包含物体的权重则为1。
Yolo算法开创了one-stage检测的先河,它将物体分类和物体检测网络合二为一,都在全链接层完成。故它大大下降了目标检测的耗时,提升了实时性。但它的缺点也十分明显

  1. 每一个网格只对应两个bounding box,当物体的长宽比不常见(也就是训练数据集覆盖不到时),效果不好。
  2. 原始图片只划分为7x7的网格,当两个物体靠的很近时,效果不好
  3. 最终每一个网格只对应一个类别,容易出现漏检(物体没有被识别到)。
  4. 对于图片中比较小的物体,效果不好。这实际上是全部目标检测算法的通病,SSD对它有些优化,咱们后面再看。

6. SSD

Faster R-CNN准确率mAP较高,漏检率recall较低,但速度较慢。而Yolo则相反,速度快,但准确率和漏检率不尽人意。SSD综合了他们的优缺点,对输入300x300的图像,在voc2007数据集上test,可以达到58 帧每秒( Titan X 的 GPU ),72.1%的mAP。
SSD和Yolo同样都是采用一个CNN网络来进行检测,可是却采用了多尺度的特征图,SSD网络结构以下图:

img
和Yolo同样,也分为三部分:卷积层,目标检测层和NMS筛选层

6.1 卷积层

SSD论文采用了VGG16的基础网络,其实这也是几乎全部目标检测神经网络的惯用方法。先用一个CNN网络来提取特征,而后再进行后续的目标定位和目标分类识别。

6.2 目标检测层

这一层由5个卷积层和一个平均池化层组成。去掉了最后的全链接层。SSD认为目标检测中的物体,只与周围信息相关,它的感觉野不是全局的,故不必也不该该作全链接。SSD的特色以下:

6.2.1 多尺寸feature map上进行目标检测

每个卷积层,都会输出不一样大小感觉野的feature map。在这些不一样尺度的feature map上,进行目标位置和类别的训练和预测,从而达到多尺度检测的目的,能够克服yolo对于宽高比不常见的物体,识别准确率较低的问题。而yolo中,只在最后一个卷积层上作目标位置和类别的训练和预测。这是SSD相对于yolo能提升准确率的一个关键所在。

img
如上所示,在每一个卷积层上都会进行目标检测和分类,最后由NMS进行筛选,输出最终的结果。多尺度feature map上作目标检测,就至关于多了不少宽高比例的bounding box,能够大大提升泛化能力。

6.2.2 设置先验框

在Yolo中,每一个单元预测多个边界框,可是其都是相对这个单元自己(正方块),可是真实目标的形状是多变的,Yolo须要在训练过程当中自适应目标的形状。而SSD和Faster R-CNN类似,也提出了anchor的概念。卷积输出的feature map,每一个点对应为原图的一个区域的中心点。以这个点为中心,构造出6个宽高比例不一样,大小不一样的anchor(SSD中称为default box)。每一个anchor对应4个位置参数(x,y,w,h)和21个类别几率(voc训练集为20分类问题,在加上anchor是否为背景,共21分类)。

img
SSD的检测值也与Yolo不太同样。对于每一个单元的每一个先验框,其都输出一套独立的检测值,对应一个边界框,主要分为两个部分。第一部分是各个类别的置信度或者评分,值得注意的是SSD将背景也当作了一个特殊的类别,若是检测目标共有 个类别,SSD其实须要预测 个置信度值,其中第一个置信度指的是不含目标或者属于背景的评分。后面当咱们说 个类别置信度时,请记住里面包含背景那个特殊的类别,即真实的检测类别只有 个。在预测过程当中,置信度最高的那个类别就是边界框所属的类别,特别地,当第一个置信度值最高时,表示边界框中并不包含目标。第二部分就是边界框的location,包含4个值 ,分别表示边界框的中心坐标以及宽高。可是真实预测值其实只是边界框相对于先验框的转换值(paper里面说是offset,可是以为transformation更合适,参见R-CNN(https://arxiv.org/abs/1311.2524)
另外,SSD采用了数据加强。生成与目标物体真实box间IOU为0.1 0.3 0.5 0.7 0.9的patch,随机选取这些patch参与训练,并对他们进行随机水平翻转等操做。SSD认为这个策略提升了8.8%的准确率。

6.3 筛选层

和yolo的筛选层基本一致,一样先过滤掉类别几率低于阈值的default box,再采用NMS非极大值抑制,筛掉重叠度较高的。只不过SSD综合了各个不一样feature map上的目标检测输出的default box。

7 其余模型

针对Yolo准确率不高,容易漏检,对长宽比不常见物体效果差等问题,结合SSD的特色,提出了YoloV2。它主要仍是采用了Yolo的网络结构,在其基础上作了一些优化和改进,以下:

  1. 网络采用DarkNet-19:19层,里面包含了大量3x3卷积,同时借鉴inceptionV1,加入1x1卷积核全局平均池化层。结构以下

    img

  2. 去掉全链接层:和SSD同样,模型中只包含卷积和平均池化层(平均池化是为了变为一维向量,作softmax分类)。这样作一方面是因为物体检测中的目标,只是图片中的一个区块,它是局部感觉野,不必作全链接。而是为了输入不一样尺寸的图片,若是采用全链接,则只能输入固定大小图片了。

  3. batch normalization:卷积层后加入BN,对下一次卷积输入的数据作归一化。能够在增大学习率的前提下,一样能够稳定落入局部最优解。从而加速训练收敛,在相同耗时下,增大了有效迭代次数。

  4. 使用anchors:借鉴faster R-CNN和SSD,对于一个中心点,使用多个anchor,获得多个bounding box,每一个bounding box包含4个位置坐标参数(x y w h)和21个类别几率信息。而在Yolo中,每一个grid(对应anchor),仅预测一次类别,并且只有两个bounding box来进行坐标预测。

  5. pass through layer:Yolo本来最终特征图为13x13x256。YoloV2还利用了以前的26x26的特征图进行目标检测。26x26x256的feature map分别按行和列隔点采样,获得4幅13x13x256的feature map,将他们组织成一幅13x13x2048的feature map。这样作的目的是提升小物体的识别率。由于越靠前的卷积,其感觉野越小,越有利于小物体的识别。

  6. 高分辨率输入Training:Yolo采用224x224图片进行预训练,而YoloV2则采用448x448

  7. Multi-Scale Training:输入不一样尺寸的图片,迭代10次,就改变输入图片尺寸。因为模型中去掉了全链接层,故能够输入不一样尺寸的图片了。从320x320,到608x608
    Yolo和YoloV2只能识别20类物体,为了优化这个问题,提出了Yolo9000,能够识别9000类物体。它在YoloV2基础上,进行了imageNet和coco的联合训练。这种方式充分利用imageNet能够识别1000类物体和coco能够进行目标位置检测的优势。当使用imageNet训练时,只更新物体分类相关的参数。而使用coco时,则更新所有全部参数。

参考大V:

知乎:

推荐阅读

如何从零开始系统化学习视觉SLAM?
从零开始一块儿学习SLAM | 为何要学SLAM?
从零开始一块儿学习SLAM | 学习SLAM到底须要学什么?
从零开始一块儿学习SLAM | SLAM有什么用?
从零开始一块儿学习SLAM | C++新特性要不要学?
从零开始一块儿学习SLAM | 为何要用齐次坐标?
从零开始一块儿学习SLAM | 三维空间刚体的旋转
从零开始一块儿学习SLAM | 为啥须要李群与李代数?
从零开始一块儿学习SLAM | 相机成像模型
从零开始一块儿学习SLAM | 不推公式,如何真正理解对极约束?
从零开始一块儿学习SLAM | 神奇的单应矩阵
从零开始一块儿学习SLAM | 你好,点云
从零开始一块儿学习SLAM | 给点云加个滤网
从零开始一块儿学习SLAM | 点云平滑法线估计
从零开始一块儿学习SLAM | 点云到网格的进化
从零开始一块儿学习SLAM | 理解图优化,一步步带你看懂g2o代码
从零开始一块儿学习SLAM | 掌握g2o顶点编程套路
从零开始一块儿学习SLAM | 掌握g2o边的代码套路
零基础小白,如何入门计算机视觉?
SLAM领域牛人、牛实验室、牛研究成果梳理
我用MATLAB撸了一个2D LiDAR SLAM
可视化理解四元数,愿你再也不掉头发
最近一年语义SLAM有哪些表明性工做?
视觉SLAM技术综述
汇总 | VIO、激光SLAM相关论文分类集锦
研究SLAM,对编程的要求有多高?
2018年SLAM、三维视觉方向求职经验分享
2018年SLAM、三维视觉方向求职经验分享
深度学习遇到SLAM | 如何评价基于深度学习的DeepVO,VINet,VidLoc?
视觉SLAM关键方法总结
SLAM方向公众号、知乎、博客上有哪些大V能够关注?
SLAM实验室
SLAM方向国内有哪些优秀公司?
SLAM面试常见问题
SLAM相关领域数据集调研
从零开始一块儿学习SALM-ICP原理及应用
解放双手——相机与IMU外参的在线标定