在前面几讲的论文研读笔记中,笔者和大家一起研读了以 R-CNN 为代表的两步走目标检测算法系列,其中包括 R-CNN、SPP-Net、Fast R-CNN 和 Faster R-CNN。往后还有何恺明 2017 年新提出的 Mask R-CNN,因其涉及到图像分割任务,故而笔者将其留到后面的图像分割系列进行介绍。总而言之,两阶段的目标检测算法就是先生成候选框再执行卷积网络识别出目标物体,无论是R-CNN、SPP-Net 和 Fast R-CNN 的选择性搜索方法还是Faster R-CNN 的 RPN 网络生成候选框,基本都是两阶段的套路。
那可否考虑直接用卷积网络识别出物体,不使用候选框呢?以 yolo 系列为代表的一步到位的目标检测算法给出了肯定的答案。Joseph Redmon、Santosh Divvala、Ross Girshick(对、又是 RBG 大佬,哪里都有他)以及 Ali Farhadi 四位研究人员于 2016 年提出完全不同于 R-CNN 系列的目标检测算法,也就是笔者此前所说的一步走算法。本节笔者就和大家一起研读 yolo 算法的第一代版本 yolo v1 算法。
yolo v1 算法是一个复杂的系统,要通过认真研读论文才能搞清楚算法的每个细节。但简单而言,yolo v1 算法是将目标检测任务当作的一个回归问题来对待,当然这是一个相当复杂的回归系统。yolo v1 通过训练一个神经网络根据整张输入的图片预测出目标物体的边界框位置和目标物体名称和置信度。相较于两阶段的目标检测算法,yolo v1 算法省掉了生成候选框的步骤,直接用一个检测网络进行端到端的检测,因而检测速度非常快。
从上图可以看到 yolo v1 的检测步骤:
将输入图片缩放到 448 x 448 的尺寸
对输入图像运行一个卷积神经网络
根据预测边界框的置信度筛选出最优结果(NMS)
统一检测方法
下面我们来详细看一下 yolo v1 算法的细节问题。
yolo v1 将输入图片进行 resize 之后将其划分为 SxS 大小的网格(grid),每个网格负责检测中心落在该网格中的物体,如下图所示:
简单的检测场景下,一个网格通常只负责检测一个目标物体,但现实的检测任务往往存在一个网格会有多个目标物体的情形。所以一般来说一个网格可以预测出 B 个边界框(Bounding Boxes)和边界框的置信度。这个置信度的含义在于该网格是否含有目标物体以及对于目标物体的定位有多大的可信度。边界框的置信度计算公式为:
其中第一项为当前网格中是否含有目标物体,含有的话就是 1,不含有的话则是 0,所以当当前网格中不含有目标物体时,该网格所对应的边界框的置信度也就为零了。当前网格包含目标物体时,对应的边界框的置信度则为预测的边界框和实际的边界框(groud truth bounding box)之间的交并比(IOU)。
到这里我们简单梳理一下以上过程基本逻辑:yolo v1 将每张输入图片划分为 SxS 个网格,每个网格可以预测 B 个边界框和对应边界框的置信度和具体定位。边界框的置信度由网格中是否含有目标物体和预测边界框与真实边界框之间的 IOU 相乘得到。
再来看边界框的位置预测问题。除了预测边界框的置信度(confidence),还有边界框的定位,而定位由四个坐标值体现,分别是 x、y、w 和 h。其中:
x 和 y 代表了预测的边界框中心与网格边界的相对值
w 和 h 则表示边界框的宽和高相对于整幅图像的比例值
所以,综合置信度和定位两个因素,我们知道了每个边界框都包含以上五个变量:
(x,y,w,h,confidence)
好了,边界框的属性变量的讨论到此暂且告一段落,我们再回到之前划分的网格。每个网格除了预测 B 个边界框之外,还需要预测 C 个条件类别概率:即在每个网格中包含目标物体的情况下,整个物体属于某个类的概率。我们把它记为:
因而 yolo v1 算法的输出张量大小可以用公式表示为:
S x S x (B*5 + C)
而到了测试阶段,每个网格的条件类别概率乘以每个边界框的置信度就可以得到每个边界框具体类别的置信度,所以这里需要区分一下之前说的边界框的置信度和边界框所属类别的置信度这两个概念。边界框的具体类别的置信度计算公式为:
论文中将 yolo v1 应用于 PASCAL VOC 数据集时将输入图像划分为 7x7 个网格,每个网格预测两个边界框,即 B = 2,每个边界框包括 x、y、w、h 和 confidence 五个预测值,另外该数据集有 20 个类别,所以根据前述计算公式我们可以得到输出张量大小为:
7 x 7 x (2*5 + 20) = 7 x 7 x 30
以上便是 yolo v1 算法的检测预测细节。完整的 yolo v1 的检测模型示意图如下所示:
检测网络设计、训练和损失函数
yolo v1 设计的检测网络包括 24 个卷积层和 2 个全连接层,网络流程于结构如下:
作者们在设计 yolo v1 的网络结构时参考了 GoogLeNet 的网络结构,但并未使用 Inception 的通道组合策略,而是大量使用了 1x1 和 3x3 卷积。前 24 层卷积用来提取图像特征,后面 2 层全连接用来预测目标位置和类别概率。
在训练时先利用 ImageNet 分类数据集对前 20 层卷积层进行预训练,将预训练结果再加上剩下的四层卷积以及 2 层全连接,采用了 Leaky Relu 作为激活函数,其中为了防止过拟合对全连接层加了失活概率为 0.5 的 dropout 层。
yolo v1 的损失函数较为复杂。一般来说系统设计需要平衡边界框坐标损失、置信度损失和分类损失。论文中设计的损失函数如下:
将上述损失函数进行拆解释义:(该图来自 hrsstudy 的CSDN博客,地址见参考资料)
如何平衡三个损失函数部分之间的平衡是算法需要重点考虑的问题。由公式可以看出,三者的损失类型均为均方损失函数,不同是在三部分损失前均有相应的权重系数来衡量三者各自的重要性。更多细节这里不想写了,各位可在读论文时逐一体会。
结果与评估
yolo v1 在 PASCAL VOC 2007 数据集上与其他算法的准确率和速度对比:
与 Fast R-CNN 的准确率比较:
从以上图表可以看出,一步到位式的 yolo v1 算法在准确度和速度的权衡上可能更偏向于速度一些,直接表现就是 yolo v1的检测速度非常之快。
yolo v1 部分检测表现:
来自 yolo 官网的检测效果视频展示,实时检测的酷炫性一览无余:
关于 yolo v1 论文中还有诸多设计细节笔者也并没有完全搞清楚,所以接下来一段时间会继续对原文进行深入推敲,也会实际编码进行试验,欢迎各位留言交流!
参考资料:
Redmon J, Divvala S, Girshick R, et al. You Only Look Once: Unified, Real-Time Object Detection[J].
https://pjreddie.com/darknet/yolo/
领取专属 10元无门槛券
私享最新 技术干货