赞
踩
参考:
yolo论文翻译
图解yolo
非极大值抑制算法的理解
性能参数的理解
IOU
把图像缩放到448*448
在图上运行卷积网络
根据模型置信度对检测结果进行阈值处理
yolo系统将输入图像分成s*s的网格,若目标中心若如某个网格中,那么该网格就负责检测该目标。
每个网格单元都会预测B个边界框和这些框的置信度分数(反映模型对框内是否含有目标的信心)。
置信度定义:
我们希望置信度分数等于预测框predict box与真实标签框ground truth之间联合部分的交集IOU。
每个边界框都包含5个预测:x,y,w,h,置信度。(x,y)坐标反映的是边界框的中心相对于网格单元边界的值。宽度和高度是相对于整张图片来预测的,置信度表示预测框与任意实际边界框之间的IOU。
每个网格单元还预测C个条件类别概率,这些概率以包含目标的网格单元为条件。
置信度评分如上面的公式所示,反映了基于当前模型bounding box内存在目标的可能性Pr(project),和bounding box预测目标位置的准确性IOU(predtruth)。如果bounding box内不存在物体,则Pr(object)=0,如果存在物体,则根据预测的bounding box和真实的bounding box计算IOU,同时会预测存在物体的条件下该物体属于某一类的后验概率Pr(Class_iObject)。
不管边界框的数量B是多少,每个网格单元只预测一组类别概率。在测试时,把条件类概率与每个框的预测置信度值相乘。
上面的公式给出了每个框特定类别的置信度分数,这些分数体现了该类出现在框中的概率以及预测框拟合目标的程度。
假设有C类物体,那么每一个网格只预测一次C类物体的类条件概率Pr(Class_iObject),i=1,2,……C,每一个网格预测B个bounding box的位置,即这B个bounding box共享一套条件类概率。基于计算得到的Pr(Class_iObject),在测试时可以计算某个bounding box类相关置信度。
为在pascal voc上评估yolo,使用S=7,B=2,pascal voc有20个标注类,C=20,最终的预测是7730的张量。
如上图所示,系统将检测模型化为一个回归问题,图像划分为SS的网格图,这里是77,并且每个网格单元预测B个边界框、以及这些框的置信度和C类概率。这些预测被编码成SS(B5+C)这里即是77*(25+20)=77*30张量。
最后一层输出7730的维度。每个1130的维度对应原图77个cell中的一个(原图划分为了77的网格)。1130中含有类别预测和bbox坐标预测。即网格负责类别信息,bounding box主要负责坐标信息(部分负责类别信息:confidence也算类别信息)。
每个网格要负责预测两个bounding box,下图中的(两个黄色实线框)的坐标(x,y,w,h),
中心坐标x,y是相对于对应的网格把值归一化到0-1之间。w,h坐标值是图像的weight和height值归一化到0-1之间。
每个bounding box除了要回归自身的位置外,还要预测一个confidence值。这个confidence代表了所预测的box中含有object的置信度和这个box预测得有多准两重信息。confidence的值为这两个量的乘积。如果ground true box人工标记的物体落在一个grid cell里,则上面confidence式子中第一个因子取值1,否则取值0。式子中的第二个因子是预测的bounding box和实际的ground truth box之间的IOU值。综上,即每个bounding box要预测5个值(x,y,w,h,confidence),两个bounding box共十个值,对应1130维度特征中的前十个。如下图所示:
每个网格还要预测类别信息,论文中是20个类别。77的网格,每个网格要预测2个bounding box和20个类别概率。输出即为77*(52+20)=77*30的一个张量。
注意类别信息是针对每个网格的,而confidence信息是针对每个bounding box的。
损失函数设计
损失函数的设计目标就是让坐标(x,y,w,h, ),confidence,classification这三个方面达到很好的平衡。
第一种思路:是不好的方法。简单的全部采用sum-squared error loss来做这件事会有以下不足:
(1)8维的localization error和20维的classification error同等重要是不合理的。
(2)如果一个网格中没有object,那么就会将这些网格中的box的confidence值push到0。(一幅图中这种网格中没有object是普遍的,而网格中有object是较少的情况),所以这种把值push到0的行为是overpowering,会导致网络不稳定甚至发散。
第二种思路:为了解决第一种简单思路产生的问题而有了思路二。
(1)在上面损失函数设计的图中,更重视8维的坐标预测(对应着上面损失函数设计框图中的蓝色框的式子部分),即2个bounding box预测的坐标(x,y,w,h)。2*4=8维。给这些坐标预测维度的损失前面赋予更大的loss weight。记为
(2)对没有object的bbox的confidence loss,(对应损失函数设计框图中的黄色框图的式子部分)赋予小的loss weight,记为
(3)有object的bbox的confidence loss(对应于损失函数框图设计中的红色框图)和类别的loss(对应于紫色框图)的loss weight正常取1。
(4)对不同大小的bbox预测中,大bbox预测存在小偏差可以忍受,但是对于小bbox存在小偏差都无法忍受。而sum-square error loss中对同样的偏移loss是一样的。为了缓和这个问题,解决办法是将box的width和height取平方根代替原本的width和height。如下图所示:small bbox的横轴值较小,发生偏移时,反映到y轴上的loss(下面图中绿色框出来的部分)比big bbox(下面图中红色框出来的部分)要大。
(5)一个网格预测多个bounding box,在训练时我们需要每个object(ground true box)只有一个bounding box负责(一个object一个bbox)。具体做法是与ground true box(object)的IOU最大的bounding box负责该ground true box的(object)的预测。这种做法称作bounding box predictor的specialization(专职化)。每个预测期会对特定的(sizes,aspect ratio,classed of object)的ground true box的预测越来越好。
将上面提到的模型作为卷积神经网络来实现,并且在pascal voc检测数据集上来评估。
网络的初始卷积层从图像中提取特征,全连接层负责预测输出概率和坐标。
网络模型受图像分类模型GoogleNet的启发,网络有24个级联的卷积层,其中卷积层包括33和11两种kernel,后面是2个全连接层。
只使用11降维层,后面是33卷积层。
上图是架构图,检测网络有24个卷积层,然后是2个全连接的层,交替的11卷积层减少了来自前面层的特征空间。在分辨率的一半(224224输入图像)上预训练ImageNet分类任务上的卷积层,然后将分辨率加倍以进行检测训练。
平方和误差对大框和小框的误差权衡是一样的,而我们的错误指标要体现出,大框的小偏差的重要性不如小框的小偏差的重要性,为了部分解决这个问题,直接预测边界框宽度和高度的平方根,而不是宽度和高度。
yolo为每个网格单元预测多个边界框,在训练时,每个目标只需要一个边界框预测器来负责。
若某预测器的预测值与目标的实际值的IOU最高,则这个预测器被指定为负责预测该目标。这带来边界框预测器的专业化。
每个预测器可以更好的预测特定大小、方向角或者目标的类别,从而改善整体召回率。
在训练期间,优化以下多部分损失函数。如下式子:
一般的目标检测流程:
例举几种顶级的检测框架
yolo与DPM相比较
yolo与R-CNN相比较
yolo与Fast-RCNN相比较
yolo与Deep MultiBox比较
4. 补充解释NMS非极大值抑制。non maximum suppression。
(1)在目标检测中得到多个候选框及其置信度得分。NMS对多个候选框,去除重合率大的冗余候选框,得到最具有代表性的结果,加快检测进程。将分类器进化为检测器的关键是:在原始图像上从多个尺寸产生窗口,并且resize到固定尺寸,然后送给分类器做判断。最常用的方法是滑动窗口。如下图,由于滑动窗口,所以同一个人可能有好几个框,每一个框都带有一个分类器得分。
虽然同一个人脸上出现好几个框,但是目标是保留最优的那个框。所以用到非极大值抑制来抑制冗余的框。抑制的过程是:迭代-遍历-消除的过程。
非极大值抑制的步骤如下:
(2)第一步:将所有框的得分排序,选择分最高的那个框。如下图:假设图中有A:0.75 , B:0.98 , C:0.83 ,(A,B,C是女生人脸上的三个框) D: 0.67 , E: 0.81(D E是男生人脸上的两个框)
上面五个框A B C D E中的最高得分是:B:0.98
(3)第二步:遍历其余的框,如果和当前最高分框的重叠面积(IOU)大于一定的阈值,就将这个框删除。由B:0.98对其余A C D E框计算IOU,B与A C的IOU>阈值,所以删除这两个框,所以第一轮后剩下三个框即A D E,如下图:
(4)第三步:从未处理的框中继续选一个得分最高的,重复上述的过程。在未处理的D E两个框中选择得分高的是D 所以删除E。故最终保留的是A D两个框。如下图:
NMS的python代码如下:
''' 非极大值抑制python程序 候选框boxes为5列,分别为[x1 y1 x2 y2 score],score为置信度得分 threshold:IOU阈值 ''' def py_nms(dets,thresh): # 取出候选框左上角和右下角坐标以及置信度得分 x1 = dets[:,0] y1 = dets[:,1] x2 = dets[:,2] y2 = dets[:,3] scores = dets[:,4] # 计算每一个框的面积 areas = (x2-x1+1)*(y2-y1+1) # 按照置信度升序排列 order = scores.argsort()[::-1] keep = [] # 循环直至所有框处理完成 while order.size > 0: i = order[0] keep.append(i) # 计算当前置信度最大矩形框与其他矩形框的重叠面积 xx1 = np.maximum(x1[i],x1[order[1:]]) yy1 = np.maximum(y1[i],y1[order[1:]]) xx2 = np.minimum(x2[i],x2[order[1:]]) yy2 = np.minimum(y2[i],y2[order[1:]]) w = np.maximum(0.0,xx2-xx1+1) h = np.maximum(0.0,yy2-yy1+1) inter = w*h # 计算IOU ovr = inter/(areas[i]+areas[order[1:]]-inter) # 保留所有重叠面积小于阈值的框 inds = np.where(ovr <= threshold)[0] order = order[inds+1]
watch -n 1 nvidia-smi
watch的作用是周期性地执行某一命令,-n 的后面指多少秒执行一次命令。这里的指令表示每1秒更新一下GPU的使用情况。
例子:
假如有如下图所示的测试集,测试集有飞机和大雁两种图片。若分类系统的目的是:能取出测试集中所有飞机的图片。
有如下四个定义:
true positive:飞机的图片识别为飞机
true negative:大雁的图片没有被取出(因为能正确识别是大雁)
false positive:大雁被识别为飞机
false negative:飞机图片没有取出来,因为识别成了大雁
性能参数:
precision
就是识别出来的图片中true positive占的比例。总的识别出来的图片数量也就是true positive的数量加上false positive的数量和。
recall
是正确识别出来的飞机个数与测试集中所有飞机个数的比值。测试集中所有飞机个数就是true positive的数量加上false negative的数量和。
阈值
可以通过调整阈值,选择让系统识别出多少张图片,进而改变precision和recall的值。
precision-recall曲线
用于评估分类器的性能,观察当阈值变化时,precision和recall值的变化情况。
(1)若分类器性能好,则应该表现为:被识别出的图片中飞机所占的比重较大,且在识别出大雁之前,尽可能多的正确的识别出飞机,也就是让recall增长的同时保持precision在一个很高的水平。
(2)性能较差的分类器表现为:可能需要损失很多的precision才能提高recall值。
Approximated Average precision
(1)相比于precision-recall曲线,一个具体的数值更能直接表现出分类器的性能。
(2)average precision的公式为:
上面的积分公式中,p代表precision,r代表recall,p是一个以r为参数的函数,积分就相当于函数曲线下的面积。这个积分公式中得到的值与下面求解得到的值是想接近的。对每一种阈值分别求(precision值)乘以(recall值的变化情况),再把所有阈值下求得的乘积值进行累加,公式如下:
在上面的乘积再求和公式中,N代表测试集中所有图片的个数,P(k)表示在能识别出k张图片时的precision值,
表示识别图片从k-1变化到k时(通过调整阈值)recall值的变化情况。
在下面给出的precision-recall曲线图所对应的例子中,套用上面的乘积再求和公式即为如下式子:
=[1*(0.2-0)]+[1*(0.4-0.2)]+[0.66*(0.4-0.4)]+[0.75*(0.6-0.4)]+[0.6*(0.6-0.6)]+[0.66*(0.8-0.6)]+[0.57*(0.8-0.8)]+[0.5*(0.8-0.8)]+[0.44*(0.8-0.8)]+[0.5*(1-0.8)]=0.782
那些recall值没有变化的地方对增加average precision值没有贡献。
Interpolated 插值 average precision
这个算法不适用P(k),而是使用
每次都使用:在所有阈值的precision中,最大值的那个precision值与recall的变化值相乘。公式如下:
下图是approximated average precision和interpolated average precision两种方法的对比:
由上图可以看出,
(1)approximated average precision与精度曲线挨得很近。
(2)使用interpolated average precision算出的average precision值要比approximated average precision算出的值要高。
(3)很多文章都是使用的interpolated avrage precision,例如PASCAL Visual Objects Challenge认为interpolated average precision能有效减少precision-recall曲线中的抖动。
(4)在比较文章中的average precision值时,要弄清楚是使用的approximated average precision还是interpolated average precision的度量方法。
def IOU(Reframe,GTframe): # 自定义函数,计算两矩形IOU,传入为矩形对角线(x,y)坐标 # Reframe:detection result GTframe:ground truth x1 = Reframe[0] y1 = Reframe[1] width1 = Reframe[2]-Reframe[0] height = Reframe[3]-Reframe[1] x2 = GTframe[0] y2 = GTframe[1] width2 = GTframe[2]-GTframe[0] height2 = GTframe[3]-GTframe[1] endx = max(x1+width1,x2+width2) startx = min(x1,x2) width = width1+width2-(endx-startx) endy = max(y1+height1,y2+height2) starty = min(y1,y2) height = height1+height2-(endy-starty) if width <= 0 or height <= 0: # 重叠率为0 ratio = 0 else: # 两矩形相交面积 Area = width*height Area1 = width1*height1 Area2 = width2*height2 ratio = Area*1./(Area1+Area2-Area) # return IOU return ratio,Reframe,GTframe
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。