目标检测 之 YOLO v1

YOLO意思是You Only Look Once,创造性的将候选区和对象识别这两个阶段合二为一,看一眼图片(不用看两眼哦)就能知道有哪些对象以及它们的位置。
实际上,YOLO并没有真正去掉候选区,而是采用了预定义的候选区(准确点说应该是预测区,因为并不是Faster RCNN所采用的Anchor)。也就是将图片划分为 7*7=49 个网格(grid),每个网格允许预测出2个边框(bounding box,包含某个对象的矩形框),总共 49*2=98 个bounding box。可以理解为98个候选区,它们很粗略的覆盖了图片的整个区域。
 
RCNN:我们先来研究一下图片,嗯,这些位置很可能存在一些对象,你们对这些位置再检测一下看到底是哪些对象在里面。
YOLO:我们把图片大致分成98个区域,每个区域看下有没有对象存在,以及具体位置在哪里。
RCNN:你这么简单粗暴真的没问题吗?
YOLO:当然没有......咳,其实是有一点点问题的,准确率要低一点,但是我非常快!快!快!
RCNN:为什么你用那么粗略的候选区,最后也能得到还不错的bounding box呢?
YOLO:你不是用过边框回归吗?我拿来用用怎么不行了。
1、YOLO V1的流程

这张图,诠释了YOLO V1的运行过程:
1.输入一张图,然后Resize到448 x 448;
2.然后输入到CNN中(文中叫darknet);
3.输出结果,经过后处理,包括NMS,得到结果(框和类别)
 
Yolo算法采用一个单独的CNN模型实现end-to-end的目标检测,整个系统如上图所示:首先将输入图片resize到448x448,然后送入CNN网络,最后处理网络预测结果得到检测的目标。相比R-CNN算法,其是一个统一的框架,其速度更快,而且Yolo的训练过程也是end-to-end的。
 
Yolo的CNN网络将输入的图片分割成 ,其中前4个表征边界框的大小与位置,而最后一个值是置信度(x,y,w,h,c)
 
 
输入和输出的映射关系:
 
输入就是原始图像,唯一的要求是缩放到448*448的大小。主要是因为YOLO的网络中,卷积层最后接了两个全连接层,全连接层是要求固定大小的向量作为输入,所以倒推回去也就要求原始图像有固定的尺寸。那么YOLO设计的尺寸就是448*448。
输出是一个 7*7*30 的张量(tensor)
30维向量:
 
