那么什么是计算机视觉呢? 这里给出了几个比较严谨的定义:
✦ “对图像中的客观对象构建明确而有意义的描述”(Ballard&Brown,1982)
✦ “从一个或多个数字图像中计算三维世界的特性”(Trucco&Verri,1998)
✦ “基于感知图像做出对客观对象和场景有用的决策”(Sockman&Shapiro,2001)
实际作用的应用,例如:
计算机视觉五大技术:图像分类、对象检测、目标跟踪、语义分割和实例分割
给定一组各自被标记为单一类别的图像,我们对一组新的测试图像的类别进行预测,并测量预测的准确性结果,这就是图像分类问题。
视点变化,尺度变化,类内变化,图像变形,图像遮挡,照明条件和背景杂斑
计算机视觉研究人员提出了一种基于数据驱动的方法。
该算法并不是直接在代码中指定每个感兴趣的图像类别,而是为计算机每个图像类别都提供许多示例,然后设计一个学习算法,查看这些示例并学习每个类别的视觉外观。也就是说,首先积累一个带有标记图像的训练集,然后将其输入到计算机中,由计算机来处理这些数据。
因此,可以按照下面的步骤来分解:
目前较为流行的图像分类架构是卷积神经网络(CNN)——将图像送入网络,然后网络对图像数据进行分类。
卷积神经网络从输入“扫描仪”开始,该输入“扫描仪”也不会一次性解析所有的训练数据。比如输入一个大小为 100*100 的图像,你也不需要一个有 10,000 个节点的网络层。相反,你只需要创建一个大小为 10 10 的扫描输入层,扫描图像的前 1010 个像素。然后,扫描仪向右移动一个像素,再扫描下一个 10 *10 的像素,这就是滑动窗口。
输入数据被送入卷积层,而不是普通层。每个节点只需要处理离自己最近的邻近节点,卷积层也随着扫描的深入而趋于收缩。除了卷积层之外,通常还会有池化层。池化是过滤细节的一种方法,常见的池化技术是最大池化,它用大小为 2*2 的矩阵传递拥有最多特定属性的像素。
第一届 ImageNet 竞赛的获奖者是 Alex Krizhevsky(NIPS 2012) ,他在 Yann LeCun 开创的神经网络类型基础上,设计了一个深度卷积神经网络。该网络架构除了一些最大池化层外,还包含 7 个隐藏层,前几层是卷积层,最后两层是全连接层。在每个隐藏层内,激活函数为线性的,要比逻辑单元的训练速度更快、性能更好。除此之外,当附近的单元有更强的活动时,它还使用竞争性标准化来压制隐藏活动,这有助于强度的变化
就硬件要求而言, Alex 在 2 个 Nvidia GTX 580 GPU (速度超过 1000 个快速的小内核)上实现了非常高效的卷积网络。 GPU 非常适合矩阵间的乘法且有非常高的内存带宽。这使他能在一周内完成训练,并在测试时快速的从 10 个块中组合出结果。如果我们能够以足够快的速度传输状态,就可以将网络分布在多个内核上。
随着内核越来越便宜,数据集越来越大,大型神经网络的速度要比老式计算机视觉系统更快。在这之后,已经有很多种使用卷积神经网络作为核心,并取得优秀成果的模型,如 ZFNet(2013),GoogLeNet(2014), VGGNet(2014), RESNET(2015),DenseNet(2016)等。
在对象检测中,你只有 2 个对象分类类别,即对象边界框和非对象边界框。例如,在汽车检测中,你必须使用边界框检测所给定图像中的所有汽车。
这不同于分类/定位任务——对很多对象进行分类和定位。
使用图像分类和定位图像这样的滑动窗口技术,我们则需要将卷积神经网络应用于图像上的很多不同物体上。
由于卷积神经网络会将图像中的每个物体识别为对象或背景,因此我们需要在大量的位置和尺度上使用卷积神经网络,但是这需要很大的计算量!
采用滑动窗口的目标检测算法思路非常简单,它将检测问题转化为了图像分类问题。其基本原理就是采用不同大小和比例(宽高比)的窗口在整张图片上以一定的步长进行滑动,然后对这些窗口对应的区域做图像分类,这样就可以实现对整张图片的检测了,如下图所示,如DPM就是采用这种思路。
但是这个方法有致命的缺点,就是你并不知道要检测的目标大小是什么规模,所以你要设置不同大小和比例的窗口去滑动,而且还要选取合适的步长。但是这样会产生很多的子区域,并且都要经过分类器去做预测,这需要很大的计算量,所以你的分类器不能太复杂,因为要保证速度。
解决思路之一就是减少要分类的子区域,这就是R-CNN的一个改进策略,其采用了selective search方法来找到最有可能包含目标的子区域(Region Proposal),其实可以看成采用启发式方法过滤掉很多子区域,这会提升效率。
神经网络研究人员建议使用区域(region)这一概念,这样我们就会找到可能包含对象的“斑点”图像区域,这样运行速度就会大大提高。第一种模型是基于区域的卷积神经网络( R-CNN ),其算法原理如下:
实质上,我们将对象检测转换为一个图像分类问题。但是也存在这些问题:训练速度慢,需要大量的磁盘空间,推理速度也很慢。
R-CNN 的第一个升级版本是 Fast R-CNN,通过使用了 2 次增强,大大提了检测速度:
Fast R-CNN 的运行速度要比 R-CNN 快的多,因为在一幅图像上它只能训练一个 CNN 。 但是,择性搜索算法生成区域提议仍然要花费大量时间。
其中:运用了全卷积的方法
CNN分类器滑动窗口是非常耗时的。但是结合卷积运算的特点,我们可以使用CNN实现更高效的滑动窗口方法。
这里要介绍的是一种全卷积的方法,简单来说就是网络中用卷积层代替了全连接层,如图所示。
输入图片大小是16x16,经过一系列卷积操作,提取了2x2的特征图,但是这个2x2的图上每个元素都是和原图是一一对应的,如图上蓝色的格子对应蓝色的区域,这不就是相当于在原图上做大小为14x14的窗口滑动,且步长为2,共产生4个字区域。最终输出的通道数为4,可以看成4个类别的预测概率值,这样一次CNN计算就可以实现窗口滑动的所有子区域的分类预测。这其实是overfeat算法的思路。之所可以CNN可以实现这样的效果是因为卷积操作的特性,就是图片的空间位置信息的不变性,尽管卷积过程中图片大小减少,但是位置对应关系还是保存的。说点题外话,这个思路也被R-CNN借鉴,从而诞生了Fast R-cNN算法。
Faster R-CNN 是基于深度学习对象检测的一个典型案例。
该算法用一个快速神经网络代替了运算速度很慢的选择性搜索算法:
一旦我们有了区域建议,就直接将它们送入 Fast R-CNN 。 并且,我们还添加了一个池化层、一些全连接层、一个 softmax 分类层以及一个边界框回归器。
总之,Faster R-CNN 的速度和准确度更高。值得注意的是,虽然以后的模型在提高检测速度方面做了很多工作,但很少有模型能够大幅度的超越 Faster R-CNN 。换句话说, Faster R-CNN 可能不是最简单或最快速的目标检测方法,但仍然是性能最好的方法之一。
比较流行的算法可以分为两类,
近年来,主要的目标检测算法已经转向更快、更高效的检测系统。这种趋势在 You Only Look Once(YOLO),Single Shot MultiBox Detector(SSD)和基于区域的全卷积网络( R-FCN )算法中尤为明显,这三种算法转向在整个图像上共享计算。因此,这三种算法和上述的3种造价较高的R-CNN 技术有所不同。
全称:You Only Look Once: Unified, Real-Time Object Detection
其中目标检测是一件比较实际的且具有挑战性的计算机视觉任务,其可以看成图像分类与定位的结合,给定一张图片,目标检测系统要能够识别出图片的目标并给出其位置,由于图片中目标数是不定的,且要给出目标的精确位置,目标检测相比分类任务更复杂。目标检测的一个实际应用场景就是无人驾驶,如果能够在无人车上装载一个有效的目标检测系统,那么无人车将和人一样有了眼睛,可以快速地检测出前面的行人与车辆,从而作出实时决策。
You Only Look Once说的是只需要一次CNN运算,
Unified指的是这是一个统一的框架,提供end-to-end的预测,
Real-Time体现是Yolo算法速度快。
Fast R CNN 尽管可以减少滑动窗口的计算量,但是只是针对一个固定大小与步长的窗口,这是远远不够的。Yolo算法很好的解决了这个问题,它不再是窗口滑动了,而是直接将原始图片分割成互不重合的小方块,然后通过卷积最后生产这样大小的特征图,基于上面的分析,可以认为特征图的每个元素也是对应原始图片的一个小方块,然后用每个元素来可以预测那些中心点在该小方格内的目标,这就是Yolo算法的朴素思想。下面将详细介绍Yolo算法的设计理念。
整体来看,Yolo算法采用一个单独的CNN模型实现end-to-end的目标检测,整个系统如图所示:
首先将输入图片resize到448x448,然后送入CNN网络,最后处理网络预测结果得到检测的目标。
相比R-CNN算法,其是一个统一的框架,其速度更快,而且Yolo的训练过程也是end-to-end的。
具体来说,Yolo的CNN网络将输入的图片分割成 SxS 网格,然后每个单元格负责去检测那些中心点落在该格子内的目标,如图 所示,可以看到狗这个目标的中心落在左下角一个单元格内,那么该单元格负责预测这个狗。
每个单元格会预测 B 个边界框(bounding box)以及边界框的置信度(confidence score)。
所谓置信度其实包含两个方面,
前者记为Pr(object) ,当该边界框是背景时(即不包含目标),此时 Pr=0 。
而当该边界框包含目标时, Pr=1 。
边界框的准确度可以用预测框与实际框(ground truth)的IOU(intersection over union,交并比)来表征,记为 I O U p r e d t r u t h IOU^{truth}_{pred} IOUpredtruth 。因此置信度可以定义为 P r ∗ I O U p r e d t r u t h Pr*IOU^{truth}_{pred} Pr∗IOUpredtruth 。
很多人可能将Yolo的置信度看成边界框是否含有目标的概率,但是其实它是两个因子的乘积,预测框的准确度也反映在里面。
边界框的大小与位置可以用4个值来表征:(x,y,w,h) ,其中 (x,y) 是边界框的中心坐标,而 w 和 h 是边界框的宽与高。还有一点要注意,中心坐标的预测值 (x,y) 是相对于每个单元格左上角坐标点的偏移值,并且单位是相对于单元格大小的。
而边界框的 w和 h 预测值是相对于整个图片的宽与高的比例,这样理论上4个元素的大小应该在 [0 1]范围。
这样,每个边界框的预测值实际上包含5个元素:(x,y,w,h,c) ,其中前4个表征边界框的大小与位置,而最后一个值是置信度。
还有目标分类问题,对于每一个单元格其还要给出预测出 C 个类别概率值,其表征的是由该单元格负责预测的边界框其目标属于各个类别的概率。
但是这些概率值其实是在各个边界框置信度下的条件概率,即 P r ( c l a s s ∣ o b j e c t ) Pr(class|object) Pr(class∣object)。
同时,我们可以计算出各个边界框类别置信度(class-specific confidence scores):
P r ( c l a s s ∣ o b j e c t ) ∗ P r ( o b j e c t ) ∗ I O U p t = P r ( c l a s s ) ∗ I O U p t Pr(class|object)*Pr(object)*IOU^{t}_p=Pr(class)*IOU^t_p Pr(class∣object)∗Pr(object)∗IOUpt=Pr(class)∗IOUpt
边界框类别置信度表征的是该边界框中目标属于各个类别的可能性大小以及边界框匹配目标的好坏。后面会说,一般会根据类别置信度来过滤网络的预测框。
总结一下,每个单元格需要预测(B5+C)个值。如果将输入图片划分为S x S网格,那么最终预测值为SxSx(B5+C)大小的张量。整个模型的预测值结构如下图所示。
对于PASCAL VOC数据,其共有20个类别,如果使用 S=7 B=2,那么最终的预测结果就是 7x7x30 大小的张量。在下面的网络结构中我们会详细讲述每个单元格的预测值的分布位置。
网络设计
Yolo采用卷积网络来提取特征,然后使用全连接层来得到预测值。网络结构参考GooLeNet模型,包含24个卷积层和2个全连接层,如图所示。对于卷积层,主要使用1x1卷积来做channle reduction,然后紧跟3x3卷积。对于卷积层和全连接层,采用Leaky ReLU激活函数: m a x ( x , 0.1 x ) max(x,0.1x) max(x,0.1x) 。但是最后一层却采用线性激活函数。
可以看到网络的最后输出为 7x7x30 大小的张量。这和前面的讨论是一致的。这个张量所代表的具体含义如图所示。
对于每一个单元格,前20个元素是类别概率值,然后2个元素是边界框置信度,两者相乘可以得到类别置信度,最后8个元素是边界框的(x,y,w,h)。
大家可能会感到奇怪,对于边界框为什么把置信度 c和 (x,y,w,h) 都分开排列,而不是按照(x,y,w,h,c) 这样排列,其实纯粹是为了计算方便,因为实际上这30个元素都是对应一个单元格,其排列是可以任意的。但是分离排布,可以方便地提取每一个部分。这里来解释一下,首先网络的预测值是一个二维张量P ,其shape为[batch ,7x7x30]。采用切片,那么P(:,0:7x7x20)就是类别概率部分,而 P(:,7x7x20:7x7x22) 是置信度部分,最后剩余部分 P(:,7x7x22:)是边界框的预测结果。这样,提取每个部分是非常方便的,这会方面后面的训练及预测时的计算。
网络训练
在训练之前,先在ImageNet上进行了预训练,其预训练的分类模型采用图中前20个卷积层,然后添加一个average-pool层和全连接层。
预训练之后,在预训练得到的20层卷积层之上加上随机初始化的4个卷积层和2个全连接层。由于检测任务一般需要更高清的图片,所以将网络的输入从224x224增加到了448x448。整个网络的流程如下图所示:
下面是训练损失函数的分析,Yolo算法将目标检测看成回归问题,所以采用的是均方差损失函数。但是对不同的部分采用了不同的权重值。首先区分定位误差和分类误差。对于定位误差,即边界框坐标预测误差,采用较大的权重
然后其区分不包含目标的边界框与含有目标的边界框的置信度,对于前者,采用较小的权重值
其它权重值均设为1。
然后采用均方误差,其同等对待大小不同的边界框,但是实际上较小的边界框的坐标误差应该要比较大的边界框要更敏感。为了保证这一点,将网络的边界框的宽与高预测改为对其平方根的预测,即预测值变为
另外一点时,由于每个单元格预测多个边界框。但是其对应类别只有一个。那么在训练时,如果该单元格内确实存在目标,那么只选择与ground truth的IOU最大的那个边界框来负责预测该目标,而其它边界框认为不存在目标。这样设置的一个结果将会使一个单元格对应的边界框更加专业化,其可以分别适用不同大小,不同高宽比的目标,从而提升模型性能。大家可能会想如果一个单元格内存在多个目标怎么办,其实这时候Yolo算法就只能选择其中一个来训练,这也是Yolo算法的缺点之一。要注意的一点时,对于不存在对应目标的边界框,其误差项就是只有置信度,坐标项误差是没法计算的。而只有当一个单元格内确实存在目标时,才计算分类误差项,否则该项也是无法计算的。
综上讨论,最终的损失函数计算如下:
其中第一项是边界框中心坐标的误差项, 1 i j o b j 1^{obj}_{ij} 1ijobj指的是第i 个单元格存在目标,且该单元格中的第 j个边界框负责预测该目标。第二项是边界框的高与宽的误差项。第三项是包含目标的边界框的置信度误差项。第四项是不包含目标的边界框的置信度误差项。而最后一项是包含目标的单元格的分类误差项, 1 i o b j 1^{obj}_{i} 1iobj指的是第 i 个单元格存在目标。
这里特别说一下置信度的target值C,如果是不存在目标,此时由于Pr=0,那么 C=0 。如果存在目标, Pr=1 ,此时需要确定 I O U p t IOU^t_p IOUpt ,当然你希望最好的话,可以将IOU取1,这样C=1,但是在YOLO实现中,使用了一个控制参数rescore(默认为1),当其为1时,IOU不是设置为1,而就是计算truth和pred之间的真实IOU。不过很多复现YOLO的项目还是取C =1 ,这个差异应该不会太影响结果吧。
在说明Yolo算法的预测过程之前,这里先介绍一下非极大值抑制算法(non maximum suppression, NMS),这个算法不单单是针对Yolo算法的,而是所有的检测算法中都会用到。NMS算法主要解决的是一个目标被多次检测的问题,如图11中人脸检测,可以看到人脸被多次检测,但是其实我们希望最后仅仅输出其中一个最好的预测框,比如对于美女,只想要红色那个检测结果。那么可以采用NMS算法来实现这样的效果:首先从所有的检测框中找到置信度最大的那个框,然后挨个计算其与剩余框的IOU,如果其值大于一定阈值(重合度过高),那么就将该框剔除;然后对剩余的检测框重复上述过程,直到处理完所有的检测框。Yolo预测过程也需要用到NMS算法。
下面就来分析Yolo的预测过程,这里我们不考虑batch,认为只是预测一张输入图片。根据前面的分析,最终的网络输出是[7,7,30] ,但是我们可以将其分割成三个部分:类别概率部分为 [7,7,20] ,置信度部分为 [7,7,2] ,而边界框部分为 [7,7,2,4] (对于这部分不要忘记根据原始图片计算出其真实值)。然后将前两项相乘(矩阵 [7,7,20] 乘以 [7,7,2] 可以各补一个维度来完成[7,7,1,20] 乘以 [7,7,2,1] )可以得到类别置信度值为 [7,7,2,20] ,这里总共预测了7x7x2=98个边界框。
所有的准备数据已经得到了,那么我们先说
第一种策略来得到检测框的结果,我认为这是最正常与自然的处理。首先,对于每个预测框根据类别置信度选取置信度最大的那个类别作为其预测标签,经过这层处理我们得到各个预测框的预测类别及对应的置信度值,其大小都是 [7,7,2] 。一般情况下,会设置置信度阈值,就是将置信度小于该阈值的box过滤掉,所以经过这层处理,剩余的是置信度比较高的预测框。最后再对这些预测框使用NMS算法,最后留下来的就是检测结果。一个值得注意的点是NMS是对所有预测框一视同仁,还是区分每个类别,分别使用NMS。Ng在deeplearning.ai中讲应该区分每个类别分别使用NMS,但是看了很多实现,其实还是同等对待所有的框,我觉得可能是不同类别的目标出现在相同位置这种概率很低吧。
上面的预测方法应该非常简单明了,但是对于Yolo算法,其却采用了另外一个不同的处理思路(至少从C源码看是这样的),其区别就是先使用NMS,然后再确定各个box的类别。其基本过程如图12所示。对于98个boxes,首先将小于置信度阈值的值归0,然后分类别地对置信度值采用NMS,这里NMS处理结果不是剔除,而是将其置信度值归为0。最后才是确定各个box的类别,当其置信度值不为0时才做出检测结果输出。这个策略不是很直接,但是貌似Yolo源码就是这样做的。Yolo论文里面说NMS算法对Yolo的性能是影响很大的,所以可能这种策略对Yolo更好。但是我测试了普通的图片检测,两种策略结果是一样的。
算法性能分析
这里看一下Yolo算法在PASCAL VOC 2007数据集上的性能,这里Yolo与其它检测算法做了对比,包括DPM,R-CNN,Fast R-CNN以及Faster R-CNN。其对比结果如表1所示。与实时性检测方法DPM对比,可以看到Yolo算法可以在较高的mAP上达到较快的检测速度,其中Fast Yolo算法比快速DPM还快,而且mAP是远高于DPM。但是相比Faster R-CNN,Yolo的mAP稍低,但是速度更快。所以。Yolo算法算是在速度与准确度上做了折中。
为了进一步分析Yolo算法,文章还做了误差分析,将预测结果按照分类与定位准确性分成以下5类:
Correct:类别正确,IOU>0.5;(准确度)
Localization:类别正确,0.1 < IOU<0.5(定位不准);
Similar:类别相似,IOU>0.1;
Other:类别错误,IOU>0.1;
Background:对任何目标其IOU<0.1。(误把背景当物体)
现在来总结一下Yolo的优缺点。首先是优点,Yolo采用一个CNN网络来实现检测,是单管道策略,其训练与预测都是end-to-end,所以Yolo算法比较简洁且速度快。第二点由于Yolo是对整张图片做卷积,所以其在检测目标有更大的视野,它不容易对背景误判。其实我觉得全连接层也是对这个有贡献的,因为全连接起到了attention的作用。另外,Yolo的泛化能力强,在做迁移时,模型鲁棒性高。
最后不得不谈一下Yolo的缺点,首先Yolo各个单元格仅仅预测两个边界框,而且属于一个类别。对于小物体,Yolo的表现会不如人意。这方面的改进可以看SSD,其采用多尺度单元格。也可以看Faster R-CNN,其采用了anchor boxes。Yolo对于在物体的宽高比方面泛化率低,就是无法定位不寻常比例的物体。当然Yolo的定位不准确也是很大的问题。
这篇长文详细介绍了Yolo算法的原理及实现,当然Yolo-v1还是有很多问题的,所以后续可以读读Yolo9000算法,看看其如何改进的。Ng说Yolo的paper是比较难读的,其实是很多实现细节,如果不看代码是很难理解的。
YOLOv2的论文全名为YOLO9000: Better, Faster, Stronger,它斩获了CVPR 2017 Best Paper Honorable Mention
在这篇文章中,作者首先在YOLOv1的基础上提出了改进的YOLOv2,然后提出了一种检测与分类联合训练方法,使用这种联合训练方法在COCO检测数据集和ImageNet分类数据集上训练出了YOLO9000模型,其可以检测超过9000多类物体。所以,这篇文章其实包含两个模型:YOLOv2和YOLO9000,不过后者是在前者基础上提出的,两者模型主体结构是一致的。YOLOv2相比YOLOv1做了很多方面的改进,这也使得YOLOv2的mAP有显著的提升,并且YOLOv2的速度依然很快,保持着自己作为one-stage方法的优势,YOLOv2和Faster R-CNN, SSD等模型的对比如图1所示。这里将首先介绍YOLOv2的改进策略,并给出YOLOv2的TensorFlow实现过程,然后介绍YOLO9000的训练方法。近期,YOLOv3也放出来了,YOLOv3也在YOLOv2的基础上做了一部分改进,我们在最后也会简单谈谈YOLOv3所做的改进工作。
YOLOv1虽然检测速度很快,但是在检测精度上却不如R-CNN系检测方法,YOLOv1在物体定位方面(localization)不够准确,并且召回率(recall)较低。YOLOv2共提出了几种改进策略来提升YOLO模型的定位准确度和召回率,从而提高mAP,YOLOv2在改进中遵循一个原则:保持检测速度,这也是YOLO模型的一大优势。YOLOv2的改进策略如图2所示,可以看出,大部分的改进方法都可以比较显著提升模型的mAP。下面详细介绍各个改进策略。
YOLOv2相比YOLOv1的改进策略
总结来看,虽然YOLOv2做了很多改进,但是大部分都是借鉴其它论文的一些技巧,如Faster R-CNN的anchor boxes,YOLOv2采用anchor boxes和卷积做预测,这基本上与SSD模型(单尺度特征图的SSD)非常类似了,而且SSD也是借鉴了Faster R-CNN的RPN网络。从某种意义上来说,YOLOv2和SSD这两个one-stage模型与RPN网络本质上无异,只不过RPN不做类别的预测,只是简单地区分物体与背景。在two-stage方法中,RPN起到的作用是给出region proposals,其实就是作出粗糙的检测,所以另外增加了一个stage,即采用R-CNN网络来进一步提升检测的准确度(包括给出类别预测)。而对于one-stage方法,它们想要一步到位,直接采用“RPN”网络作出精确的预测,要因此要在网络设计上做很多的tricks。YOLOv2的一大创新是采用Multi-Scale Training策略,这样同一个模型其实就可以适应多种大小的图片了。
通过联合训练策略,YOLO9000可以快速检测出超过9000个类别的物体,总体mAP值为19,7%。我觉得这是作者在这篇论文作出的最大的贡献,因为YOLOv2的改进策略亮点并不是很突出,但是YOLO9000算是开创之举。
相比YOLOv2,我觉得YOLOv3最大的变化包括两点:使用残差模型和采用FPN架构。YOLOv3的特征提取器是一个残差模型,因为包含53个卷积层,所以称为Darknet-53,从网络结构上看,相比Darknet-19网络使用了残差单元,所以可以构建得更深。另外一个点是采用FPN架构(Feature Pyramid Networks for Object Detection)来实现多尺度检测。
从YOLO的三代变革中可以看到,在目标检测领域比较好的策略包含:设置先验框,采用全卷积做预测,采用残差网络,采用多尺度特征图做预测。
https://zhuanlan.zhihu.com/p/35325884
https://zhuanlan.zhihu.com/p/32525231
目标跟踪,是指在特定场景跟踪某一个或多个特定感兴趣对象的过程。现在,目标跟踪在无人驾驶领域也很重要,例如 Uber 和特斯拉等公司的无人驾驶。
根据观察模型,目标跟踪算法可分成 2 类:生成算法和判别算法。
为了通过检测实现跟踪,我们检测所有帧的候选对象,并使用深度学习从候选对象中识别想要的对象。有两种可以使用的基本网络模型:堆叠自动编码器( SAE )和卷积神经网络( CNN )。
目前,最流行的使用 SAE 进行目标跟踪的网络是 Deep Learning Tracker(DLT),它使用了离线预训练和在线微调。其过程如下:
鉴于 CNN 在图像分类和目标检测方面的优势,它已成为计算机视觉和视觉跟踪的主流深度模型。 一般来说,大规模的卷积神经网络既可以作为分类器和跟踪器来训练。具有代表性的基于卷积神经网络的跟踪算法有全卷积网络跟踪器( FCNT )和多域卷积神经网络( MD Net )。
FCNT 充分分析并利用了 VGG 模型中的特征映射,这是一种预先训练好的 ImageNet 数据集,并有如下效果:
因此, FCNT 设计了特征选择网络,在 VGG 网络的卷积 4-3 和卷积 5-3 层上选择最相关的特征映射。 然后为避免噪音的过拟合, FCNT 还为这两个层的选择特征映射单独设计了两个额外的通道(即 SNet 和 GNet ): GNet 捕获对象的类别信息; SNet 将该对象从具有相似外观的背景中区分出来。
这两个网络的运作流程如下:都使用第一帧中给定的边界框进行初始化,以获取对象的映射。而对于新的帧,对其进行剪切并传输最后一帧中的感兴趣区域,该感兴趣区域是以目标对象为中心。最后,通过 SNet 和 GNet ,分类器得到两个预测热映射,而跟踪器根据是否存在干扰信息,来决定使用哪张热映射生成的跟踪结果。 FCNT 的图如下所示。
与 FCNT 的思路不同, MD Net 使用视频的所有序列来跟踪对象的移动。上述网络使用不相关的图像数据来减少跟踪数据的训练需求,并且这种想法与跟踪有一些偏差。该视频中的一个类的对象可以是另一个视频中的背景,因此, MD Net 提出了“多域”这一概念,它能够在每个域中独立的区分对象和背景,而一个域表示一组包含相同类型对象的视频。
如下图所示, MD Net 可分为两个部分,即 K 个特定目标分支层和共享层:每个分支包含一个具有 softmax 损失的二进制分类层,用于区分每个域中的对象和背景;共享层与所有域共享,以保证通用表示。
近年来,深度学习研究人员尝试使用了不同的方法来适应视觉跟踪任务的特征,并且已经探索了很多方法:
应用到诸如循环神经网络( RNN )和深度信念网络(DBN )等其他网络模型;
设计网络结构来适应视频处理和端到端学习,优化流程、结构和参数;
或者将深度学习与传统的计算机视觉或其他领域的方法(如语言处理和语音识别)相结合。
计算机视觉的核心是分割,它将整个图像分成一个个像素组,然后对其进行标记和分类。特别地,语义分割试图在语义上理解图像中每个像素的角色(比如,识别它是汽车、摩托车还是其他的类别)。如上图所示,除了识别人、道路、汽车、树木等之外,我们还必须确定每个物体的边界。因此,与分类不同,我们需要用模型对密集的像素进行预测。
与其他计算机视觉任务一样,卷积神经网络在分割任务上取得了巨大成功。最流行的原始方法之一是通过滑动窗口进行块分类,利用每个像素周围的图像块,对每个像素分别进行分类。但是其计算效率非常低,因为我们不能在重叠块之间重用共享特征。
解决方案就是加州大学伯克利分校提出的全卷积网络( FCN ),它提出了端到端的卷积神经网络体系结构,在没有任何全连接层的情况下进行密集预测。
这种方法允许针对任何尺寸的图像生成分割映射,并且比块分类算法快得多,几乎后续所有的语义分割算法都采用了这种范式。
但是,这也仍然存在一个问题:在原始图像分辨率上进行卷积运算非常昂贵。为了解决这个问题, FCN 在网络内部使用了下采样和上采样:下采样层被称为条纹卷积( striped convolution );而上采样层被称为反卷积( transposed convolution )。
尽管采用了上采样和下采样层,但由于池化期间的信息丢失, FCN 会生成比较粗糙的分割映射。 SegNet 是一种比 FCN (使用最大池化和编码解码框架)更高效的内存架构。在 SegNet 解码技术中,从更高分辨率的特征映射中引入了 shortcut/skip connections ,以改善上采样和下采样后的粗糙分割映射。
目前的语义分割研究都依赖于完全卷积网络,如空洞卷积 ( Dilated Convolutions ),DeepLab 和 RefineNet 。
除了语义分割之外,实例分割将不同类型的实例进行分类,比如用 5 种不同颜色来标记 5 辆汽车。分类任务通常来说就是识别出包含单个对象的图像是什么,但在分割实例时,我们需要执行更复杂的任务。我们会看到多个重叠物体和不同背景的复杂景象,我们不仅需要将这些不同的对象进行分类,而且还要确定对象的边界、差异和彼此之间的关系!
到目前为止,我们已经看到了如何以多种有趣的方式使用卷积神经网络的特征,通过边界框有效定位图像中的不同对象。我们可以将这种技术进行扩展吗?也就是说,对每个对象的精确像素进行定位,而不仅仅是用边界框进行定位? Facebook AI 则使用了 Mask R-CNN 架构对实例分割问题进行了探索。
就像 Fast R-CNN 和 Faster R-CNN 一样, Mask R-CNN 的底层是鉴于 Faster R-CNN 在物体检测方面效果很好,我们是否可以将其扩展到像素级分割?
Mask R-CNN 通过向 Faster R-CNN 添加一个分支来进行像素级分割,该分支输出一个二进制掩码,该掩码表示给定像素是否为目标对象的一部分:该分支是基于卷积神经网络特征映射的全卷积网络。将给定的卷积神经网络特征映射作为输入,输出为一个矩阵,其中像素属于该对象的所有位置用 1 表示,其他位置则用 0 表示,这就是二进制掩码。
另外,当在原始 Faster R-CNN 架构上运行且没有做任何修改时,感兴趣池化区域( RoIPool ) 选择的特征映射区域或原始图像的区域稍微错开。由于图像分割具有像素级特性,这与边界框不同,自然会导致结果不准确。 Mas R-CNN 通过调整 RoIPool 来解决这个问题,使用
感兴趣区域对齐( Roialign )方法使其变的更精确。本质上, RoIlign 使用双线性插值来避免舍入误差,这会导致检测和分割不准确。
一旦生成这些掩码, Mask R-CNN 将 RoIAlign 与来自 Faster R-CNN 的分类和边界框相结合,以便进行精确的分割:
https://github.com/khanhnamle1994/computer-vision
https://cloud.tencent.com/developer/article/1109237