传统目标检测算法处理:
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.结合空间金字塔方法实现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直接训练得到候选区域
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.对于属于某一类别的候选框,用回归器进一步调整其位置
Faster-RCNN损失函数
Faster-rcnn中RPN网络的损失函数为分类损失与回归损失的总和,其表达式如下:
分类损失使用交叉熵损失函数计算,需要注意的是分类损失计算的是所有样本的平均损失,参数就是样本总数量,隐含在输入参数中,通常为256。
回归损失则使用上述的Smoooh L1 Loss计算。
下面先介绍一下Smoooh L1 Loss损失由来
L2 loss(平方损失)
RPN网络中对于边框的预测是一个回归问题,通常可以选择平方损失函数,即L2损失。但是当预测值与目标值相差很大时,容易产生梯度爆炸。
L1 loss(绝对值损失)
我们可以采用稍微缓和一点的绝对损失函数,即L1损失。它随着误差线性增长,而不是平方增长。但这个函数在0点处导数不存在,因此可能会影响收敛。
针对上述两个损失的优缺点,我们使用一个分段函数来作为RPN网络的损失函数。此函数在0点附近使用平方损失函数,这样使得它更加平滑,因此被称为平滑L1损失函数,即:Smoooh L1 Loss,表达式如下:
通常情况下,会增加一个参数来控制平滑的区域,则表达式变为如下形式:
YOLO算法:
给个⼀个输⼊图像,⾸先将图像划分成7*7的⽹格,每个网格要预测两个bounding box的坐标(x,y,w,h)和box内包含物体的置信度confidence,以及物体属于20类别中每一类的概率(yolo的训练数据为voc2012,它是一个20分类的数据集)。所以一个网格对应的参数为(4x2+2+20) = 30。如下图
对于YOLO V5,无论是V5s,V5m,V5l还是V5x其Backbone,Neck和Head一致。唯一的区别在与模型的深度和宽度设置,只需要修改这两个参数就可以调整模型的网络结构。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