① 20个对象分类的概率
因为YOLO支持识别20种不同的对象(人、鸟、猫、汽车、椅子等),所以这里有20个值表示该网格位置存在任一种对象的概率。可以记为 ,之所以写成条件概率,意思是如果该网格存在一个对象Object,那么它是的概率是 。(记不清条件概率的同学可以参考一下 理解贝叶斯定理
② 2个bounding box的位置
每个bounding box需要4个数值来表示其位置,(Center_x,Center_y,width,height),即(bounding box的中心点的x坐标,y坐标,bounding box的宽度,高度),2个bounding box共需要8个数值来表示其位置。
③ 2个bounding box的置信度
bounding box的置信度 = 该bounding box内存在对象的概率 * 该bounding box与该对象实际bounding box的IOU,用公式来表示就是
 
是bounding box内存在对象的概率,区别于上面第①点的 。Pr(Object)并不管是哪个对象,它体现的是 有或没有 对象的概率。第①点中的 意思是假设已经有一个对象在网格中了,这个对象具体是哪一个。
是 bounding box 与 对象真实bounding box 的IOU(Intersection over Union,交并比)。要注意的是,现在讨论的30维向量中的bounding box是YOLO网络的输出,也就是预测的bounding box。所以 体现了预测的bounding box与真实bounding box的接近程度。
还要说明的是,虽然有时说"预测"的bounding box,但这个IOU是在训练阶段计算的。等到了测试阶段(Inference),这时并不知道真实对象在哪里,只能完全依赖于网络的输出,这时已经不需要(也无法)计算IOU了。
综合来说,一个bounding box的置信度Confidence意味着它 是否包含对象且位置准确的程度。置信度高表示这里存在一个对象且位置比较准确,置信度低表示可能没有对象 或者 即便有对象也存在较大的位置偏差。
30维向量 = 20个对象的概率 + 2个bounding box * 4个坐标 + 2个bounding box的置信度
 
CNN整体的结构是由24个卷积层和2个全链接层组成,激活函数为“Leaky ReLU”,最后输出的向量维度是1470 = 7 x 7 x 30,说明最后输出了 7 x 7“组”结果,每组结果由30个数组成。网络结构如下:
1. 448*448*3 图像输入
2. 7*7卷积步长2 64输出 + 2*2最大值池化步长2 padding = 3
3. 3*3卷积步长1 192输出 + 2*2最大值池化步长2
4. 1*1卷积128输出 + 3*3卷积256输出 + 1*1卷积256输出 + 3*3卷积512输出 + 2*2最大值池化步长2
5. (1*1卷积256输出 + 3*3卷积512输出 )*4次 + 1*1卷积512输出 + 3*3卷积1024输出 + 2*2最大值池化步长2
6. (1*1卷积512输出 + 3*3卷积1024输出)*2次 + 3*3卷积1024输出 + 3*3卷积步长2 1024输出
7. 3*3卷积1024输出*2次
      8. 全链接层(1*1卷积) 512输出 + 全链接层(1*1卷积)4096输出 + 全链接层(1*1卷积)1470输出
其中各个卷积层 padding= "VALID", 各个池化层 padding= "SAME"
 
2、YOLO V1的核心
YOLO V1核心的思想是把图片分成Sx S个网格(grid cell),然后每个网格负责检测“一个”框和类别,再经过概率和NMS过滤,得到最终结果。
1)S是多少?
直接回答S=7,由于网格(grid cell)的数目需要跟最后特征图尺寸一一对应,最后特征图的尺寸为 7 x 7,因此网格的数目也就是 S x S = 7 x 7。
 
2)为什么要分成S x S个网格?
用以预测结果(框和类别)的特征图大小为 7 x 7,有49个向量(这里有点像RPN),每个向量都要去预测“框”和“类别”,训练时,我们需要为每个向量分配类别以及是否需要负责预测框,那么如何分配呢?我们需要把7x 7个点映射回原图,正好形成7 x 7个网格,然后根据每个网格跟Ground Truth之间的关系(作者设定了规则去建立联系),来做后续分配。也就是为什么分成S x S(7 x 7)个框了。
 
3)选择哪些网格(grid cell)去预测框?
每个网格在最后7 x 7的特征图上对应一个向量,这个30维向量用来预测结果,那么我们应该选择哪个网格来负责预测框呢?通俗一些,就是哪些网格是正例,哪些是负例(过程有点儿类似RPN,但区别蛮大),我们先看文中的一段描述:
物体的“中心”落在哪个网格中,哪个网格就负责训练这个框(类别和坐标)。这句英文大家都能看懂,但是实际呢?我们看看下面这张图:
 
这张图,中心点被标出来了,并且落在了“橘黄网格”中,那么它就是正例,那么“绿色网格”和“白色网格”的标签(Label)是什么呢?这里是与RPN最大不同之处了,YOLOV1中,对于一个Ground Truth, 有且只有一个网格是正例,其余的就算与Ground Truth IOU很大,也是负例 ,所以“绿色网格”和“白色网格”Label为负,所以也就不用负责训练框坐标了(但是会负责训练其他信息)。
 
