目标检测算法总结

传统目标检测算法处理:

1)区域选择(穷举策略:采用滑动窗口,且设置不同的大小,不同的长宽比对图像进行遍历,时间复杂度高)

2)特征提取(SIFT、HOG等;形态多样性、光照变化多样性、背景多样性使得特征鲁棒性差)

3)分类器分类(主要有SVM、Adaboost等)

对一张图片,用各种大小的框(遍历整张图片)将图片截取出来,输入到CNN,然后CNN会输出这个框的得分(classification)以及这个框图片对应的x,y,h,w(regression)。

1)基于滑动窗口的区域选择策略没有针对性,时间复杂度高,窗口冗余

2)手工设计的特征对于多样性的变化没有很好的鲁棒性

看做classification, 有没有办法优化下?我可不想试那么多框那么多位置啊

        总结就是:区域选择太多。

由此引出了R-CNN方法:

 利用选择性搜索Selective Search算法在图像中从下到上提取2000个左右的可能包含物体的候选区域Region Proposal

因为取出的区域大小各自不同,所以需要将每个Region Proposal缩放(warp)(可以通过resize实现)成统一的227x227的大小并输入到CNN,将CNN的fc层的输出作为特征。

将每个Region Proposal提取到的CNN特征输入到SVM进行分类。

总结就是:通过Selective Search算法在图像上提取2000个左右的候选区域Region Proposal。

然后将每个Region Proposal缩放(warp)(可以通过resize实现)成统一的227x227的大小并输入到CNN。因为CNN是固定输入,固定输出,而全连接层需要固定输入,所以需要对Region Proposal 执行resize到统一尺寸。

但是还是有个缺点:R-CNN虽然不再像传统方法那样穷举,但R-CNN流程的第一步中对原始图片通过Selective Search提取的候选框region proposal多达2000个左右,而这2000个候选框每个框都需要进行CNN提特征+SVM分类,计算量很大,导致R-CNN检测速度很慢,一张图都需要47s。而且将不同大小的候选区域resize到统一大小导致的问题要么被拉伸变形、要么物体不全,限制了识别精确度。

这2000个region proposal不都是图像的一部分吗,那么我们完全可以对图像提一次卷积层特征,然后只需要将region proposal在原图的位置映射到卷积层特征图上,这样对于一张图像我们只需要提一次卷积层特征,然后将每个region proposal的卷积层特征输入到全连接层做后续操作。

但是每个region proposal尺寸大小不一样,而全连接层需要固定大小输入。region proposal不是图像,因此我们没办法采用resize方式处理成统一大小。

由此引出了SPP Net:

R-CNN和SPP Net检测流程的比较:

目标检测算法总结_第1张图片

1.结合空间金字塔方法实现CNNs的多尺度输入。

SPP Net的第一个贡献就是在最后一个卷积层后,接入了金字塔池化层,保证传到下一层全连接层的输入固定。

换句话说,在普通的CNN机构中,输入图像的尺寸往往是固定的(比如224*224像素),输出则是一个固定维数的向量。SPP Net在普通的CNN结构中加入了ROI池化层(ROI Pooling),使得网络的输入图像可以是任意尺寸的,输出则不变,同样是一个固定维数的向量。

简言之,CNN原本只能固定输入、固定输出,CNN加上SSP之后,便能任意输入、固定输出。神奇吧?

ROI池化层一般跟在卷积层后面,此时网络的输入可以是任意尺度的,在SPP layer中每一个pooling的filter会根据输入调整大小,而SPP的输出则是固定维数的向量,然后给到全连接FC层。

总结:通过执行一次卷积特征提取,然后将region proposal在原图的位置映射到卷积层特征图上。再加上利用SPP NET空间金字塔实现任意输入、固定输出,Fast-RCNN就是这样实现的。

R-CNN与Fast R-CNN的区别有哪些呢?

