手把手实现YOLOv3(一)

前言

本文翻译总结于scratch

目标检测是一个很古老的视觉问题,和其他视觉问题一样,它也从深度学习的发展中受益匪浅。
近年来,人们开发了许多用于对象检测的算法,其中包括YOLO,SSD,Mask RCNN和RetinaNet。

目录

正文

在过去的几个月中,我一直在实验室中改进对象检测算法。
这次体验最大的收获之一就是认识到学习目标检测的最佳方法是自己从头开始实现它。这就是本教程的目标。

我们将使用PyTorch来实现基于YOLOv3的对象检测器,YOLOv3是一种较快的对象检测算法。

本教程的代码可在Python 3.7和PyTorch 1.1.0上运行。
可以在此Github存储库
中找到全部内容。
本教程分为5部分:

 第一部分(这一部分):了解YOLO的工作方式

 第二部分:创建各层神经网路

 第三部分:实现网络的前向传递

 第四部分:目标阈值化和非最大抑制

 第五部分:设计输入和输出管道

先决条件

您应该了解卷积神经网络如何工作。
这包括残差块,跃接层和上采样的知识。
什么是物体检测,边界框回归,IoU和非最大抑制。
PyTorch的基本用法。您应该能够轻松创建简单的神经网络。
如果您在任何方面有疑惑,我会在文章末尾提供链接。

什么是YOLO?

YOLO代表you only look once。
它是一种目标检测器,它使用深度卷积神经网络学习到的特征来检测对象。
在弄清代码之前,我们必须了解YOLO的工作方式。

全卷积神经网络

YOLO仅含卷积层,因此被称为全卷积神经网络(FCN).
它具有75个卷积层,以及跃连层和上采样层。
不含任何形式的池化层,而是使用跨度为2的卷积层对特征图进行下采样。
这有助于防止通常归因于池化层稀释的丢失。
作为FCN,YOLO不受输入图像的大小影响。但是,在实践中,由于各种问题,我们可能希望坚持一个固定的输入层,而这些问题只有在实现算法时你才能体会到。
这些问题中最大的一个问题是,如果我们要分批处理图像(批处理图像可以由GPU并行处理,从而提高了速度),我们需要拥有固定尺寸的所有图像。
这需要将多个图像串联成一个大组(将多个PyTorch张量串联成一个)
网络通过称为网络步幅的因素对图像进行下采样。
例如,如果网络的间隔为32,则大小为416 x 416的输入图像将产生大小为13 x 13的输出。
通常,网络中任何层的步幅等于网络输入图像除以输出的大小。

解释输出

通常,(与所有目标检测器一样)将由卷积层学习的特征传递到分类器/回归器上,该分类器/回归器进行目标预测(边界框的座标,类标签等)
在YOLO中,预测是通过使用1 x 1卷积的卷积层完成的。

现在,首先要注意的是我们的输出是一个特征图。
由于我们使用了1 x 1卷积,因此预测图的大小恰好是其之前的特征图的大小。在YOLO v3(及其后续版本)中,解释此输出图的方式是每个单元格都可以预测固定数量的边界框。
尽管在技术上正确地称谓特征图中一个单元的术语是一个神经元,但为了让它在我们的上下文中更加直观,这里我们把它称为单元。

在数值上,特征图中有(B x(5 + C))个元素。
B表示每个单元格可以预测的边界框的数量。
根据本文,这些边界框中的每一个都可以专门用于检测某种对象。
每个边界框都有5 + C属性,这些属性描述每个边界框的中心座标,尺寸,目标得分和C类置信度。
YOLO v3会为每个单元格预测3个边界框。
如果目标的中心落在该单元的接受域中,则您希望特征图的每个单元都可以通过其边界框之一来预测该对象。
(感受野是输入图像对细胞可见的区域。有关进一步的说明,请参见卷积神经网络上的链接)。

这与YOLO的训练方式有关,其中仅一个边界框负责检测任何给定的对象。
首先,我们必须确定此边界框属于哪个单元格。

为此,我们将输入图像划分为尺寸等于最终特征图尺寸的网格。

让我们考虑下面的示例,其中输入图像为416 x 416,网络的步幅为32。
如前所述,特征图的尺寸将为13 x13。然后将输入图像划分为13 x 13个像元。

图像点图,红点对侦测到狗很有用。
在这里插入图片描述预测特征图
在这里插入图片描述每个box的元素构成

在这里插入图片描述

然后,将包含对象地面真值框中心的单元格(在输入图像上)选择为负责预测对象的单元格。在图像中,标记为红色的单元格包含地面真值框(标记为黄色)的中心。
现在,红色单元格是网格第7行中的第7个单元格。现在,我们将特征图上第7行中的第7个单元格(特征图上的对应单元格)分配为负责检测狗的单元格。

现在,该单元格可以预测三个边界框。哪一个将被分配给狗的真实值标签?为了理解这一点,我们必须将锚的概念描述一遍。
请注意,我们在此讨论的单元格是预测功能图上的单元格。
我们将输入图像划分为一个网格只是为了确定预测特征图的哪个单元负责预测该网格。

锚框