4)选好了网格,下一步计算x,y,w,h(用来训练),它们是怎么计算的?
根据原论文我们可以确定几点, 第一:x,y指的是中心点,是物体框的中心点,不是网格的中心点(当然物体的中心点必然会落在相应的网格中);第二,w,h指的是物体框的宽高;第三,x,y, w, h都在0-1之间。我们在训练的时候,损失函数(LossFunction)计算的是预测的(x‘,y’,w‘,h’)与实际值(x,y,w,h)之间的L2-Loss,预测值是通过网络,最后在30维向量中(7 x 7 x 30) ,实际值是怎么算的呢?
5)最后输出的30维向量,代表什么?
论文中说了,我们一共预测98个框(明明只有49组向量),所以30维向量中一定包含了2个框的信息,也就是两组(x, y, w, h)。由于是在Pascal VOC上训练的,所以还有20个类别信息,这样组合发现只有28个值,YOLO V1不仅预测了框的x, y, w, h,还预测了框的分数,用来判断是不是框,所以30维向量成分:2组( x, y, w, h, score) + 20个类别概率。
 
6)框的分数是怎么算的?
预测的时候,分数是直接输出的,那么训练的时候呢?是不是选中的网格分数为1,没选中的为0,答案是NO,这也是YOLO V1的巧妙之处,YOLO V1计算了一个所谓的IOU分数,IOU指的是预测的框与实际框的IOU,这样在训练的时候,我们需要实时的计算这个IOU,作为输入到Loss Function中的“目标”,与预测的IOU分数做L2-Loss,举个例子,第一次迭代,网络会输出一个预测框P1,对应的真实框为G,程序会计算P1和G的IOU,然后继续做Loss。
 
7)为什么每个输出有两个框,实际却只负责一个框?
其中YOLO V1有一个细节,我画图描述一下:
其中,绿色的框P1与白色的框P2是网络预测的框,而红色的框G是真实值,YOLO V1会计算P1与G的IOU1,以及P2与G的IOU2,然后比较哪个IOU大,比如IOU2更大,那么P2的信息会输入到LossFunction中,P1被忽略掉(??)并不是100%被忽略,如果IOU1小于一个阈值,会作为负例,压向0值。
 
 
① 20个对象分类的概率
对于输入图像中的每个对象,先找到其中心点。比如上图中的自行车,其中心点在黄色圆点位置,中心点落在黄色网格内,所以这个黄色网格对应的30维向量中,自行车的概率是1,其它对象的概率是0。所有其它48个网格的30维向量中,该自行车的概率都是0。这就是所谓的"中心点所在的网格对预测该对象负责"。狗和汽车的分类概率也是同样的方法填写。
② 2个bounding box的位置
训练样本的bounding box位置应该填写对象实际的bounding box,但一个对象对应了2个bounding box,该填哪一个呢?上面讨论过,需要根据网络输出的bounding box与对象实际bounding box的IOU来选择,所以要在训练过程中动态决定到底填哪一个bounding box。参考下面第③点。
③ 2个bounding box的置信度
上面讨论过置信度公式
 
