前言:在之前的博客中,我依次总结了目标检测算法、算法的卷积改进、Bounding Box预测算法、交并比与非极大值抑制等内容,这些是YOLO 算法的重要细节,现在还差一柄利剑,我们就可以构建YOLO算法了,现在让我们先一起来了解一下这柄剑——Anchor Boxes算法。
相关链接如下:
深度学习基础—目标定位与特征点检测https://blog.csdn.net/sniper_fandc/article/details/142707197?fromshare=blogdetail&sharetype=blogdetail&sharerId=142707197&sharerefer=PC&sharesource=sniper_fandc&sharefrom=from_link深度学习基础—目标检测算法https://blog.csdn.net/sniper_fandc/article/details/142716828?fromshare=blogdetail&sharetype=blogdetail&sharerId=142716828&sharerefer=PC&sharesource=sniper_fandc&sharefrom=from_link深度学习基础—交并比与非极大值抑制https://blog.csdn.net/sniper_fandc/article/details/142729579?fromshare=blogdetail&sharetype=blogdetail&sharerId=142729579&sharerefer=PC&sharesource=sniper_fandc&sharefrom=from_link
1.Anchor Boxes算法
(1)理解Anchor Boxes算法
目前介绍的内容都是在一个格子检测一个对象的案例,但是如果出现一个格子有多个对象需要检测,那就需要Anchor Boxes算法了,来一起看看:
上图所示,假设进行人、汽车、摩托车3个对象的检测,仍然采用3*3的网格划分,人物和汽车的中心点位于同一个格子,如果对于原先的标签定义方式:
这种方式只能保证网络的输出一个格子只包含一个对象,无法同时输出两个对象的分类和定位,显然,我们需要对标签向量进行扩充,让其能输出多个对象的预测信息。
引入Anchor Boxes,它是一组预定义的边框,又叫锚框。要求Anchor Boxes的比例和对象的真实边框比例相似,大小可以不完全一致。这里由于人的比例形如竖放的长方形,而汽车的比例形如横放的长方形,因此引入2个如上图的Anchor Boxes,一个记为Anchor Box 1,另一个记为Anchor Box 2(实际可以引入更多的Anchor Boxes)。重新定义标签:
标签的前8个元素是Anchor Box 1的输出,后8个元素是Anchor Box 2的输出。现在要做的就是为每个对象分配格子和Anchor Boxes,人形如Anchor Box 1,汽车形如Anchor Box 2。因此如果一个格子同时存在人和汽车的中心点,那这个格子的标签应该为(c1为人,c2为汽车,c3为摩托车):
如果一个格子只有汽车,没有人,那这个格子的标签为(?表示格子没有该对象,不考虑位置和分类等信息):
对于一个格子没有任何对象的标签定义,很容易得到,不再赘述。
总结一下:之前的算法对于训练集图像中的每个对象,都根据那个对象中点位置分配到对应的格子中,所以在3*3的网格下输出就是3*3*8。8表示标签的8个分量的输出。
在anchor boxes算法中:每个对象分配一个格子和与对象真实边框交并比LOU最高的anchor box中,即(网格单元,anchor box)对,输出变为3*3*16(也可以看成3*3*2*8,因为16其实是2个anchor box,如果有更多的对象类别,就需要定义更多的anchor box,输出也就更多)。如上图所示,如果对象形状是编号1的红色框,编号2和编号3是紫色框的anchor box,编号2的anchor box和实际边界框(编号1,红色框)的交并比更高,就需要为对象分配编号2的anchor box。
结合上个公式讲讲我对anchor boxes算法的理解方式:这个公式是Faster R-CNN原文中采用的损失函数,L_cls是标签的损失函数,L_reg是真实边框相对于anchor box的位置偏移损失,也就是最终会不断减小损失,让对象从anchor box的模糊定位精确到真实边框的定位,也就是用anchor box去拟合真实边框。这就是anchor box的作用,一方面用于训练前的标注和标签定义,另一方面用于预测给出对象的定位。
注意:如果出现一个格子超过3种对象或者2个对象被分配到同一个格子并且他们的anchor box也一样,就需要其他手段来处理了,不过这两种情况出现的概率并不高,情况2对网络的性能影响也不大。
(2)anchor box的尺寸选择
目前anchor box的选择主要有三种方式:
人为经验选取:人们根据图片中常见的对象形状,选择多种形状定义,保证涵盖所有对象的形状。
k-means聚类:将对象形状聚类,选择最具有代表性的一组anchor box,代表试图检测的十几个对象类别。
作为超参数进行学习。
2.YOLO 算法
现在,YOLO算法的主要组件都已了解,我们来一起了解一下完整的YOLO算法。
(1)定义标签,构造训练集
需要识别的对象有3类:行人、汽车、摩托车。选择两个anchor box,则定义的标签向量长度为16,前8个分量是anchor box 1的相关参数,后8个分量是anchor box 2的相关参数,划分图片为3*3的网格,遍历9个格子,依次定义相关的标签y,如上图所示。
上图所示,现在处理绿色边框的格子外,其他边框的标签都是中间那个向量,而绿色边框的格子有汽车,假设这个汽车与anchor box 2的交并比最大(编号5,紫色长方形框),因此绿色边框的格子的标签是最右边的向量(anchor box 1对应的分量的pc=0),然后根据红色边框(编号3来编码真实边框的参数,也就是右边向量的红色部分)。
(2)训练网络
假设输入的图片是100*100*3,那么经过卷积网络的训练后,得到的输出为3*3*16,3*3依次对应网格的3*3划分的区域,16表示每个网格单元对应的输出的长度为16的预测向量。
注意这里可能有误区,许多人认为划分3*3网格后,我们的训练并不是将每个网格单元依次输入到网络中,然后一张图片跑9次向前传播,这样做不就退化成滑动窗口算法了吗?实际上,由于将网络全连接层改造成卷积层,由于卷积计算共享的特性,就可以一次输入一整张图片,得到9个网格每个网格的结果。
(3)预测
用网络进行预测,编号1的网格很可能输出为编号3的向量结果,编号2的网格很可能输出编号4的向量结果,显示这个网格中包含汽车对象,不包含行人对象,并显示汽车的定位边框。其中,对于没有识别到对象的网格,pc=0,故不需要考虑其他分量,但是网络不可能输出问号等元素,因此这些分量是无意义的数值(噪音)。
(4)非极大值抑制
编号1是网络输出的结果,每个单元网格内都有两个anchor box拟合的边框,从这个现象也可以看出anchor box算法的作用之一:用预定形状的anchor box去拟合对象的真实边框。但是有些格子没有对象,却有对象的边框,实际上这些边框的概率很低,因此非极大值抑制算法首先需要去除这些低概率的边框。
去除低概率的边框后得到编号2的结果,此时再对每个对象类别使用非极大值抑制,选择概率最大的边框,去除与最大概率边框交并比超过阈值的边框,也就是行人的横框和汽车的竖框,得到编号3所示的结果。此时我们完成了YOLO算法的主要流程,得到了目标检测的结果。
这就是YOLO对象检测算法,是目前最有效、最常用的对象检测算法之一,包含了整个计算机视觉对象检测领域文献中很多精妙的思路,当然YOLO算法目前仍在不断改进和发展。在了解该算法的基础后,希望大家也能不断启发灵感,获取新的检测算法思路。