要了解目标检测问题,先要了解图像的分类与定位问题,可以看到下图中,分类与预测一般是同一个网络下,经过不同的全连接而生成的不同结果,一边是分类,评价分数,另一边是对检测位置标框,进行回归计算,这里的L2 Loss为测量两个张量之间或张量与0之间的误差。,这些可以用于测量回归任务中的网络的精确度,最后的损失函数将二者相加,这样就完成了整个模型:
这里说一下回归与分类的区别,回归其实是分类的连续化,如预测房价、未来的天气情况等等,例如一个产品的实际价格为500元,通过回归分析预测值为499元,我们认为这是一个比较好的回归分析。一个比较常见的回归算法是线性回归算法(LR)。另外,回归分析用在神经网络上,其最上层是不需要加上softmax函数的,而是直接对前一层累加即可。回归是对真实值的一种逼近预测;而分类问题是用于将事物打上一个标签,通常结果为离散值。
回归中我们将预测与正确(groundtruth)候选框用4各参数表示:x,y表示候选框左上角坐标位置;w,h表示候选框宽与高。这两者之间差值损失就是候选框预测损失。
后来看了一下里面的边框回归的含义,有一个文章解释边框回归的比较好:https://blog.csdn.net/zijin0802034/article/details/77685438
只是其中我认为里面预测与真实边框坐标差值处以框宽与框高是要对应尺度,因为普通的相减会因为框的大小为失去意义。最后的损失函数与优化函数为:
Φ 5 ( P ) Φ5(P) Φ5(P)是输入 Proposal 的特征向量, w ∗ w∗ w∗是要学习的参数( ∗ * ∗表示 x , y , w , h x,y,w,h x,y,w,h, 也就是每一个变换对应一个目标函数) , w T ∗ Φ 5 ( P ) w^T∗Φ5(P) wT∗Φ5(P) 是得到的预测值。,我们要让预测值跟真实值 t ∗ = ( t x , t y , t w , t h ) t∗=(tx,ty,tw,th) t∗=(tx,ty,tw,th)差距最小,而里面的 w T ∗ Φ 5 ( P ) w^T∗Φ5(P) wT∗Φ5(P)与 t ∗ = ( t x , t y , t w , t h ) t∗=(tx,ty,tw,th) t∗=(tx,ty,tw,th)都是偏移量。
其实一张图片中可能出现很多种物体的情况:
如果我们再进行回归,参数就太多了,那么假如将目标检测不看成是回归问题,而是看成分类问题,下面的滑窗思想就可以很好的解释分类结果:
上图可以看出就是通过在图片中裁剪不同的框,分别判别是否为背景与物体的分类。
上面所展示出的框可以说是非常非常多的,那么对这些框的筛选就是一个大问题,这里面的方法革新就要说到选择性搜索(Selective Search),它将之前的方法进行融合创新,这个方法优点在于:捕捉不同尺度(Capture All Scales)、多样化(Diversification)、快速计算(Fast to Compute)。
总结为:选择性搜索是用于目标检测的区域提议算法,它计算速度快,具有很高的召回率,基于颜色,纹理,大小和形状兼容计算相似区域的分层分组。
具体操作是使用Felzenszwalb and Huttenlocher的方法对图像找出相似区域(通过像素相近的聚合方法),再使用贪心算法对区域迭代分组:
这样就可以将原图通过区域预测出包含物体或者背景的少数框,但是框数依然可能很多,一张图可能有2000个左右。
R-CNN方法就是将上面的选择性搜索与卷积神经网络进行结合,将选择性搜索所得到的图形丢入卷积神经网络中,输出分类结果(目标或背景),另一个就是对选择性搜索出来的框使用回归进行微调:
大概说一下详细过程:先将所有选择性搜索出来的框保存下来,使用一个分类模型专门学习目标与背景分类,再通过回归对搜索出来的区域进行调整,使其更加完美。
但是R-CNN也有很多缺点:
针对R-CNN中的难点,一个是每次都要单独将区域保存下来,并且单独送入CNN,另一个是每次保存下来的图片都要重新调整大小到同样尺寸,SPPNet对之进行了很好的改进,它的思想是这样的:
上图中将一张图片先送入卷积层得到最后一层卷积层的结果特征图,然后对特征图规定同样大小,比如最后输出为256通道,那么针对每个通道,都进行一次 16 ∗ 16 16*16 16∗16、 4 ∗ 4 4*4 4∗4、 1 ∗ 1 1*1 1∗1最大池化,将输出堆叠起来,再送入全连接层分类,可以大大减少R-CNN需要保存的空间,也将输出统一了尺度,这个方法也是接下来要讲的Fast R-CNN的ROI pooling思想的原型。
Fast R-CNN与SPPNet同样大大简化了R-CNN在前期做选择性搜索的查找,而是直接将一张图片丢入CNN进行计算:
这里面最大的革新就是在ROI pooling部分,在R-CNN中,被形变操作在这里得到整合,不需要形变,这里使用了最大池化操作使得输出为确定的大小,下面的图片很显然地描述了这一操作:
而且在反向传播里池化操作也可以很简单的回传梯度,这样会节省很多的时间。
Fast R-CNN比R-CNN训练与测试时间都提升了几十倍,可是,很明显的看出来训练的时间有一大部分都是选择性搜索消耗的,那么可不可能将选择性搜索直接在CNN内操作呢?
Faster R-CNN直接丢弃了选择性搜索的操作,使用了Region Proposal Network代替选择性搜索,整体操作如下图所示:
这里讲几个技术要点:
通过最开始的卷积层输出feature map,一部分带入RPN结构,一部分放到ROI pooling层
RPN结构内分为两部分操作,一部分对anchors所对应的区域进行二分类(目标或背景),另一部分进行边框回归,找到最好的位置
大体讲一下anchors,下图中右边是anchors的具体表示,这里的 ( x 1 , y 1 , x 2 , y 2 ) (x_1, y_1, x_2, y_2) (x1,y1,x2,y2)是9个anchors的左上角与右下角的坐标,左边图形是三种不同尺寸的anchors width:height ∈ { 1 : 1 , 1 : 2 , 2 : 1 } \text{width:height}\in\{1:1, 1:2, 2:1\} width:height∈{1:1,1:2,2:1},这里的anchors是原图的坐标。
因为所有的anchors都是在原图上产生的,那么一共有多少个anchors呢?如果通过前置CNN将原图变为特征图变为1/16大小,那么特征图一共有多少个点 a a a,就有 9 a 9a 9a个anchors(9代表anchors数量,每个anchor就是以特征图中的点在原图的 16 ∗ 16 16*16 16∗16大小为中点,向外找anchors)
这样学习出来的就是对于不同anchors的数值,将之从大到小排序,提取前6000(举例)个,在其中筛选掉anchors超出原图边框情况,筛选掉特别小的,再进行非极大值抑制(方法参考https://www.cnblogs.com/makefile/p/nms.html),最后得到200(举例)个框,也就是得到的region proposal
剩下的就和Fast R-CNN一样了,将框与特征图丢入POI Pooling,再进行最后的分类与回归,就大功告成了
Fast R-CNN相当于在原始图像上选择性搜索找到region proposals,并且映射到特征图谱上;而Faster R-CNN则相当于在特征图谱上通过不同的anchors映射到原始图像中,我觉得这是两者很大的区别,而这个区别也就使图像处理的更加快速。
在最原始的Faster R-CNN版本中,是先进行RPN网络训练,再统一一起训练,后来改进的版本中至今实现了端对端的操作,最后的损失由RPN的分类与回归损失和最后整体分类与回归损失一起调控网络。
Mask R-CNN意义在于在Faster R-CNN基础上增加一个Mask蒙版层,使得最后的输出可以是像素级的目标,而不是单纯的框:
它对Faster R-CNN的改进是在于新增加了一个RoI Align与预测Mask操作,其中RoI Align在于之前的RoI pooling是将原来的特征像素级归一化到同一尺寸使用的取整操作,这里新的RoI Align使用的是双线性插值方法,使物体位置更加精确;而RoI Align之后有一个"head"部分,主要作用是将RoI Align的输出维度扩大,这样在预测Mask时会更加精确。在Mask Branch的训练环节,作者没有采用FCN式的SoftmaxLoss,反而是输出了K个Mask预测图(为每一个类都输出一张),并采用average binary cross-entropy loss训练,当然在训练Mask branch的时候,输出的K个特征图中,也只是对应ground truth类别的那一个特征图对Mask loss有贡献。
最后的损失函数由五部分构成, L f i n a l = L ( { p i } , { t i } ) + ( L c l s + L b o x + L m a s k ) L_{final} = L(\{p_i\},\{t_i\})+(L_{cls}+L_{box}+L_{mask}) Lfinal=L({pi},{ti})+(Lcls+Lbox+Lmask)
这里对于Faster R-CNN还有一点改进是positive RoI被定义成与groundtruth的IoU大于0.5的(Faster R-CNN是0.7)
再提一句,Mask R-CNN在蒙版级目标检测是比当时的FCIS方法要优秀一些的,这里就不解读FCIS方法了,感兴趣可以看大神的解读:https://blog.csdn.net/jiongnima/article/details/78961147
YOLO与其他目标检测网络的区别在于,它不使用Region Proposal进行物体位置识别,而是直接使用回归方法,看下图:
大体意思为将图片平均分成S*S的小格,每个格子负责检测‘落入’该格子的物体。若某个物体的中心位置的坐标落入到某个格子,那么这个格子就负责检测出这个物体。如下图所示,图中物体狗的中心点(红色原点)落入第5行、第2列的格子内,所以这个格子负责预测图像中的物体狗:
每个格子输出B个bounding box(包含物体的矩形区域)信息,以及C个物体属于某种类别的概率信息。
Bounding box信息包含5个数据值,分别是x,y,w,h,和confidence。其中x,y是指当前格子预测得到的物体的bounding box的中心位置的坐标。w,h是bounding box的宽度和高度。注意:实际训练过程中,w和h的值使用图像的宽度和高度进行归一化到[0,1]区间内;x,y是bounding box中心位置相对于当前格子位置的偏移值,并且被归一化到[0,1]。
confidence反映当前bounding box是否包含物体以及物体位置的准确性,计算方式如下:
c o n f i d e n c e = P ( o b j e c t ) ∗ I O U confidence = P(object) * IOU confidence=P(object)∗IOU, 其中,若bounding box包含物体,则P(object) = 1;否则P(object) = 0. IOU(intersection over union)为预测bounding box与物体真实区域的交集面积(以像素为单位,用真实区域的像素面积归一化到[0,1]区间)。
因此,YOLO网络最终的全连接层的输出维度是 S ∗ S ∗ ( B ∗ 5 + C ) S*S*(B*5 + C) S∗S∗(B∗5+C)。
最后的特征提取就是将之前的每一个小格子变成特征图上的每一个元素:
具体细节查看论文:https://arxiv.org/pdf/1506.02640.pdf
说一下YOLO的优缺点:
以上所说的都是YOLO的最初版本,也就是YOLO V1,看了几篇论文了解了之后的几个版本,这里来说一下这几个版本的不同点与改进:
YOLO V2:YOLO V2和YOLO 9000是当时一起推出的两款模型,但是YOLO V2是主要的检测网络,YOLO 9000只是YOLO V1的改进版,这里主要讲YOLO V2,他对于原来版本最大的改进是在最后的特征图上由V1的 7 ∗ 7 7*7 7∗7变成了 13 ∗ 13 13*13 13∗13并引入anchor box的思想,从原本的只有 7 ∗ 7 ∗ 2 7*7*2 7∗7∗2个bounding box,而V2由于anchor box可以提升很多倍的bounding box,达到1000多,而且这个anchor box是不同于Fast R-CNN的固定anchors大小,而是通过聚类得到的;还有V2在每一个层前都加了BN层加速收敛;还有将原图尺寸进行扩大,以提升分辨率与最后特征图的准确度,还有一些其他的小细节就不一一说明了。
YOLO V3:YOLO V3比V2大体上改进的方面不多,他引入了类似FPN的思想,就是多尺度融合,将最后一层 13 ∗ 13 13*13 13∗13与倒数第二层 26 ∗ 26 26*26 26∗26与前一层 52 ∗ 52 52*52 52∗52进行连接,加强了小目标的检测准确性。
本节主要讲述了目标检测的方法,如何对目标位置框查找,再对框内物体分类,从最原始的滑窗操作到衍生出的选择性搜索,再到R-CNN的几种变形,到后来的Mask R-CNN,最后大致讲解YOLO模型的不同点,具体细节需要上手代码!
资料来源: