精华内容
参与话题
问答
  • 目标检测(Object Detection)入门概要

    万次阅读 多人点赞 2018-07-12 11:10:32
    Objection Detection Tasks Methods Algorithms Region Proposal Selective Search EdgeBoxes R-CNN ...Fast R-CNN ...本文首先介绍目标检测的任务,然后介绍主流的目标检测算法或框架,重点为Faster...


    本文首先介绍目标检测的任务,然后介绍主流的目标检测算法或框架,重点为Faster R-CNN,SSD,YOLO三个检测框架。本文内容主要整理自网络博客,用于普及性了解

    ps:由于之后可能会有一系列对象检测的论文阅读笔记,在论文阅读之前,先大致了解一下目前的研究现状,目标检测的各种主流方法的大致原理,以助于后面能更顺畅看懂论文,后续再通过论文阅读进行细节学习。由于尚未阅读相关论文原文,若有问题,欢迎指出!先献上一个RCNN系列的图(来自知乎:iker peng)。

    这里写图片描述


    Objection Detection Tasks

    目前计算机视觉(CV,computer vision)与自然语言处理(Natural Language Process, NLP)及语音识别(Speech Recognition)并列为人工智能(AI,artificial intelligence)·机器学习(ML,machine learning)·深度学习(DL,deep learning)方向的三大热点方向 。

    而计算机视觉又有四个基本任务(关于这个任务,说法不一,比如有些地方说到对象检测detection、对象追踪tracking、对象分割segmentation,不用拘泥),即图像分类,对象定位及检测,语义分割,实例分割。图示如下:

    • a)图像分类:一张图像中是否包含某种物体
    • b)物体检测识别:若细分该任务可得到两个子任务,即目标检测,与目标识别,首先检测是视觉感知得第一步,它尽可能搜索出图像中某一块存在目标(形状、位置)。而目标识别类似于图像分类,用于判决当前找到得图像块得目标具体是什么类别。
    • c)语义分割:按对象得内容进行图像得分割,分割的依据是内容,即对象类别。
    • d)实例分割:按对象个体进行分割,分割的依据是单个目标。

    这里写图片描述
    这里写图片描述

    不管什么任务,目标检测应该是计算机视觉领域首先需要掌握的


    Methods

    传统的计算机视觉问题的解决思路:图像——预处理——人工特征(hand-crafted features)提取——分类。大部分研究集中在人工特征的构造和分类算法上,涌现了很多杰出的工作。但存在的问题是人工设计的特征可能适用性并不强,或者说泛化能力较弱,一类特征可能针对某类问题比较好,其他问题就效果甚微。

    目前主流的深度学习解决思路:通过深度学习算法,进行端到端的解决,即输入图像到输出任务结果一步完成。但其实内部它还是分stages的,通常是图像——特征提取网络——分类、回归。

    这里特征提取网络即各种深度神经网络结构,针对这一算法的研究很多,比如说各层的设计细节(激活函数,损失函数,网络结构等)、可视化等,为了能提取更加强壮有效的特征,研究者考虑各种问题,如尺度不变性问题(通常用于解决小目标的检测,如特征金字塔网络,Feature Pyramid Network,FPN),整个网络其实是分作两类的,前N个层为第一部分,用于特征的提取,输入的图片,输出的是特征图,这与传统的人工特征提取本质上没有太大区别,只是提取特征的算法变成了神经网络算法。而网络的后K层是作为第二部分,完成具体的分类或者回归任务,任务的输入是前一个部分得到的特征图,输出是任务的结果。所以显然后一部分其实是可以被替代的,也确实有很多框架的第二部分采用其他机器学习的算法替代,如SVM。

    所以需要对自己有个认识!是做算法的研究(通常深度学习就是研究神经网络算法,如何让它特征提取更强大、分类更准确、速度更快,从网络结构、loss function、activation function等入手,需要强大的数学理论)?还是解决某个具体的问题(用已有的优秀的神经网络算法,侧重于研究解决问题的框架,当然很多时候需要对已有的算法做些微调)?

    我粗浅的认为前者更纯理论,后者往往以工程为依托。

    针对你的任务,如何设计网络? 当面对你的实际任务时,如果你的目标是解决该任务而不是发明新算法,那么不要试图自己设计全新的网络结构,也不要试图从零复现现有的网络结构。找已经公开的实现和预训练模型进行微调。去掉最后一个全连接层和对应softmax,加上对应你任务的全连接层和softmax,再固定住前面的层,只训练你加的部分。如果你的训练数据比较多,那么可以多微调几层,甚至微调所有层。


    Algorithms

    目标检测的基本思路:同时解决定位(localization) + 检测(detection)。
    多任务学习,带有两个输出分支。一个分支用于做图像分类,即全连接+softmax判断目标类别,和单纯图像分类区别在于这里还另外需要一个“背景”类。另一个分支用于判断目标位置,即完成回归任务输出四个数字标记包围盒位置(例如中心点横纵坐标和包围盒长宽),该分支输出结果只有在分类分支判断不为“背景”时才使用。

    Region Proposal

    为什么要有候选区域?既然目标是在图像中的某一个区域,那么最直接的方法就是滑窗法(sliding window approach),就是遍历图像的所有的区域,用不同大小的窗口在整个图像上滑动,那么就会产生所有的矩形区域,然后再后续排查,思路简单,但开销巨大。

    候选区域生成算法通常基于图像的颜色、纹理、面积、位置等合并相似的像素,最终可以得到一系列的候选矩阵区域。这些算法,如selective searchEdgeBoxes,通常只需要几秒的CPU时间,而且,一个典型的候选区域数目是2k,相比于用滑动窗把图像所有区域都滑动一遍,基于候选区域的方法十分高效。另一方面,这些候选区域生成算法的查准率(precision)一般,但查全率(recall)通常比较高,这使得我们不容易遗漏图像中的目标。


    Segmentation as selective search for object recognition ”,ICCV,2011.

    Selective search for object recognition.” International journal of computer vision ,2013

    论文应该是有两部分内容,一部分是Selective Search的方法寻找候选区域,第二部分为该区域上的特征提取及后续的分类。由于目前特征提取和分类都采用了深度学习方法,所以只是借鉴其候选区寻找算法Selective Search。

    将图像划分成很多的小区域(regions)

    如何将图像划分成很多的小区域? 划分的方式应该有很多种,比如:

    • 1)等间距划分grid cell,这样划分出来的区域每个区域的大小相同,但是每个区域里面包含的像素分布不均匀,随机性大;同时,不能满足目标多尺度的要求(当然,可以用不同的尺度划分grid cell,这称为Exhaustive Search, 计算复杂度太大)!
    • 2)使用边缘保持超像素划分;
    • 3)使用本文提出的Selective Search(SS)的方法来找到最可能的候选区域;

    其实这一步可以看做是对图像的过分割,都是过分割,本文SS方法的过人之处在于预先划分的区域什么大小的都有(满足目标多尺度的要求),而且对过分割的区域还有一个合并的过程(区域的层次聚类),最后剩下的都是那些最可能的候选区域,然后在这些已经过滤了一遍的区域上进行后续的识别等处理,这样的话,将会大大减小候选区域的数目,提供了算法的速度.

    下图说明目标的多尺度:

    这里写图片描述

    总体思路:假设现在图像上有n个预分割的区域,表示为R={R1, R2, …, Rn}, 计算每个region与它相邻region(注意是相邻的区域)的相似度,这样会得到一个n*n的相似度矩阵(同一个区域之间和一个区域与不相邻区域之间的相似度可设为NaN),从矩阵中找出最大相似度值对应的两个区域,将这两个区域合二为一,这时候图像上还剩下n-1个区域; 重复上面的过程(只需要计算新的区域与它相邻区域的新相似度,其他的不用重复计算),重复一次,区域的总数目就少1,知道最后所有的区域都合并称为了同一个区域(即此过程进行了n-1次,区域总数目最后变成了1).算法的流程图如下图所示:

    这里写图片描述

    • step0:生成区域集R,具体参见论文《Efficient Graph-Based Image Segmentation》,基于图的图像分割,也就是说起点还是图像分割
    • step1:计算区域集R里每个相邻区域的相似度S={s1,s2,…}
    • step2:找出相似度最高的两个区域,将其合并为新集,添加进R
    • step3:从S中移除所有与step2中有关的子集
    • step4:计算新集与所有子集的相似度
    • step5:跳至step2,直至S为空

    相似度计算:论文从四个方面考虑相似度度量——颜色、纹理、尺寸和空间交叠


    EdgeBoxes

    Edge Boxes: Locating Object Proposals from Edges ,ECCV2014

    文章没有涉及到“机器学习”,采用的是纯图像的方法。

    研究方法:利用边缘信息(Edge),确定box内的轮廓个数和与box边缘重叠的edge个数(知道一个box内完全包含的轮廓个数,那么目标有很大可能性,就在这个box中),基于此对box进行评分,进一步根据得分的高低顺序确定proposal信息(由大小,长宽比,位置构成)。而后续工作就是在proposal内部运行相关检测算法。

    matlab 代码:https://github.com/pdollar/edges

    建议参考博客:《Edge Boxes: Locating Object Proposals from Edges》读后感 :https://blog.csdn.net/wsj998689aa/article/details/39476551


    R-CNN

    “Rich feature hierarchies for accurate object detection and semantic segmentation.” CVPR 2014

    卷积神经网络进入目标识别的里程碑,R-CNN,直接看图了解其结构!
    这里写图片描述
    这里写图片描述

    流程:原图——Selective Search得到2K Proposal Regions —— Warpped image region(?) —— ConvNet —— 分类(svm) + 回归(bounding box regression)

    这里的Warpped Image Region应该是一种类似resize的操作,将不同大小的proposal region统一到相同的尺寸,用以输入相同的ConvNet,上面的Convnet是相同的,但SVM分类器是针对每一个类别单独训练好的,是不同的分类器。

    R-CNN,是基于这样一种非常简单的想法,对于输入图像,通过selective search方法,先确定出例如2000个最有可能包含物体的窗口,对于这2000个窗口,我们希望它能够对待检测物体达到非常高的召回率。然后对这2000个中的每一个去用CNN进行特征提取和分类。对这2000个区域都要去跑一次CNN,那么它的速度是非常慢的,即使每次只需要0.5秒,2000个窗口的话也是需要1000秒,为了加速2014年的时候何凯明提出了SPP-net,其做法是对整个图跑一次CNN,而不需要每一个窗口单独做,但是这样有一个小困难,就是这2000个候选窗口每一个的大小都不一样,为了解决这个问题,SPP-net设计了spatial pyramid pooling,使得不同大的小窗口具有相同维度的特征。这个方法使得检测时不需要对每一个候选窗口去计算卷积,但是还是不够快,检测一张图像还是需要几秒的时间。

    存在的不足:

    1)多个候选区域对应的图像需要预先提取,占用较大的磁盘空间;

    2)针对传统CNN需要固定尺寸的输入图像,crop/warp(归一化)产生物体截断或拉伸,会导致输入CNN的信息丢失;

    3)每一个ProposalRegion都需要进入CNN网络计算,上千个Region存在大量的范围重叠,重复的特征提取带来巨大的计算浪费。


    SPP-Net

    Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition,ECCV 2014,Kaiming He

    各个Proposal Region大小不一,全图只卷积一次的话,就不需要经过Wrapp,在特征图上找这些Region的时候还是存在大小不一的问题,由于维度不同,后面的全连接层FC的输入无法统一,故采用SPP,空间金字塔池化,这样不同尺寸的Region通过不同金字塔池化层,从而得到统一维度的输出,加速算法同时,兼顾了尺度问题。

    在R-CNN中,要求输入固定大小的图片,因此需要对图片进行crop、wrap变换,改变尺寸引起的形变影响检测效果。此外,对每一个图像中每一个proposal进行一遍CNN前向特征提取,如果是2000个propsal,需要2000次前向CNN特征提取,这无疑将浪费很多时间。

    该论文对R-CNN中存在的缺点进行了改进,基本思想是,输入整张图像,提取出整张图像的特征图,然后利用空间关系从整张图像的特征图中,在spatial pyramid pooling layer提取各个region proposal的特征。

    这里写图片描述

    1)取消了crop/warp图像归一化过程,解决图像变形导致的信息丢失以及存储问题;

    2)采用空间金字塔池化(SpatialPyramid Pooling )替换了 全连接层之前的最后一个池化层(上图top),翠平说这是一个新词,我们先认识一下它。

    SPP主要有两个特点:

    • 结合空间金字塔方法实现CNNs的对尺度输入。
      一般CNN后接全连接层或者分类器,他们都需要固定的输入尺寸,因此不得不对输入数据进行crop或者warp,这些预处理会造成数据的丢失或几何的失真。SPP Net的第一个贡献就是将金字塔思想加入到CNN,实现了数据的多尺度输入。

      如下图所示,在卷积层和全连接层之间加入了SPP layer。此时网络的输入可以是任意尺度的,在SPP layer中每一个pooling的filter会根据输入调整大小,而SPP的输出尺度始终是固定的。

      这里写图片描述

    • 只对原图提取一次卷积特征

      在R-CNN中,每个候选框先resize到统一大小,然后分别作为CNN的输入,这样是很低效的。 所以SPP Net根据这个缺点做了优化:只对原图进行一次卷积得到整张图的feature map,然后找到每个候选框在feature map上的映射patch,将此patch作为每个候选框的卷积特征输入到SPP layer和之后的层。节省了大量的计算时间,比R-CNN有一百倍左右的提速。

      这里写图片描述

    存在的不足:

    1)和RCNN一样,训练过程仍然是隔离的,提取候选框 | 计算CNN特征| SVM分类 | Bounding Box回归独立训练,大量的中间结果需要转存,无法整体训练参数;

    2)SPP-Net在无法同时Tuning在SPP-Layer两边的卷积层和全连接层,很大程度上限制了深度CNN的效果;

    3)在整个过程中,Proposal Region仍然很耗时。


    Fast R-CNN

    “Fast r-cnn.” ICCV 2015. Girshick, Ross.

    R-CNN的进阶版Fast R-CNN就是在RCNN的基础上采纳了SPP Net方法,对RCNN作了改进,使得性能进一步提高。

    Fast R-CNN借鉴了SPP-net的做法,在全图上进行卷积,然后采用ROI-pooling得到定长的特征向量,例如不管窗口大小是多少,转换成7x7这么大。Fast R-CNN还引入了一个重要的策略,在对窗口进行分类的同时,还会对物体的边框进行回归,使得检测框更加准确。前面我们说候选窗口会有非常高的召回率,但是可能框的位置不是很准,例如一个人体框可能是缺胳膊缺腿,那么通过回归就能够对检测框进行校准,在初始的位置上求精。Fast R-CNN把分类和回归放在一起来做,采用了多任务协同学习的方式。

    这里写图片描述

    ROI Pooling(region of interest pooling

    兴趣区域汇合旨在由任意大小的候选区域对应的局部卷积特征提取得到固定大小的特征,这是因为下一步的两分支网络由于有全连接层,需要其输入大小固定。其做法是,先将候选区域投影到卷积特征上,再把对应的卷积特征区域空间上划分成固定数目的网格(数目根据下一步网络希望的输入大小确定,例如VGGNet需要7×7的网格),最后在每个小的网格区域内进行最大汇合,以得到固定大小的汇合结果。和经典最大汇合一致,每个通道的兴趣区域汇合是独立的。
    这里写图片描述


    Faster R-CNN

    Faster R-CNN: Towards Real-Time Object Detection with Region Proposal Networks,NIPS 2015

    这里写图片描述

    之前的Fast R-CNN已经基本实现端到端的检测,而主要的速度瓶颈是在Selective Search算法实现的Region Proposal,故到了Faster R-CNN,主要是解决Region Proposal问题,以实现Real-Time检测。Faster R-CNN的主要思路是,既然检测工作是在卷积的结果Feature Map上做的,那么候选区域的选取是否也能在Feature Map上做?于是RPN网络(Region Proposal Network)应运而生。

    候选框提取不一定要在原图上做,特征图上同样可以,低分辨率特征图意味着更少的计算量,基于这个假设,MSRA的任少卿等人提出RPN(RegionProposal Network),整体架构如下图所示

    这里写图片描述

    通过添加额外的RPN分支网络,将候选框提取合并到深度网络中,这正是Faster-RCNN里程碑式的贡献 !

    RPN引入了所谓anchor box的设计,具体来说,RPN在最后一个卷积层输出的特征图上,先用3x3的卷积得到每个位置的特征向量,然后基于这个特征向量去回归9个不同大小和长宽比的窗口,如果特征图的大小是40x60,那么总共就会有大约2万多个窗口,把这些窗口按照信度进行排序,然后取前300个作为候选窗口,送去做最终的分类 。

    Faster实现了端到端的检测,并且几乎达到了效果上的最优,但小物体的识别还存在问题,故SSD算法诞生;速度方向的改进仍有余地,于是YOLO诞生了。


    SSD

    SSD算法是一种直接预测目标类别和bounding box的多目标检测算法。与faster rcnn相比,该算法没有生成 proposal 的过程,这就极大提高了检测速度。针对不同大小的目标检测,传统的做法是先将图像转换成不同大小(图像金字塔),然后分别检测,最后将结果综合起来(NMS)。而SSD算法则利用不同卷积层的 feature map 进行综合也能达到同样的效果。算法的主网络结构是VGG16,将最后两个全连接层改成卷积层,并随后增加了4个卷积层来构造网络结构。对其中5种不同的卷积层的输出(feature map)分别用两个不同的 3×3 的卷积核进行卷积,一个输出分类用的confidence,每个default box 生成21个类别confidence;一个输出回归用的 localization,每个 default box 生成4个坐标值(x, y, w, h)。此外,这5个feature map还经过 PriorBox 层生成 prior box(生成的是坐标)。上述5个feature map中每一层的default box的数量是给定的(8732个)。最后将前面三个计算结果分别合并然后传给loss层。

    这里写图片描述


    YOLO

    2015年出现了一个名为YOLO的方法,其最终发表在CVPR 2016上。这是一个蛮奇怪的方法,对于给定的输入图像,YOLO不管三七二十一最终都划分出7x7的网格,也就是得到49个窗口,然后在每个窗口中去预测两个矩形框。这个预测是通过全连接层来完成的,YOLO会预测每个矩形框的4个参数和其包含物体的信度,以及其属于每个物体类别的概率。YOLO的速度很快,在GPU上可以达到45fps。

    YOLO的处理步骤为:把输入图片缩放到448×448大小;运行卷积网络;对模型置信度卡阈值,得到目标位置与类别。对VOC数据集来说,YOLO就是把图片统一缩放到448×448,然后每张图平均划分为7×7=49个小格子,每个格子预测2个矩形框及其置信度,以及20种类别的概率。舍弃了Region proposal阶段,加快了速度,但是定位精度比较低,与此同时带来的问题是,分类的精度也比较低。在各类数据集上的平均表现大概为54.5%mAP。


    总结一下RCNN系列算法的步骤:
    这里写图片描述

    RCNN

    1. 在图像中确定约1000-2000个候选框 (使用选择性搜索)
    2. 每个候选框内图像块缩放至相同大小,并输入到CNN内进行特征提取
    3. 对候选框中提取出的特征,使用分类器判别是否属于一个特定类
    4. 对于属于某一特征的候选框,用回归器进一步调整其位置

    Fast RCNN

    1. 在图像中确定约1000-2000个候选框 (使用选择性搜索)
    2. 对整张图片输进CNN,得到feature map
    3. 找到每个候选框在feature map上的映射patch,将此patch作为每个候选框的卷积特征输入到SPP layer和之后的层
    4. 对候选框中提取出的特征,使用分类器判别是否属于一个特定类
    5. 对于属于某一特征的候选框,用回归器进一步调整其位置

    Faster RCNN

    1. 对整张图片输进CNN,得到feature map
    2. 卷积特征输入到RPN,得到候选框的特征信息
    3. 对候选框中提取出的特征,使用分类器判别是否属于一个特定类
    4. 对于属于某一特征的候选框,用回归器进一步调整其位置

    三者比较

    方法 创新 缺点 改进
    R-CNN (Region-based Convolutional Neural Networks) 1、SS提取RP; 2、CNN提取特征; 3、SVM分类; 4、BB盒回归。 1、 训练步骤繁琐(微调网络+训练SVM+训练bbox); 2、 训练、测试均速度慢 ; 3、 训练占空间 1、 从DPM HSC的34.3%直接提升到了66%(mAP); 2、 引入RP+CNN
    Fast R-CNN (Fast Region-based Convolutional Neural Networks) 1、SS提取RP; 2、CNN提取特征; 3、softmax分类; 4、多任务损失函数边框回归。 1、 依旧用SS提取RP(耗时2-3s,特征提取耗时0.32s); 2、 无法满足实时应用,没有真正实现端到端训练测试; 3、 利用了GPU,但是区域建议方法是在CPU上实现的。 1、 由66.9%提升到70%; 2、 每张图像耗时约为3s。
    Faster R-CNN (Fast Region-based Convolutional Neural Networks) 1、RPN提取RP; 2、CNN提取特征; 3、softmax分类; 4、多任务损失函数边框回归。 1、 还是无法达到实时检测目标; 2、 获取region proposal,再对每个proposal分类计算量还是比较大。 1、 提高了检测精度和速度; 2、 真正实现端到端的目标检测框架; 3、 生成建议框仅需约10ms。

    references

    计算机视觉入门系列(一) 综述:https://blog.csdn.net/wangss9566/article/details/54618507
    目标检测–Selective Search for Object Recognition(IJCV, 2013)(https://www.cnblogs.com/zhao441354231/p/5941190.html)
    选择性搜索(selective search)https://blog.csdn.net/guoyunfei20/article/details/78723646
    目标检测-RCNN系列 : https://blog.csdn.net/linolzhang/article/details/54344350
    基于深度学习的目标检测技术演进:R-CNN、Fast R-CNN、Faster R-CNN : https://www.cnblogs.com/skyfsm/p/6806246.html
    基于深度学习的目标检测技术进展与展望:https://zhuanlan.zhihu.com/p/23770994
    深度学习笔记(七)SSD 论文阅读笔记简化 : https://www.cnblogs.com/xuanyuyt/p/7447111.html

    展开全文
  • 干货 | 目标检测入门,看这篇就够了(上)

    千次阅读 多人点赞 2018-03-16 00:00:00
    作者 | 李家丞( 同济大学数学系本科在读,现格灵深瞳算法部实习生)近年来,深度学习模型逐渐取代传统机器视觉方法而成为目标检测领域的主流算法,本系列文章将回顾早期的经典工作,并对较新的趋势做一个全景式的...
        

    640?wx_fmt=jpeg&wxfrom=5&wx_lazy=1


    作者 | 李家丞( 同济大学数学系本科在读,现格灵深瞳算法部实习生)


    近年来,深度学习模型逐渐取代传统机器视觉方法而成为目标检测领域的主流算法,本系列文章将回顾早期的经典工作,并对较新的趋势做一个全景式的介绍,帮助读者对这一领域建立基本的认识。(营长注:因本文篇幅较长,营长将其分为上、下两部分。)


    导言:目标检测的任务表述


    如何从图像中解析出可供计算机理解的信息,是机器视觉的中心问题。深度学习模型由于其强大的表示能力,加之数据量的积累和计算力的进步,成为机器视觉的热点研究方向。


    那么,如何理解一张图片?根据后续任务的需要,有三个主要的层次。


    640?wx_fmt=jpeg

    图像理解的三个层次


    一是分类(Classification),即是将图像结构化为某一类别的信息,用事先确定好的类别(string)或实例ID来描述图片。这一任务是最简单、最基础的图像理解任务,也是深度学习模型最先取得突破和实现大规模应用的任务。其中,ImageNet是最权威的评测集,每年的ILSVRC催生了大量的优秀深度网络结构,为其他任务提供了基础。在应用领域,人脸、场景的识别等都可以归为分类任务。


    二是检测(Detection)。分类任务关心整体,给出的是整张图片的内容描述,而检测则关注特定的物体目标,要求同时获得这一目标的类别信息和位置信息。相比分类,检测给出的是对图片前景和背景的理解,我们需要从背景中分离出感兴趣的目标,并确定这一目标的描述(类别和位置),因而,检测模型的输出是一个列表,列表的每一项使用一个数据组给出检出目标的类别和位置(常用矩形检测框的坐标表示)。


    三是分割(Segmentation)。分割包括语义分割(semantic segmentation)和实例分割(instance segmentation),前者是对前背景分离的拓展,要求分离开具有不同语义的图像部分,而后者是检测任务的拓展,要求描述出目标的轮廓(相比检测框更为精细)。分割是对图像的像素级描述,它赋予每个像素类别(实例)意义,适用于理解要求较高的场景,如无人驾驶中对道路和非道路的分割。


    本系列文章关注的领域是目标检测,即图像理解的中层次。


    目标检测入门(一):目标检测经典模型回顾


    本文结构

    640?wx_fmt=jpeg


    两阶段(2-stage)检测模型


    两阶段模型因其对图片的两阶段处理得名,也称为基于区域(Region-based)的方法,我们选取R-CNN系列工作作为这一类型的代表。


    R-CNN: R-CNN系列的开山之作


    Rich feature hierarchies for accurate object detection and semantic segmentation

    论文链接: 

    https://arxiv.org/abs/1311.2524


    本文的两大贡献:


    1)CNN可用于基于区域的定位和分割物体;

    2)监督训练样本数紧缺时,在额外的数据上预训练的模型经过fine-tuning可以取得很好的效果。


    第一个贡献影响了之后几乎所有2-stage方法,而第二个贡献中用分类任务(Imagenet)中训练好的模型作为基网络,在检测问题上fine-tuning的做法也在之后的工作中一直沿用。


    传统的计算机视觉方法常用精心设计的手工特征(如SIFT, HOG)描述图像,而深度学习的方法则倡导习得特征,从图像分类任务的经验来看,CNN网络自动习得的特征取得的效果已经超出了手工设计的特征。本篇在局部区域应用卷积网络,以发挥卷积网络学习高质量特征的能力。


    640?wx_fmt=jpeg

    R-CNN网络结构


    R-CNN将检测抽象为两个过程,一是基于图片提出若干可能包含物体的区域(即图片的局部裁剪,被称为Region Proposal),文中使用的是Selective Search算法;二是在提出的这些区域上运行当时表现最好的分类网络(AlexNet),得到每个区域内物体的类别。


    另外,文章中的两个做法值得注意。


    640?wx_fmt=jpeg

    IoU的计算


    一是数据的准备。输入CNN前,我们需要根据Ground Truth对提出的Region Proposal进行标记,这里使用的指标是IoU(Intersection over Union,交并比)。IoU计算了两个区域之交的面积跟它们之并的比,描述了两个区域的重合程度。


    文章中特别提到,IoU阈值的选择对结果影响显著,这里要谈两个threshold,一个用来识别正样本(如跟ground truth的IoU大于0.5),另一个用来标记负样本(即背景类,如IoU小于0.1),而介于两者之间的则为难例(Hard Negatives),若标为正类,则包含了过多的背景信息,反之又包含了要检测物体的特征,因而这些Proposal便被忽略掉。


    另一点是位置坐标的回归(Bounding-Box Regression),这一过程是Region Proposal向Ground Truth调整,实现时加入了log/exp变换来使损失保持在合理的量级上,可以看做一种标准化(Normalization)操作。


    小结


    R-CNN的想法直接明了,即将检测任务转化为区域上的分类任务,是深度学习方法在检测任务上的试水。模型本身存在的问题也很多,如需要训练三个不同的模型(proposal, classification, regression)、重复计算过多导致的性能问题等。尽管如此,这篇论文的很多做法仍然广泛地影响着检测任务上的深度模型革命,后续的很多工作也都是针对改进这一工作而展开,此篇可以称得上"The First Paper"。


    Fast R-CNN: 共享卷积运算


    Fast R-CNN

    论文链接:

    https://arxiv.org/abs/1504.08083


    文章指出R-CNN耗时的原因是CNN是在每一个Proposal上单独进行的,没有共享计算,便提出将基础网络在图片整体上运行完毕后,再传入R-CNN子网络,共享了大部分计算,故有Fast之名。


    640?wx_fmt=jpeg

    Fast R-CNN网络结构


    上图是Fast R-CNN的架构。图片经过feature extractor得到feature map, 同时在原图上运行Selective Search算法并将RoI(Region of Interset,实为坐标组,可与Region Proposal混用)映射到到feature map上,再对每个RoI进行RoI Pooling操作便得到等长的feature vector,将这些得到的feature vector进行正负样本的整理(保持一定的正负样本比例),分batch传入并行的R-CNN子网络,同时进行分类和回归,并将两者的损失统一起来。


    640?wx_fmt=png

    RoI Pooling图示,来源:https://blog.deepsense.ai/region-of-interest-pooling-explained/


    RoI Pooling 是对输入R-CNN子网络的数据进行准备的关键操作。我们得到的区域常常有不同的大小,在映射到feature map上之后,会得到不同大小的特征张量。RoI Pooling先将RoI等分成目标个数的网格,再在每个网格上进行max pooling,就得到等长的RoI feature vector。


    文章最后的讨论也有一定的借鉴意义:


    • multi-loss traing相比单独训练classification确有提升

    • multi-scale相比single-scale精度略有提升,但带来的时间开销更大。一定程度上说明CNN结构可以内在地学习尺度不变性

    • 在更多的数据(VOC)上训练后,精度是有进一步提升的

    • Softmax分类器比"one vs rest"型的SVM表现略好,引入了类间的竞争

    • 更多的Proposal并不一定带来精度的提升


    小结


    Fast R-CNN的这一结构正是检测任务主流2-stage方法所采用的元结构的雏形。


    文章将Proposal, Feature Extractor, Object Classification&Localization统一在一个整体的结构中,并通过共享卷积计算提高特征利用效率,是最有贡献的地方。


    Faster R-CNN: 两阶段模型的深度化


    Faster R-CNN: Towards Real Time Object Detection with Region Proposal Networks

    论文链接:

    https://arxiv.org/abs/1506.01497


    Faster R-CNN是2-stage方法的奠基性工作,提出的RPN网络取代Selective Search算法使得检测任务可以由神经网络端到端地完成。粗略的讲,Faster R-CNN = RPN + Fast R-CNN,跟RCNN共享卷积计算的特性使得RPN引入的计算量很小,使得Faster R-CNN可以在单个GPU上以5fps的速度运行,而在精度方面达到SOTA(State of the Art,当前最佳)。


    本文的主要贡献是提出Regional Proposal Networks,替代之前的SS算法。RPN网络将Proposal这一任务建模为二分类(是否为物体)的问题。


    640?wx_fmt=jpeg

    Faster R-CNN网络结构


    第一步是在一个滑动窗口上生成不同大小和长宽比例的anchor box(如上图右边部分),取定IoU的阈值,按Ground Truth标定这些anchor box的正负。于是,传入RPN网络的样本数据被整理为anchor box(坐标)和每个anchor box是否有物体(二分类标签)。


    RPN网络将每个样本映射为一个概率值和四个坐标值,概率值反应这个anchor box有物体的概率,四个坐标值用于回归定义物体的位置。最后将二分类和坐标回归的损失统一起来,作为RPN网络的目标训练。


    由RPN得到Region Proposal在根据概率值筛选后经过类似的标记过程,被传入R-CNN子网络,进行多分类和坐标回归,同样用多任务损失将二者的损失联合。


    小结


    Faster R-CNN的成功之处在于用RPN网络完成了检测任务的"深度化"。使用滑动窗口生成anchor box的思想也在后来的工作中越来越多地被采用(YOLO v2等)。这项工作奠定了"RPN+RCNN"的两阶段方法元结构,影响了大部分后续工作。


    单阶段(1-stage)检测模型


    单阶段模型没有中间的区域检出过程,直接从图片获得预测结果,也被成为Region-free方法。


    YOLO


    You Only Look Once: Unified, Real-Time Object Detection

    论文链接:

    https://arxiv.org/abs/1506.02640


    YOLO是单阶段方法的开山之作。它将检测任务表述成一个统一的、端到端的回归问题,并且以只处理一次图片同时得到位置和分类而得名。


    YOLO的主要优点:


    • 快。

    • 全局处理使得背景错误相对少,相比基于局部(区域)的方法, 如Fast RCNN。

    • 泛化性能好,在艺术作品上做检测时,YOLO表现比Fast R-CNN好。


    640?wx_fmt=jpeg

    YOLO网络结构


    YOLO的工作流程如下:


    1.准备数据:将图片缩放,划分为等分的网格,每个网格按跟Ground Truth的IoU分配到所要预测的样本。


    2.卷积网络:由GoogLeNet更改而来,每个网格对每个类别预测一个条件概率值,并在网格基础上生成B个box,每个box预测五个回归值,四个表征位置,第五个表征这个box含有物体(注意不是某一类物体)的概率和位置的准确程度(由IoU表示)。测试时,分数如下计算:


    640?wx_fmt=jpeg


    等式左边第一项由网格预测,后两项由每个box预测,以条件概率的方式得到每个box含有不同类别物体的分数。 因而,卷积网络共输出的预测值个数为S×S×(B×5+C),其中S为网格数,B为每个网格生成box个数,C为类别数。


    3.后处理:使用NMS(Non-Maximum Suppression,非极大抑制)过滤得到最后的预测框


    损失函数的设计


    640?wx_fmt=jpeg

    YOLO的损失函数分解,来源:https://zhuanlan.zhihu.com/p/24916786


    损失函数被分为三部分:坐标误差、物体误差、类别误差。为了平衡类别不均衡和大小物体等带来的影响,损失函数中添加了权重并将长宽取根号。


    小结


    YOLO提出了单阶段的新思路,相比两阶段方法,其速度优势明显,实时的特性令人印象深刻。但YOLO本身也存在一些问题,如划分网格较为粗糙,每个网格生成的box个数等限制了对小尺度物体和相近物体的检测。


    SSD: Single Shot Multibox Detector


    SSD: Single Shot Multibox Detector

    论文链接:

    https://arxiv.org/abs/1512.02325


    640?wx_fmt=jpeg

    SSD网络结构


    SSD相比YOLO有以下突出的特点:


    • 多尺度的feature map:基于VGG的不同卷积段,输出feature map到回归器中。这一点试图提升小物体的检测精度。

    • 更多的anchor box,每个网格点生成不同大小和长宽比例的box,并将类别预测概率基于box预测(YOLO是在网格上),得到的输出值个数为(C+4)×k×m×n,其中C为类别数,k为box个数,m×n为feature map的大小。


    小结


    SSD是单阶段模型早期的集大成者,达到跟接近两阶段模型精度的同时,拥有比两阶段模型快一个数量级的速度。后续的单阶段模型工作大多基于SSD改进展开。


    检测模型基本特点


    最后,我们对检测模型的基本特征做一个简单的归纳。


    640?wx_fmt=jpeg

    两阶段检测模型Pipeline,来源:https://tryolabs.com/blog/2018/01/18/faster-r-cnn-down-the-rabbit-hole-of-modern-object-detection/


    检测模型整体上由基础网络(Backbone Network)和检测头部(Detection Head)构成。前者作为特征提取器,给出图像不同大小、不同抽象层次的表示;后者则依据这些表示和监督信息学习类别和位置关联。检测头部负责的类别预测和位置回归两个任务常常是并行进行的,构成多任务的损失进行联合训练。


    640?wx_fmt=jpeg

    检测模型头部并行的分支,来源同上


    相比单阶段,两阶段检测模型通常含有一个串行的头部结构,即完成前背景分类和回归后,把中间结果作为RCNN头部的输入再进行一次多分类和位置回归。这种设计带来了一些优点:


    • 对检测任务的解构,先进行前背景的分类,再进行物体的分类,这种解构使得监督信息在不同阶段对网络参数的学习进行指导

    • RPN网络为RCNN网络提供良好的先验,并有机会整理样本的比例,减轻RCNN网络的学习负担


    这种设计的缺点也很明显:中间结果常常带来空间开销,而串行的方式也使得推断速度无法跟单阶段相比;级联的位置回归则会导致RCNN部分的重复计算(如两个RoI有重叠)。


    另一方面,单阶段模型只有一次类别预测和位置回归,卷积运算的共享程度更高,拥有更快的速度和更小的内存占用。读者将会在接下来的文章中看到,两种类型的模型也在互相吸收彼此的优点,这也使得两者的界限更为模糊。


    目标检测入门(二):模型的评测与训练技巧


    文章结构


    640?wx_fmt=jpeg


    检测模型的评测指标


    目标检测模型本源上可以用统计推断的框架描述,我们关注其犯第一类错误和第二类错误的概率,通常用准确率和召回率来描述。准确率描述了模型有多准,即在预测为正例的结果中,有多少是真正例;召回率则描述了模型有多全,即在为真的样本中,有多少被我们的模型预测为正例。不同的任务,对两类错误有不同的偏好,常常在某一类错误不多于一定阈值的情况下,努力减少另一类错误。在检测中,mAP(mean Average Precision)作为一个统一的指标将这两种错误兼顾考虑。


    具体地,对于每张图片,检测模型输出多个预测框(常常远超真实框的个数),我们使用IoU(Intersection Over Union,交并比)来标记预测框是否为预测正确。标记完成后,随着预测框的增多,召回率总会提升,在不同的召回率水平下对准确率做平均,即得到AP,最后再对所有类别按其所占比例做平均,即得到mAP。


    在较早的Pascal VOC数据集上,常采用固定的一个IoU阈值(如0.5, 0.75)来计算mAP,现阶段较为权威的MS COCO数据集上,对不同的IoU阈值(0.5-0.95,0.05为步长)分别计算AP,再综合平均,并且给出了不同大小物体分别的AP表现,对定位准确的模型给予奖励并全面地展现不同大小物体上检测算法的性能,更为科学合理。


    在实践中,我们不仅关注检测模型的精度,还关注其运行的速度,常常用FPS(Frame Per Second,每秒帧率)来表示检测模型能够在指定硬件上每秒处理图片的张数。通常来讲,在单块GPU上,两阶段方法的FPS一般在个位数,而单阶段方法可以达到数十。现在检测模型运行的平台并不统一,实践中也不能部署较为昂贵的GPU进行推断。事实上,很多文章并没有严谨讨论其提出模型的速度表现(加了较多的trick以使精度达到SOTA),另外,考虑到目前移动端专用芯片的发展速度和研究进展,速度方面的指标可能较难形成统一的参考标准,需要谨慎看待文章中汇报的测试结果。


    标准评测数据集


    Pascal VOC(Pascal Visual Object Classes)


    链接:http://host.robots.ox.ac.uk/pascal/VOC/


    自2005年起每年举办一次比赛,最开始只有4类,到2007年扩充为20个类,共有两个常用的版本:2007和2012。学术界常用5k的trainval2007和16k的trainval2012作为训练集(07+12),test2007作为测试集,用10k的trainval2007+test2007和和16k的trainval2012作为训练集(07++12),test2012作为测试集,分别汇报结果。


    Pascal VOC对早期检测工作起到了重要的推动作用,目前提升的空间相对有限,权威评测集的交接棒也逐渐传给了下面要介绍的COCO。


    MS COCO(Common Objects in COntext-http://cocodataset.org)


    640?wx_fmt=jpeg

    检测任务在COCO数据集上的进展


    COCO数据集收集了大量包含常见物体的日常场景图片,并提供像素级的实例标注以更精确地评估检测和分割算法的效果,致力于推动场景理解的研究进展。依托这一数据集,每年举办一次比赛,现已涵盖检测、分割、关键点识别、注释等机器视觉的中心任务,是继ImageNet Chanllenge以来最有影响力的学术竞赛之一。


    640?wx_fmt=jpeg

    iconic与non-iconic图片对比


    相比ImageNet,COCO更加偏好目标与其场景共同出现的图片,即non-iconic images。这样的图片能够反映视觉上的语义,更符合图像理解的任务要求。而相对的iconic images则更适合浅语义的图像分类等任务。


    COCO的检测任务共含有80个类,在2014年发布的数据规模分train/val/test分别为80k/40k/40k,学术界较为通用的划分是使用train和35k的val子集作为训练集(trainval35k),使用剩余的val作为测试集(minival),同时向官方的evaluation server提交结果(test-dev)。除此之外,COCO官方也保留一部分test数据作为比赛的评测集。


    640?wx_fmt=jpeg

    COCO数据集分布


    在分布方面,COCO的每个类含有更多实例,分布也较为均衡(上图a),每张图片包含更多类和更多的实例(上图b和c,均为直方图,每张图片平均分别含3.3个类和7.7个实例),相比Pascal VOC,COCO还含有更多的小物体(下图,横轴是物体占图片的比例)。


    640?wx_fmt=jpeg

    COCO数据集物体大小分布


    如本文第一节所述,COCO提供的评测标准更为精细化,提供的API不仅包含了可视化、评测数据的功能,还有对模型的错误来源分析脚本,能够更清晰地展现算法的不足之处。COCO所建立的这些标准也逐渐被学术界认可,成为通用的评测标准。您可以在这里找到目前检测任务的LeaderBoard。


    640?wx_fmt=jpeg

    错误来源分解,详见http://cocodataset.org/#detections-eval


    Cityscapes(https://www.cityscapes-dataset.com)


    640?wx_fmt=jpeg

    Cityscapes数据示例


    Cityscapes数据集专注于现代城市道路场景的理解,提供了30个类的像素级标注,是自动驾驶方向较为权威的评测集。


    检测模型中的Bells and wisthles


    本节介绍常见的提升检测模型性能的技巧,它们常作为trick在比赛中应用。其实,这样的名称有失公允,部分工作反映了作者对检测模型有启发意义的观察,有些具有成为检测模型标准组件的潜力(如果在早期的工作中即被应用则可能成为通用做法)。读者将它们都看作学术界对解决这一问题的努力即可。对研究者,诚实地报告所引用的其他工作并添加有说服力的消融实验(ablation expriments)以支撑自己工作的原创性和贡献之处,则是值得倡导的行为。


    Data augmentation 数据增强


    数据增强是增加深度模型鲁棒性和泛化性能的常用手段,随机翻转、随机裁剪、添加噪声等也被引入到检测任务的训练中来,其信念是通过数据的一般性来迫使模型学习到诸如对称不变性、旋转不变性等更一般的表示。通常需要注意标注的相应变换,并且会大幅增加训练的时间。个人认为数据(监督信息)的适时传入可能是更有潜力的方向。


    Multi-scale Training/Testing 多尺度训练/测试


    输入图片的尺寸对检测模型的性能影响相当明显,事实上,多尺度是提升精度最明显的技巧之一。在基础网络部分常常会生成比原图小数十倍的特征图,导致小物体的特征描述不容易被检测网络捕捉。通过输入更大、更多尺寸的图片进行训练,能够在一定程度上提高检测模型对物体大小的鲁棒性,仅在测试阶段引入多尺度,也可享受大尺寸和多尺寸带来的增益。


    multi-scale training/testing最早见于[1],训练时,预先定义几个固定的尺度,每个epoch随机选择一个尺度进行训练。测试时,生成几个不同尺度的feature map,对每个Region Proposal,在不同的feature map上也有不同的尺度,我们选择最接近某一固定尺寸(即检测头部的输入尺寸)的Region Proposal作为后续的输入。在[2]中,选择单一尺度的方式被Maxout(element-wise max,逐元素取最大)取代:随机选两个相邻尺度,经过Pooling后使用Maxout进行合并,如下图所示。


    640?wx_fmt=jpeg

    使用Maxout合并feature vector


    近期的工作如FPN等已经尝试在不同尺度的特征图上进行检测,但多尺度训练/测试仍作为一种提升性能的有效技巧被应用在MS COCO等比赛中。


    Global Context 全局语境


    这一技巧在ResNet的工作[3]中提出,做法是把整张图片作为一个RoI,对其进行RoI Pooling并将得到的feature vector拼接于每个RoI的feature vector上,作为一种辅助信息传入之后的R-CNN子网络。目前,也有把相邻尺度上的RoI互相作为context共同传入的做法。


    Box Refinement/Voting 预测框微调/投票法


    微调法和投票法由工作[4]提出,前者也被称为Iterative Localization。微调法最初是在SS算法得到的Region Proposal基础上用检测头部进行多次迭代得到一系列box,在ResNet的工作中,作者将输入R-CNN子网络的Region Proposal和R-CNN子网络得到的预测框共同进行NMS(见下面小节)后处理,最后,把跟NMS筛选所得预测框的IoU超过一定阈值的预测框进行按其分数加权的平均,得到最后的预测结果。投票法可以理解为以顶尖筛选出一流,再用一流的结果进行加权投票决策。


    OHEM 在线难例挖掘


    OHEM(Online Hard negative Example Mining,在线难例挖掘)见于[5]。两阶段检测模型中,提出的RoI Proposal在输入R-CNN子网络前,我们有机会对正负样本(背景类和前景类)的比例进行调整。通常,背景类的RoI Proposal个数要远远多于前景类,Fast R-CNN的处理方式是随机对两种样本进行上采样和下采样,以使每一batch的正负样本比例保持在1:3,这一做法缓解了类别比例不均衡的问题,是两阶段方法相比单阶段方法具有优势的地方,也被后来的大多数工作沿用。


    640?wx_fmt=jpeg

    OHEM图解


    但在OHEM的工作中,作者提出用R-CNN子网络对RoI Proposal预测的分数来决定每个batch选用的样本,这样,输入R-CNN子网络的RoI Proposal总为其表现不好的样本,提高了监督学习的效率。实际操作中,维护两个完全相同的R-CNN子网络,其中一个只进行前向传播来为RoI Proposal的选择提供指导,另一个则为正常的R-CNN,参与损失的计算并更新权重,并且将权重复制到前者以使两个分支权重同步。


    OHEM以额外的R-CNN子网络的开销来改善RoI Proposal的质量,更有效地利用数据的监督信息,成为两阶段模型提升性能的常用部件之一。


    Soft NMS 软化非极大抑制


    640?wx_fmt=jpeg

    NMS后处理图示


    NMS(Non-Maximum Suppression,非极大抑制)是检测模型的标准后处理操作,用于去除重合度(IoU)较高的预测框,只保留预测分数最高的预测框作为检测输出。Soft NMS由[6]提出。在传统的NMS中,跟最高预测分数预测框重合度超出一定阈值的预测框会被直接舍弃,作者认为这样不利于相邻物体的检测。提出的改进方法是根据IoU将预测框的预测分数进行惩罚,最后再按分数过滤。配合Deformable Convnets(将在之后的文章介绍),Soft NMS在MS COCO上取得了当时最佳的表现。算法改进如下:


    640?wx_fmt=jpeg

    Soft-NMS算法改进


    上图中的f即为软化函数,通常取线性或高斯函数,后者效果稍好一些。当然,在享受这一增益的同时,Soft-NMS也引入了一些超参,对不同的数据集需要试探以确定最佳配置。


    RoIAlign RoI对齐


    RoIAlign是Mask R-CNN([7])的工作中提出的,针对的问题是RoI在进行Pooling时有不同程度的取整,这影响了实例分割中mask损失的计算。文章采用双线性插值的方法将RoI的表示精细化,并带来了较为明显的性能提升。这一技巧也被后来的一些工作(如light-head R-CNN)沿用。


    拾遗


    除去上面所列的技巧外,还有一些做法也值得注意:


    • 更好的先验(YOLOv2):使用聚类方法统计数据中box标注的大小和长宽比,以更好的设置anchor box的生成配置

    • 更好的pre-train模型:检测模型的基础网络通常使用ImageNet(通常是ImageNet-1k)上训练好的模型进行初始化,使用更大的数据集(ImageNet-5k)预训练基础网络对精度的提升亦有帮助

    • 超参数的调整:部分工作也发现如NMS中IoU阈值的调整(从0.3到0.5)也有利于精度的提升,但这一方面尚无最佳配置参照


    最后,集成(Ensemble)作为通用的手段也被应用在比赛中。


    总结


    本篇文章里,我们介绍了检测模型常用的标准评测数据集和训练模型的技巧,上述内容在溯源和表述方面的不实之处也请读者评论指出。从下一篇开始,我们将介绍检测领域较新的趋势,请持续关注。


    Reference

    [1]: Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition

    [2]: Object Detection Networks on Convolutional Feature Maps

    [3]: Deep Residual Learning for Image Classification

    [4]: Object Detection via a Multi-region & Semantic Segmentatio-aware CNN Model

    [5]: Training Region-based Object Detectors with Online Hard Example Mining

    [6]: Improving Object Detection With One Line of Code

    [7]: Mask R-CNN


    插播:格灵深瞳2018春季校招现已启动!点击查看格灵深瞳空中宣讲会


    招聘

    新一年,AI科技大本营的目标更加明确,有更多的想法需要落地,不过目前对于营长来说是“现实跟不上灵魂的脚步”,因为缺人~~


    所以,AI科技大本营要壮大队伍了,现招聘AI记者和资深编译,有意者请将简历投至:gulei@csdn.net,期待你的加入!


    如果你暂时不能加入营长的队伍,也欢迎与营长分享你的精彩文章,投稿邮箱:suiling@csdn.net


    AI科技大本营读者群(计算机视觉、机器学习、深度学习、NLP、Python、AI硬件、AI+金融、AI+PM方向)正在招募中,关注AI科技大本营微信公众号,后台回复:读者群,联系营长,添加营长请备注姓名,研究方向。


    640?wx_fmt=gif

    640?wx_fmt=png

    640?wx_fmt=png

    640?wx_fmt=png


    ☟☟☟点击 | 阅读原文 | 查看更多精彩内

    展开全文
  • 目标检测综述

    万次阅读 多人点赞 2019-07-09 21:36:26
    这意味着,我们不仅要用算法判断图片中是不是一辆汽车, 还要在图片中标记出它的位置, 用边框或红色方框把汽车圈起来, 这就是目标检测问题。 其中“定位”的意思是判断汽车在图片中的具体位置。 近几年来,目标...

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

    前言

    图片分类任务我们已经熟悉了,就是算法对其中的对象进行分类。而今天我们要了解构建神经网络的另一个问题,即目标检测问题。这意味着,我们不仅要用算法判断图片中是不是一辆汽车, 还要在图片中标记出它的位置, 用边框或红色方框把汽车圈起来, 这就是目标检测问题。 其中“定位”的意思是判断汽车在图片中的具体位置。
    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是一个非常灵活的框架,可以增加不同的分支完成不同的任务,可以完成目标分类、目标检测、语义分割、实例分割、人体姿势识别等多种任务,如下图所示。

      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外参的在线标定

    展开全文
  • 目标检测(一)——目标检测综述(持续更新中)

    万次阅读 多人点赞 2018-05-09 09:56:09
    目标检测 目标检测要解决的核心问题 目标检测最新进展 目标检测应用

    1. 什么是目标检测?

    这里写图片描述
    **目标检测 **的任务是找出图像中所有感兴趣的目标(物体),确定它们的位置和大小,是机器视觉领域的核心问题之一。由于各类物体有不同的外观,形状,姿态,加上成像时光照,遮挡等因素的干扰,目标检测一直是机器视觉领域最具有挑战性的问题。

    计算机视觉中关于图像识别有四大类任务:
    分类-Classification:解决“是什么?”的问题,即给定一张图片或一段视频判断里面包含什么类别的目标。
    定位-Location:解决“在哪里?”的问题,即定位出这个目标的的位置。
    检测-Detection:解决“是什么?在哪里?”的问题,即定位出这个目标的的位置并且知道目标物是什么。
    分割-Segmentation:分为实例的分割(Instance-level)和场景分割(Scene-level),解决“每一个像素属于哪个目标物或场景”的问题。

    2. 目标检测要解决的核心问题

    除了图像分类之外,目标检测要解决的核心问题是:
    1.目标可能出现在图像的任何位置。
    2.目标有各种不同的大小。
    3.目标可能有各种不同的形状。
    如果用矩形框来定义目标,则矩形有不同的宽高比。由于目标的宽高比不同,因此采用经典的滑动窗口+图像缩放的方案解决通用目标检测问题的成本太高。

    3. 目标检测学习资源

    3.1 目标检测论文、代码整理

    下边这个网站是一个整理计算视觉的网站,上边会定期更新最新发表的论文以及相关的代码。而且这个仅仅是目标检测一个分类,感兴趣的同学还可以进去看一下其他方向整理的论文与代码
    Object Detection - handong1587:https://handong1587.github.io/deep_learning/2015/10/09/object-detection.html

    3.2 VOC数据集检测排名

    这里写图片描述
    Leaderboards for the Evaluations on PASCAL VOC Data:http://host.robots.ox.ac.uk:8080/leaderboard/main_bootstrap.php
      上边网址为以VOC数据集为基础进行目标检测、对象分割以及行为检测等各项排名。你可以从总了解到目前比较先进的检测算法。

    3.3各大论文期刊目标检测

    Detector VOC07 (mAP@IoU=0.5) VOC12 (mAP@IoU=0.5) COCO (mAP) Published In
    R-CNN 58.5 - - CVPR’14
    OverFeat - - - ICLR’14
    MultiBox 29.0 - - CVPR’14
    SPP-Net 59.2 - - ECCV’14
    MR-CNN 78.2 (07+12) 73.9 (07+12) - ICCV’15
    AttentionNet - - - ICCV’15
    Fast R-CNN 70.0 (07+12) 68.4 (07++12) - ICCV’15
    Faster R-CNN 73.2 (07+12) 70.4 (07++12) - NIPS’15
    YOLO v1 66.4 (07+12) 57.9 (07++12) - CVPR’16
    G-CNN 66.8 66.4 (07+12) - CVPR’16
    AZNet 70.4 - 22.3 CVPR’16
    ION 80.1 77.9 33.1 CVPR’16
    HyperNet 76.3 (07+12) 71.4 (07++12) - CVPR’16
    OHEM 78.9 (07+12) 76.3 (07++12) 22.4 CVPR’16
    MPN - - 33.2 BMVC’16
    SSD 76.8 (07+12) 74.9 (07++12) - ECCV’16
    GBDNet 77.2 (07+12) - 27.0 ECCV’16
    CPF 76.4 (07+12) 72.6 (07++12) - ECCV’16
    MS-CNN - - - ECCV’16
    R-FCN 79.5 (07+12) 77.6 (07++12) 29.9 NIPS’16
    PVANET - - - NIPSW’16
    DeepID-Net 69.0 - - PAMI’16
    NoC 71.6 (07+12) 68.8 (07+12) 27.2 TPAMI’16
    DSSD 81.5 (07+12) 80.0 (07++12) - Arxiv’17
    TDM - - 37.3 CVPR’17
    FPN - - 36.2 CVPR’17
    YOLO v2 78.6 (07+12) 73.4 (07++12) - CVPR’17
    RON 77.6 (07+12) 75.4 (07++12) - CVPR’17
    DCN - - - ICCV’17
    DeNet 77.1 (07+12) 73.9 (07++12) 33.8 ICCV’17
    CoupleNet 82.7 (07+12) 80.4 (07++12) 34.4 ICCV’17
    RetinaNet - - 39.1 ICCV’17
    Mask R-CNN - - - ICCV’17
    DSOD 77.7 (07+12) 76.3 (07++12) - ICCV’17
    SMN 70.0 - - ICCV’17
    YOLO v3 - - 33.0 Arxiv’18
    SIN 76.0 (07+12) 73.1 (07++12) 23.2 CVPR’18
    STDN 80.9 (07+12) - - CVPR’18
    RefineDet 83.8 (07+12) 83.5 (07++12) 41.8 CVPR’18
    MegDet - - - CVPR’18
    RFBNet 82.2 (07+12) - - ECCV’18
    CornerNet - - 42.1 ECCV’18
    PFPNet 84.1 (07+12) 83.7 (07++12) 39.4 ECCV’18
    Pelee 70.9 (07+12) - - NIPS’18
    HKRM 78.8 (07+12) - 37.8 NIPS’18
    M2Det - - 44.2 AAAI’19
    R-DAD 81.2 (07++12) 82.0 (07++12) 43.1 AAAI’19
    ScratchDet 84.1 (07++12) 83.6 (07++12) 39.1 CVPR’19
    Libra R-CNN - - 43.0 CVPR’19
    Reasoning-RCNN 82.5 (07++12) - 43.2 CVPR’19
    FSAF - - 44.6 CVPR’19
    AmoebaNet + NAS-FPN - - 47.0 CVPR’19
    Cascade-RetinaNet - - 41.1 CVPR’19
    TridentNet - - 48.4 ICCV’19
    DAFS 85.3 (07+12) 83.1 (07++12) 40.5 ICCV’19
    Auto-FPN 81.8 (07++12) - 40.5 ICCV’19
    FCOS - - 44.7 ICCV’19
    FreeAnchor - - 44.8 NeurIPS’19
    DetNAS 81.5 (07++12) - 42.0 NeurIPS’19
    NATS - - 42.0 NeurIPS’19
    AmoebaNet + NAS-FPN + AA - - 50.7 arXiv’19
    EfficientDet - - 51.0 arXiv’19

    该表是参考大神的Github,建议大家也可以去看一看-GitHub - hoya012/deep_learning_object_detection: A paper list of object detection using deep learning.

    4. 目标检测最新进展

    这里写图片描述
       随着深度学习与计算机硬件的迅速发展,目标检测与深度学习的结合,目标检测也得以迅速发展,这一部分将在后续部分进行详细讲述(持续更新中)。
    目标检测(一)——目标检测综述
    目标检测(二)——评价指标
    目标检测(三)——R-CNN
    目标检测(四)——SPP-Net
    目标检测(五)——Fast R-CNN
    目标检测(六)——Faster R-CNN
             Faster RCNN安装以及Demo运行
    目标检测(七)——YOLO
    目标检测(八)——YOLO v2
             YOLO v2 安装训练测试
             darkflow安装测试
    目标检测(九)——YOLO v3
    目标检测(十)——SSD
    目标检测(十一)——DSSD

    参考

    基于深度学习的目标检测算法综述-SigAI
    深度学习时代的目标检测算法-炼数成金订阅号
    GitHub - hoya012/deep_learning_object_detection: A paper list of object detection using deep learning.

    展开全文
  • 图像处理---目标检测二十年

    万次阅读 多人点赞 2018-04-17 11:11:07
    目标检测是当前计算机视觉和机器学习领域的研究热点。从Viola-Jones Detector、DPM等冷兵器时代的智慧到当今RCNN、YOLO等深度学习土壤孕育下的GPU暴力美学,整个目标检测的发展可谓是计算机视觉领域的一部浓缩史。...
  • 2018年小目标检测文章总结

    千次阅读 2019-01-04 15:45:45
    由于最近需要写一篇小目标检测的综述,但是在认真调研之后,发现关于小目标检测的文章真的不多,但是又不想直接放弃度过的文章,所以就写成一篇博客来纪念一下。 在现有的目标检测的文献中,大多数是针对通用的目标...
  • 点击上方“AI算法与图像处理”,选择加"星标"或“置顶”重磅干货,第一时间送达本文转载自公众号:计算机视觉life前言图片分类任务我们已经熟悉了,就是算法对其中的对象进行...
  • CVPR2019目标检测方法进展

    千次阅读 2019-04-04 14:50:50
    目标检测是很多计算机视觉应用的基础,比如实例分割、人体关键点提取、人脸识别等,它结合了目标分类和定位两个任务。现代大多数目标检测器的框架是 two-stage,其中目标检测被定义为一个多任务学习问题:1)区分...
  • 2020年最全目标检测综述(完结篇)

    万次阅读 2020-03-13 20:37:41
    点击蓝字关注我们computerVision计算机视觉战队●扫码关注,回复:目标检测●获取目标检测相关下载链接今天我们的目标检测综述最后一章,也是这...
  • 目标检测一览1

    千次阅读 2020-05-29 17:34:21
    1.目标检测问题 1.1分类和回归 目标检测,即是分类问题,也是回归问题。 分类Classification:对打框的部分进行分类,是目标物体?还是背景?解决识别与分类(classification)。 回归Regression:cat(x,y,w,h)...
  • 目标检测 (Object Detection) 算法汇集

    万次阅读 2018-03-26 21:39:06
    基于深度学习的目标检测综述(一)(2018年03月16日) 图像分类,检测及分割是计算机视觉领域的三大任务。图像分类模型(详情见这里)是将图像划分为单个类别,通常对应于图像中最突出的物体。但是现实世界的很多图片...
  • 视频目标检测识别

    万次阅读 多人点赞 2018-03-25 21:53:21
    之前文章目标检测API 已经介绍过API的基本使用,这里就不赘述了,直接上本次内容的代码了,添加的内容并不多。将测试的test.mp4原文件放到models-master\research\object_detection路径下,并创建一个detect_video....
  • 目标检测】RCNN算法详解

    万次阅读 多人点赞 2016-04-05 23:10:36
    深度学习用于目标检测的RCNN算法
  • 目标检测】Faster RCNN算法详解

    万次阅读 多人点赞 2016-04-21 15:08:06
    继RCNN,fast RCNN之后,目标检测界的领军人物Ross Girshick在2015年提出faster RCNN。目标检测速度达到15fps。
  • 目标检测算法对比

    万次阅读 2018-04-14 21:49:58
    R-CNN。 来自 ICCV 2015,可以说是利用深度学习进行目标检测的开山之作。作者Ross Girshick多次在PASCAL VOC的目标检测竞赛中折桂,...包括本文在内的一系列目标检测算法:RCNN, Fast RCNN, Faster RCNN代表当下目...
  • (自己写的,需要转载请联系作者,或者标明出处呀,欢迎加微信交流:wx604954) ...本文介绍了目前发展迅猛的深度学习方法在目标检测中的最新应用进展,然后介绍了基于深度学习的目标检测算法在医学图像领域的应...
  • 目标检测算法之SSD

    万次阅读 多人点赞 2018-04-06 15:17:33
    码字不易,欢迎给个赞! 欢迎交流与转载,文章会同步发布在公众号:机器学习算法...目标检测近年来已经取得了很重要的进展,主流的算法主要分为两个类型:(1)two-stage方法,如R-CNN系算法,其主要思路是先通过启...
  • 目标检测算法

    千次阅读 2020-05-23 09:58:09
    目标检测算法 文章目录目标检测算法全卷积神经网络(FCN)非极大值抑制(Non-max suppression)R-CNN算法流程SPP-Net(Spatial Pyramid Pooling Net)Fast-RCNNFaster-RCNNFaster-RCNN-RPN的损失函数Faster-RCNN的...
  • 目标检测算法汇集介绍

    万次阅读 多人点赞 2018-09-15 19:15:33
    目标检测算法 目标检测概念 目标检测这里阐述两个应用场景,1 为物体位置检测,2 为物体关键点检测。 1 物体位置检测 相比与图片分类,目标检测算法结果要求不仅识别出图片中的物理类别并且输出物体...
  • 基于深度学习的目标检测算法综述

    万次阅读 多人点赞 2018-06-19 16:04:53
    其它机器学习、深度学习算法的全面系统讲解可以阅读《机器学习-原理、算法与应用》,清华大学出版社,雷明著,由SIGAI公众号作者倾力打造。 书的购买链接 书的勘误,优化,源代码资源 导言 目标检测的任务是找出...

空空如也

1 2 3 4 5 ... 20
收藏数 465,506
精华内容 186,202
关键字:

目标检测