手把手教你使用PyTorch从零实现YOLOv3(1)

2019-11-15 16:29:55 浏览数 (1)

图片来源:Karol Majek

目标检测是深度学习中应用比较多的领域。近年来,人们开发了许多用于对象检测的算法,其中包括YOLO,SSD,Mask RCNN和RetinaNet。

我们将使用PyTorch来实现基于YOLO v3的目标检测,这是目前最快的目标检测算法之一。

本教程的代码旨在在Python 3.5和PyTorch 0.4上运行。可以在此Github存储库中找到全部内容。(https://github.com/ayooshkathuria/YOLO_v3_tutorial_from_scratch)

先决条件

  • 你需要了解卷积神经网络如何工作。这也包括残差块知识,跳过连接和上采样。
  • 什么是物体检测,边界框回归,IoU和非最大抑制。
  • PyTorch的基本用法。您应该能够轻松创建简单的神经网络。

什么是YOLO?

YOLO代表您只看一次。它是一种目标检测方法,它使用深度卷积神经网络学习的特征来检测对象。在弄清代码之前,我们必须了解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(及其后代)中,解释此预测图的方式是每个单元格可以预测固定数量的边界框。

尽管在技术上描述特征图中一个单元的正确的术语是神经元,但称其为细胞使它在我们的上下文中更加直观。

在深度上,特征图中有(Bx(5 C))个条目。B表示每个单元格可以预测的边界框的数量。根据本文,这些B边界框中的每一个都可以专门用于检测某种对象。每个边界框都有5 C属性,这些属性描述每个边界框的中心坐标,尺寸,置信度得分和C类置信度YOLO v3会为每个单元格预测3个边界框

如果对象的中心落在该单元的接受域中,则可以期望特征图的每个单元通过其边界框之一来预测该对象。(感受野是输入图像对细胞可见的区域。)。

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

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

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

然后,将包含对象地面真值框中心的单元格(在输入图像上)选择为负责预测对象的单元格。在图像中,标记为红色的单元格包含地面真值框的中心(标记为黄色)。

现在,红色单元格是网格第7行中的第7个单元格。现在,我们将特征图上第7行中的第7个单元格(特征图上的对应单元格)分配为负责检测狗的那个单元格。

现在,该单元格可以预测三个边界框。哪一个将被分配给狗的地面真相标签?为了理解这一点,我们必须围绕锚的概念展开思考。

请注意,我们在此讨论的单元格是预测特征图上的单元格。我们将输入图像划分为一个网格只是为了确定预测特征图的哪个单元负责预测。

锚盒

预测边界框的宽度和高度可能很有意义,但是在实践中,这会导致训练过程中出现不稳定的渐变。取而代之的是,大多数现代物体检测器会预测对数空间转换,或者只是偏移到称为“ 锚点”的预定义默认边界框。

然后,将这些变换应用于锚框以获得预测。YOLO v3具有三个锚点,可预测每个单元格三个边界框。

回到我们前面的问题,负责检测狗的边界框将是具有地面真理框的锚具有最高IoU的边界框。

做出预测

以下公式描述了如何转换网络输出以获得边界框预测。

YOLO方程 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数据库是正确的。

但是,当我们有像Women和Person这样的类时,这种假设可能不成立。这就是作者避免使用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。(不同尺度的锚是不同的)

作者报告说,这有助于YOLO v3更好地检测小物体,这是YOLO早期版本的常见问题。上采样可以帮助网络学习细粒度的功能,这些功能对于检测小物体很有帮助。

输出处理

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

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

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

非最大抑制

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

我们的实施

YOLO只能检测属于用于训练网络的数据集中存在的类的对象。我们将使用检测器的官方权重文件。这些权重是通过在COCO数据集上训练网络获得的,因此我们可以检测80个对象类别。

这是第一部分。这篇文章介绍了有关YOLO算法的足够知识,使您能够实现检测器。但是,如果您想深入了解YOLO的工作原理,训练方式以及与其他检测器相比的性能,则可以阅读原始文章,我在下面提供了这些文章的链接。

https://pjreddie.com/media/files/papers/YOLOv3.pdf

参考文献:

how-to-implement-a-yolo-object-detector-in-pytorch

0 人点赞