预测边界框的宽度和高度的真实值可能很有意义,但是在实践中,这会导致训练过程中出现不稳定的渐变。
取而代之的是,大多数现代物体检测器会使用对数空间转换进行预测,或者只是到称为锚点的预定义默认边界框的偏移量。
然后,将这些变换应用于锚框以获得预测。
YOLO v3具有三个锚点,可以预测每个单元格三个边界框。
回到我们前面的问题,负责检测狗的边界框将是具有真实值的锚框中具有最高IoU的边界框。
在这里插入图片描述

做出预测

以下公式描述了如何调整网络输出以获得边界框预测。
bx,by,bw,bh是我们预测的x,y中心点座标的宽度和高度。 tx,ty,tw,th是网络输出的数值。 cx和cy是网格的左上角座标。 pw和ph是该框的锚点尺寸。

中心座标

请注意,我们正在通过S型函数实现中心座标预测。

这将强制输出值在0到1之间。

为什么会这样呢?

通常,YOLO不会预测边界框中心的绝对座标。它预测的偏移量是:

相对于预测对象的网格单元的左上角。

通过特征图中的像元尺寸进行归一化,即1。

例如,考虑我们的狗图像的情况。
如果中心预测为(0.4,0.7),则意味着中心位于13 x 13特征图上的(6.4,6.7)。
(因为红色单元格的左上角座标为(6,6))。

但是,等等,如果预测的x,y座标大于1,例如(1.2,0.7),会发生什么。
这意味着中心位于(7.2,6.7)。
请注意,中心现在位于红色单元格或第7行的第8个单元格的右边。
这打破了YOLO背后的理论,因为如果我们假设红框负责预测这只狗,那么该狗的中心必须位于红细胞中,而不是在其旁边。
因此,为解决此问题,输出通过S型函数,该函数将输出压缩在0到1的范围内,从而有效地将中心保持在所预测的网格中。
在这里插入图片描述

边框的尺寸

通过对输出数值使用对数空间转换,然后与锚点相乘,可以预测边界框的尺寸。
对检测器进行输出如何转换以给出最终预测。

图片积分

结果预测bw和bh由图像的高度和宽度标准化。 (以这种方式选择训练标签)。 因此,如果对包含狗的盒子的预测bx和by为(0.3,0.8),则13 x 13特征图上的实际宽度和高度为(13 x 0.3,13 x 0.8)。

目标分数

对象分数表示对象包含在边界框内的概率。
红色和相邻的网格应该接近1,而角落的网格应该接近0。
客观性分数也将通过S形传递,因为它将被解释为概率。

类别置信度

类别置信度表示检测到的对象属于特定类别(狗,猫,香蕉,汽车等)的概率。
在v3之前,YOLO曾使用softmax来评分。
但是,该设计选择已在v3中删除,作者选择使用Sigmoid。 原因是Softmaxing类分数假定这些类是互斥的。 用简单的话来说,如果一个对象属于一个类,那么可以保证它不能属于另一个类。 这对于我们将基于检测器的COCO数据库是正确的。

但是,当我们开设“女性”和“人”这样的课程时,这种假设可能不成立。 这就是作者避免使用Softmax激活的原因。

跨不同尺度的预测。

YOLO v3可以进行3种不同尺度的预测。
检测层用于在三个不同大小的特征图中进行检测,分别具有步幅32、16、8。
这意味着,使用416 x 416的输入,我们将以13 x 13、26 x 26和52 x 52的比例进行检测。

网络对输入图像进行下采样,直到第一检测层为止,在此使用步幅为32的图层的特征图进行检测。
此外,将各层上采样2倍,并与具有相同特征图大小的先前图层的特征图连接在一起。 现在在步幅为16的层上进行另一次检测。
重复相同的上采样步骤,并在步幅8层进行最终检测。

在每个尺度上,每个像元使用3个锚点预测3个边界框,使使用的锚点总数为9。(不同尺度的锚点不同)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

输出处理

对于416 x 416尺寸的图像,YOLO预测((52 x 52)+(26 x 26)+ 13 x 13))x 3 = 10647边界框。
但是,就我们的形象而言,只有一个物体,一只狗。
我们如何将检测结果从10647减少到1?

通过对象置信度进行阈值化

首先,我们根据盒子的客观性得分对其进行过滤。
通常,分数低于阈值的框将被忽略。

非最大抑制

NMS旨在解决同一图像的多次检测问题。 例如,红色网格单元的所有3个边界框可以检测到一个框,或者相邻单元可以检测到同一对象。

在这里插入图片描述

多个单元格可能会检测同一个对象NMS被用来去除多个探测值。
如果你不知道NMS,我已经提供了一个链接来解释它。

我们的实现

YOLO 只能侦测到训练数据集里出现过的类别。
我们将使用官方权重文件来虚拟我们的侦测器。
这些权重来自于cooc数据集的网络训练,因此我们可以探测到80个类别。
第一部分到此结束了。
本文将会详细解释yolo 以便于你能够自己实现它。然而,如果你想深入理解yolo
是如何工作的,它是如何训练的,以及它与其它检测算法的比较,你可以阅读原始的论文,链接在下面。
本节结束,欢迎阅读下一节,我们将实现需求的不同层来实现这个检测器。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章