先说R-CNN的缺点:即使使用了Selective Search等预处理步骤来提取潜在的边界框bounding box作为输入,但是R-CNN仍会有严重的速度瓶颈,原因也很明显,就是计算机对所有region进行特征提取时会有重复计算,Fast-RCNN正是为了解决这个问题诞生的。

与R-CNN框架图对比,可以发现主要有两处不同:一是最后一个卷积层后加了一个ROI pooling layer,二是损失函数使用了多任务损失函数(multi-task loss),将边框回归Bounding Box Regression直接加入到CNN网络中训练(关于什么是边框回归,请参看本深度学习分类下第56题:https://www.julyedu.com/question/big/kp_id/26/ques_id/2139)。

也就是说,之前R-CNN的处理流程是先提proposal,然后CNN提取特征,之后用SVM分类器,最后再做box regression,而在Fast R-CNN中,作者巧妙的把box regression放进了神经网络内部,与region分类(用softmax)和并成为了一个multi-task模型,实际实验也证明,这两个任务能够共享卷积特征,并相互促进。

R-CNN有一些相当大的缺点(把这些缺点都改掉了,就成了Fast R-CNN)。

大缺点:由于每一个候选框都要独自经过CNN,这使得花费的时间非常多。

解决:共享卷积层,现在不是每一个候选框都当做输入进入CNN了,而是输入一张完整的图片,在第五个卷积层再得到每个候选框的特征

原来的方法:许多候选框(比如两千个)-->CNN-->得到每个候选框的特征-->分类+回归

现在的方法:一张完整图片-->CNN-->得到每张候选框的特征-->分类+回归

所以容易看见,Fast R-CNN相对于R-CNN的提速原因就在于:不过不像R-CNN把每个候选区域给深度网络提特征,而是整张图提一次特征,再把候选框映射到conv5上,而SPP只需要计算一次特征,剩下的只需要在conv5层上操作就可以了。

Fast R-CNN存在的问题:存在瓶颈:选择性搜索,找出所有的候选框,这个也非常耗时。那我们能不能找出一个更加高效的方法来求出这些候选框呢?

解决:加入一个提取边缘的神经网络,也就说找到候选框的工作也交给神经网络来做了。在Fast R-CNN中引入Region Proposal Network(RPN)替代Selective Search,同时引入anchor box应对目标形状的变化问题(anchor就是位置和大小固定的box,可以理解成事先设置好的固定的proposal)。

具体做法:

• 将RPN放在最后一个卷积层的后面

• RPN直接训练得到候选区域

目标检测算法总结_第2张图片

RPN简介:

• 在feature map上滑动窗口

• 建一个神经网络用于物体分类+框位置的回归

• 滑动窗口的位置提供了物体的大体位置信息

• 框的回归提供了框更精确的位置

总结:

最后总结一下各大算法的步骤:

RCNN

1.在图像中确定约1000-2000个候选框 (使用选择性搜索Selective Search)

2.每个候选框内图像块缩放至相同大小,并输入到CNN内进行特征提取 

3.对候选框中提取出的特征,使用分类器判别是否属于一个特定类 

4.对于属于某一类别的候选框,用回归器进一步调整其位置

Fast R-CNN

1.在图像中确定约1000-2000个候选框 (使用选择性搜索)

2.对整张图片输进CNN,得到feature map

3.找到每个候选框在feature map上的映射patch,将此patch作为每个候选框的卷积特征输入到SPP layer和之后的层

4.对候选框中提取出的特征,使用分类器判别是否属于一个特定类 

5.对于属于某一类别的候选框,用回归器进一步调整其位置

Faster R-CNN

1.对整张图片输进CNN,得到feature map

2.卷积特征输入到RPN,得到候选框的特征信息

3.对候选框中提取出的特征,使用分类器判别是否属于一个特定类 

4.对于属于某一类别的候选框,用回归器进一步调整其位置

目标检测算法总结_第3张图片

Faster-RCNN损失函数

Faster-rcnn中RPN网络的损失函数为分类损失与回归损失的总和,其表达式如下:

分类损失使用交叉熵损失函数计算,需要注意的是分类损失计算的是所有样本的平均损失,N_{cls}参数就是样本总数量,隐含在输入参数中,通常为256。

回归损失则使用上述的Smoooh L1 Loss计算。

下面先介绍一下Smoooh L1 Loss损失由来

L2   loss(平方损失)

RPN网络中对于边框的预测是一个回归问题,通常可以选择平方损失函数,即L2损失。但是当预测值与目标值相差很大时,容易产生梯度爆炸。

L1  loss(绝对值损失)

我们可以采用稍微缓和一点的绝对损失函数,即L1损失。它随着误差线性增长,而不是平方增长。但这个函数在0点处导数不存在,因此可能会影响收敛。

Smoooh L1 Loss

针对上述两个损失的优缺点,我们使用一个分段函数来作为RPN网络的损失函数。此函数在0点附近使用平方损失函数,这样使得它更加平滑,因此被称为平滑L1损失函数,即:Smoooh L1 Loss,表达式如下:

目标检测算法总结_第4张图片

通常情况下,会增加一个\sigma参数来控制平滑的区域,则表达式变为如下形式: 

目标检测算法总结_第5张图片

YOLO算法:

给个⼀个输⼊图像,⾸先将图像划分成7*7的⽹格,每个网格要预测两个bounding box的坐标(x,y,w,h)和box内包含物体的置信度confidence,以及物体属于20类别中每一类的概率(yolo的训练数据为voc2012,它是一个20分类的数据集)。所以一个网格对应的参数为(4x2+2+20) = 30。如下图 

目标检测算法总结_第6张图片

目标检测算法总结_第7张图片

  • 使用Pytorch框架,对用户非常友好,能够方便地训练自己的数据集,相对于YOLO V4采用的Darknet框架,Pytorch框架更容易投入生产
  • 代码易读,整合了大量的计算机视觉技术,非常有利于学习和借鉴
  • 不仅易于配置环境,模型训练也非常快速,并且批处理推理产生实时结果
  • 能够直接对单个图像,批处理图像,视频甚至网络摄像头端口输入进行有效推理
  • 能够轻松的将Pytorch权重文件转化为安卓使用的ONXX格式,然后可以转换为OPENCV的使用格式,或者通过CoreML转化为IOS格式,直接部署到手机应用端
  • 最后YOLO V5s高达140FPS的对象识别速度令人印象非常深刻,使用体验非常棒

对于YOLO V5,无论是V5s,V5m,V5l还是V5x其BackboneNeckHead一致。唯一的区别在与模型的深度和宽度设置,只需要修改这两个参数就可以调整模型的网络结构。V5l 的参数是默认参数。

一阶段算法与二阶段算法的理解

第一,one-stage算法从网络结构上看只是一个多分类的rpn网络,相当于faster rcnn的第一阶段。其预测结果是从feature map中anchor对应的特征中预测得到的,而two-stage会对上述结果再进行roi pooling之后进一步精细化,因此更为精准。比如,一个anchor有可能只覆盖了一个目标的50%,但却作为完全的正样本,因此其预测肯定是有误差的。

第二,one-stage算法对小目标检测效果较差,如果所有的anchor都没有覆盖到这个目标,那么这个目标就会漏检。如果一个比较大的anchor覆盖了这个目标,那么较大的感受野会弱化目标的真实特征,得分也不会高。two-stage算法中的roi pooling会对目标做resize, 小目标的特征被放大,其特征轮廓也更为清晰,因此检测也更为准确。

yolov5中的focus:

YOLOv5从入门到部署之:网络和损失函数 - 知乎

参考:

[1] Yolov5 系列1--- Yolo发展史以及Yolov5模型详解_sooner高的博客-CSDN博客_yolov5模型介绍

[2] 一文读懂YOLO V5 与 YOLO V4 - 知乎

[3] https://www.zhihu.com/question/266143762/answer/304039469

你可能感兴趣的:(简历项目分析,计算机视觉,目标检测,深度学习,神经网络)