可以直接计算出来,就是用网络输出的2个bounding box与对象真实bounding box一起计算出IOU。
然后看2个bounding box的IOU,哪个比较大(更接近对象实际的bounding box),就由哪个bounding box来负责预测该对象是否存在,即该bounding box的 ,同时对象真实bounding box的位置也就填入该bounding box。另一个不负责预测的bounding box的
总的来说就是,与对象实际bounding box最接近的那个bounding box,其 ,该网格的其它bounding box的
举个例子,比如上图中自行车的中心点位于4行3列网格中,所以输出tensor中4行3列位置的30维向量如下图所示。
图 训练样本的一个30维向量
翻译成人话就是:4行3列网格位置有一辆自行车,它的中心点在这个网格内,它的位置边框是bounding box1所填写的自行车实际边框。
注意,图中将自行车的位置放在bounding box1,但实际上是在训练过程中等网络输出以后,比较两个bounding box与自行车实际位置的IOU,自行车的位置(实际bounding box)放置在IOU比较大的那个bounding box(图中假设是bounding box1),且该bounding box的置信度设为1。
6)损失函数
损失就是网络实际输出值与样本标签值之间的偏差。
图 样本标签与网络实际输出
YOLO给出的损失函数如下
图 损失函数
公式中
意思是网格i中存在对象。
意思是网格i的第j个bounding box中存在对象。
意思是网格i的第j个bounding box中不存在对象。
总的来说,就是用网络输出与样本标签的各项内容的误差平方和作为一个样本的整体误差。
损失函数中的几个项是与输出的30维向量中的内容相对应的。
① 对象分类的误差
公式第5行,注意意味着存在对象的网格才计入误差。
② bounding box的位置误差
公式第1行和第2行。
a)都带有 意味着只有"负责"(IOU比较大)预测的那个bounding box的数据才会计入误差。
b)第2行宽度和高度先取了平方根,因为如果直接取差值的话,大的对象对差值的敏感度较低,小的对象对差值的敏感度较高,所以取平方根可以降低这种敏感度的差异,使得较大的对象和较小的对象在尺寸误差上有相似的权重。
c)乘以 调节bounding box位置误差的权重(相对分类误差和置信度误差)。YOLO设置 ,即调高位置误差的权重。
③ bounding box的置信度误差
公式第3行和第4行。
a)第3行是存在对象的bounding box的置信度误差。带有 意味着只有"负责"(IOU比较大)预测的那个bounding box的置信度才会计入误差。
b)第4行是不存在对象的bounding box的置信度误差。因为不存在对象的bounding box应该老老实实的说"我这里没有对象",也就是输出尽量低的置信度。如果它不恰当的输出较高的置信度,会与真正"负责"该对象预测的那个bounding box产生混淆。其实就像对象分类一样,正确的对象概率最好是1,所有其它对象的概率最好是0。
c)第4行会乘以 调节不存在对象的bounding box的置信度的权重(相对其它误差)。YOLO设置 ,即调低不存在对象的bounding box的置信度误差的权重。
 
损失函数公式如上,里面有几个值得我们借鉴的地方:
1)对于平方差,同样很小的数值,对于大框影响相对于小框的影响小一些,(同样的值,加在大框上,可能几乎没有变化,而小框的变化会很大),此时作者是如何处理的呢?
文中是把w,h都开根号了,预测的是开根号的值,这样影响会相对一致一些。
2)由于每个框只有一个网格负责,那么49个网格,预测98个框,可能只有1-2个是正例,其余的都是负例,需要取向零,这样会导致网络更好的学习负例:
文中的做法是赋予不同的权重,预测坐标的权重为5,“没有物体“的权重为0.5,权重相差10倍。
 
 
 
YOLO的NMS计算方法如下。
网络输出的7*7*30的张量,在每一个网格中,对象 位于第j个bounding box的得分:
 
它代表着某个对象 存在于第j个bounding box的可能性。
每个网格有:20个对象的概率*2个bounding box的置信度,共40个得分(候选对象)。49个网格共1960个得分。Andrew Ng建议每种对象分别进行NMS,那么每种对象有 1960/20=98 个得分。
NMS步骤如下:
1)设置一个Score的阈值,低于该阈值的候选对象排除掉(将该Score设为0)
2)遍历每一个对象类别
 2.1)遍历该对象的98个得分
  2.1.1)找到Score最大的那个对象及其bounding box,添加到输出列表
  2.1.2)对每个Score不为0的候选对象,计算其与上面2.1.1输出对象的bounding box的IOU
  2.1.3)根据预先设置的IOU阈值,所有高于该阈值(重叠度较高)的候选对象排除掉(将Score设为0)
  2.1.4)如果所有bounding box要么在输出列表中,要么Score=0,则该对象类别的NMS完成,返回步骤2处理下一种对象
3)输出列表即为预测的对象
感谢: https://mp.weixin.qq.com/s/cwAhC6z5MO_QPm-VeFLF2w  公众号:懒人学AI
发布了34 篇原创文章 · 获赞 3 · 访问量 737

猜你喜欢

转载自blog.csdn.net/qq_41168327/article/details/104995954