目标检测是用于在图像中查找感兴趣目标的计算机视觉技术:

 

目标检测入门

 

这比只能告诉你图像的“主体”是什么的分类更高类 ,目标检测可以找到多个目标,并对它们进行分类并找到它们在图像中的位置。

 

目标检测模型为每个目标预测一个边界框和目标的分类概率。

目标检测常常会预测太多的边界框。每个框还有一个置信度分数,表示模型认为该框确实包含一个目标的可能性。作为后处理步骤,我们筛选掉分数低于某个阈值的框(这个步骤也称为非最大值抑制)。

 

目标检测比分类更棘手。你会遇到的问题之一是,训练图像可能有零到几十个目标,并且该模型可能输出多个预测,那么在损失函数中,你该将哪个预测结果与哪个真实边界框做比较?

 

像Faster R-CNN这样的高端模型首先提取候选区域 ——图像中可能包含目标的区域 ,然后对每个区域进行单独预测。它的效果很好,但也很慢,因为它需要多次运行模型的检测和分类。

另一方面,一次性检测器只需要通过神经网络一次,一次性预测所有边界框。一次性检测更快,更适合移动设备。一次性物体检测器最常见的例子是YOLO,SSD,SqueezeDet和DetectNet。

 

在这篇文章中,我将尝试解释这些一次性检测器是如何工作的以及如何对它们进行训练和评估。

 

为什么目标检测如此棘手

 

分类器将图像作为输入并生成单个输出,即类的概率分布。但是,这只能给出图像整体内容的概要,当图像具有多个感兴趣的目标时,分类并不适合。

 

在下图中,分类器可能会认识到图像的某部分包含“猫”和某部分包含“狗”,但这已经是它能做出的最好结果。

 

目标检测入门

 

另一方面,目标检测模型将通过预测每个目标的边界框来告诉您每个目标的位置:

 

目标检测入门

 

由于它现在可以专注于对边界框内的物体进行分类,并忽略外部的所有物体,所以该模型能够对各个目标给出更加可靠的预测。

 

如果您的数据集带有边界框标注(所谓的真实标签框),则向您的模型添加位置输出非常容易。只需预测另外4个数字,即边界框的每个角。

 

目标检测入门

 

现在该模型有两个输出:

1. 分类结果的概率分布,以及

2. 边界框回归。

 

模型的损失函数简单地将边界框的回归损失(通常使用均方误差

(MSE))与分类的交叉熵损失相加,:

 

  1. outputs = model.forward_pass(image)
  2. class_pred = outputs[0]
  3. bbox_pred = outputs[1]
  4. class_loss = cross_entropy_loss(class_pred, class_true)
  5. bbox_loss = mse_loss(bbox_pred, bbox_true)
  6. loss = class_loss + bbox_loss
  7. optimize(loss)

 

现在,您可以像往常一样在上面的相加的损失上使用SGD来优化模型,实际上效果非常好。以下是一个预测示例:

 

目标检测入门

 

该模型已经正确地找到了该目标的类(狗)以及它在图像中的位置。红色框是真实标签框,而青色框是预测。这不是一个完美重合,但非常接近。

 

注意:这里给出的分数52.14%是狗的分类分数82.16%和边界框包含目标的可能性的可信度分数63.47%的综合。

 

 

为了对预测框与真实标签框相匹配的程度进行评分,可以计算两个边界框之间的IOU(或interaction-over-union,也称为Jaccard指数)。

 

IOU是0到1之间的数字,越大越好。理想情况下,预测框和真实标签框的IOU为100%,但在实践中超过50%通常被认为是正确的预测。对于上面的例子,IOU是74.9%,你可以认为这两个框是很好的匹配。

 

使用回归输出预测单个边界框会得到不错的结果。但是,就像分类在图像中有多个感兴趣的目标时效果不佳,那么这个简单的定位方案就失败了:

 

目标检测入门

 

该模型只能预测一个边界框,因此它必须选择其中一个目标,但是该框会在中间某处结束。事实上,这里发生的事情是非常有意义的:模型知道有两个物体,但它只有一个边界框可以分配,所以它会妥协并将预测的框放在两匹马之间。框的大小也在两匹马的大小之间。

 

注意:您可能会期望模型现在可以围绕两个目标绘制框,但这并不会发生,因为它尚未接受过这方面的训练。数据集中的真实标签框总是绘制在单个目标周围,而不是围绕一组目标。

 

你可能会认为,“这听起来很容易解决,让我们通过给模型附加回归输出来添加更多的边界框检测器。”毕竟,如果模型可以预测N个边界框,那么它应该能够找到N个目标,对不?听起来像一个好主意...但它并不奏效。

 

即使有一个具有多个这样的检测器的模型,我们最终仍然会得到位于图像中间的边界框:

 

目标检测入门

为什么会这样?问题在于模型不知道应该将哪个边界框分配给哪个目标,为了安全起见,将它们放在中间的某个位置。

 

模型没有办法决定,“我可以把边界框1放在左边的马上,边界框2放在右边的马上”。相反,每个检测器仍然试图预测所有的目标,而不是仅仅其中一个。尽管模型有N个检测器,但它们不能作为一个团队一起工作。具有多个边界框检测器的模型的行为与仅预测一个边界框的模型完全相同。

 

我们需要的是专用边界框检测器,以便每个检测器将尝试仅预测单个目标,并且不同的检测器将找到不同的目标。

 

在一个非专门化的模型中,每个检测器都应该能够处理图像中任何可能位置的每种可能类型的目标。模型现在试图学习如何预测始终处于图像中心的方框,因为这样做在整个训练集中实际上可以最大限度地减少错误数量。

 

从SGD的角度来看,平均来说得到了相当不错的结果,但在实践中这也不是一个真正有用的结果......所以我们需要更清晰地了解我们如何训练模型。

 

通过将每个边界框检测器分配到图像中的特定位置,诸如YOLO,SSD和DetectNet等一次性检测器都解决了这个问题。这样检测器就可以专门研究特定位置的物体。为了获得更好的结果,我们还可以让检测器专门研究物体的形状和大小。

 

使用网格

 

使用固定的检测器网格是支撑一次性检测器的主要思想,也是区分一次性检测与R-CNN等基于候选区域的检测器的因素。

 

让我们考虑这种模型可能的最简单架构。它存在一个充当特征提取器的基础网络。像大多数特征提取器一样,它通常在ImageNet上进行预训练。

 

对于YOLO的情况,特征提取器以416×416像素图像作为输入。 SSD通常使用300×300图像。这些比用于分类的图像(通常是224×224)更大,因为我们不希望丢失小细节。

 

目标检测入门

 

基础网络可以是任意的,例如Inception或ResNet或YOLO的DarkNet,但在移动设备上使用SqueezeNet或MobileNet等小型快速架构会更好。

 

(在我自己的实验中,我使用了经过224×224图像训练的MobileNet V1特征提取器,并将其扩展至448×448,然后在包括130万幅图像的ILSVRC 2012数据集上,使用诸如随机截取和颜色抖动等基本数据增强技术,对这个网络进行了7个epoch的微调,在这些较大的图像上重新训练特征提取器使得该模型在用于物体检测的输入为416×416上更好地工作。)

 

在特征提取器的顶部是几个额外的卷积层。对这些层进行了微调,以学习如何预测这些边界框内的目标边界框和类概率。这是模型的目标检测部分。

 

有许多用于训练物体检测器的常用数据集。在这篇文章,我们将使用Pascal VOC数据集,它有20个类。这里的神经网络的训练的第一部分是在ImageNet上进行的,第二部分是在VOC上。

 

当您查看YOLO或SSD的实际架构时,它们比这个简单的示例网络稍微复杂一些,它们增加了跳过连接等,稍后将会介绍。现在上述模型就足够了,而且事实上可以用它来构建一个快速且相当精确的物体检测器。

 

最后一层的输出是一个特征图(上图中的绿色部分)。对于这里的示例模型,它是一个具有125个通道的13×13特征图。

注意:这里的数字13是因为像素的输入大小为416,而且这里使用的特定基础网络具有五个池化层(或具有步幅2的卷积层),它们一起使得输入缩小了32倍,而416/32 = 13。如果你想要一个更细的网格,例如19×19,那么输入图像应该是19×32 = 608像素宽和高(或者你可以使用更小步幅的网络)。

 

我们将此特征图解释为由13X13的单元格组成的网格。这个数字是奇数的,使得网格中心只有一个单元格。网格中的每个单元有5个独立的物体检测器,每个检测器预测一个单独的边界框。

 

目标检测入门

 

关键在于检测器的位置是固定的:它只能检测位于该单元附近的物体(事实上,物体的中心必须位于网格单元内)。这可以让我们避免先前的问题,即检测器有太多的自由(注:即可以检测任何位置的物体)。通过这个网格,图像左侧的检测器将永远不会预测位于右侧的物体。

 

每个物体检测器产生25个数字:

• 包含类概率的20个数字

• 4个边界框坐标(中心x,中心y,宽度,高度)

• 1个置信度分数

 

由于每个单元有5个检测器,并且5×25 = 125,这就是为什么我们有125个输出通道的原因。

 

与常规分类器一样,20个类别概率上都使用了softmax。我们可以通过查看最大的数值来获得预测的类别。

 

置信度分数是介于0和1(或100%)之间的数字,它描述模型认为此预测边界框包含目标的可能性。它也被称为“目标”分数。请注意,这个分数只能说明这是否是一个目标,但没有说明这是什么类型的目标(它是用类的概率表示的)。

 

该模型总是预测相同数量的边界框:13×13个单元乘5个检测器给出845个预测。很明显,绝大多数这些预测都是不好的 - 毕竟,大多数图像最多只包含少数几个目标,不会超过800个。置信度分数告诉我们可以忽略哪些预测框。

 

通常我们最终会得到十几个模型认为是好的预测。其中一些会重叠 - 这是因为附近的单元格可能会对同一个目标做出预测,而有时单个单元会做出多个预测(尽管在训练中这种情况不鼓励)。

 

目标检测入门

 

具有多个较大重叠的预测对于物体检测很常见。常规的后处理技术是应用非最大值抑制(NMS)来消除这种重复。简而言之,NMS保留那些具有最高置信度分数的预测结果,并去除任何与这些最高置信度的边框有重叠超过一定阈值(例如60%)的其他框。

 

通常我们只会保留10个左右的最佳预测,并舍弃其他预测。理想情况下,我们希望对图像中的每个目标只有一个边界框。

 

好吧,它描述了使用网格进行目标检测预测的基本流程。但是它为什么能起作用呢?

 

制约因素很好

 

我已经提到,将每个边界框检测器分配到图像中的固定位置是使一次性目标检测器运行良好的技巧。我们使用13×13网格作为空间约束,以使模型更容易学习如何预测目标。

 

使用这种(架构)约束是机器学习的一种有用的技术。实际上,卷积本身也是一个约束:卷积层实际上只是全连接(FC)层的受限制的版本。 (这就是为什么你可以使用FC层实现卷积,反之亦然 - 它们基本上是一回事。)

 

如果我们只使用普通的FC层,那么机器学习模型就很难学习图像。强加在卷积层上的约束—— 一次只能看到几个像素,并且连接共享相同的权重 —— 帮助模型从图像中提取知识。我们使用这些约束来消除自由度并指导模型学习我们想要学习的内容。

 

同样,网格强制模型学习专门针对特定位置的物体检测器。位于左上角的单元格中的检测器仅预测位于左上角单元格附近的目标,而不会预测相距较远的目标。 (该模型是经过训练的,以便给定网格单元中的检测器仅负责检测其中心位于该网格单元内的物体。)

 

网格是一个有用的约束,它限制了检测器可以在图像中找到目标的位置。我们还可以添加另一个约束来帮助模型做出更好的预测,那就是目标形状的约束。

 

我们的示例模型具有13×13个网格单元,每个单元有5个检测器,因此总共有845个检测器。但为什么每个网格单元有5个检测器而不是一个?那么,就像检测器很难学习如何预测可以放在任何地方的物体一样,检测器也很难学会预测任何形状或大小的物体。

 

我们使用网格来专门化我们的检测器,使其只查看特定的空间位置,并且通过每个网格单元有多个不同的检测器,我们可以使这些物体检测器中的每一个都专注于某种物体形状。

我们训练5种特定形状的检测器:

 

目标检测入门

 

红色框是训练集中五个最典型的目标形状。青色框分别是训练集中最小的和最大的目标。请注意,这些边界框以模型的416×416像素输入分辨率显示。 (该图还显示了浅灰色的网格,因此您可以看到这五个形状如何与网格单元相关联,每个网格单元格覆盖输入图像中的32×32像素。)

 

这五种形状被称为锚或锚框。锚只不过是宽度和高度的列表:

锚= [1.19,1.99,#锚1的宽度,高度

2.79,4.60,#锚2的宽度,高度

4.54,8.93,#等

8.06,5.29,

10.33,10.65]

 

锚描述数据集中的5个最常见(平均)目标形状。而“形状”只是指它们的宽度和高度,因为在这里总是使用基本的矩形。

 

有5个锚不是偶然的。网格单元中的每个检测器都有一个锚。就像网格对检测器施加位置约束一样,锚将检测器内部的检测器强制为专用于特定目标形状。

 

单元格中的第一个检测器负责检测尺寸与第一个锚相似的目标,第二个检测器负责尺寸与第二个锚相似的目标,等等。因为我们每个单元有5个检测器,所以我们也有5个锚。

 

因此,检测器1将拾取小物体,检测器2拾取稍大的物体,检测器3拾取长而平的物体,检测器4拾取高而薄的物体,检测器5拾取大物体。

 

注意:上面代码片段中锚的宽度和高度表示在网格的13×13坐标系中,因此第一个锚的宽度略大于网格单元格的宽度,它的高度将近2个网格单元格的高度。最后一个锚几乎覆盖整个网格,超过10×10个单元格。这就是YOLO存储它的锚的方法。然而,SSD具有几个不同尺寸的不同网格,因此使用标准化的坐标(介于0和1之间)作为锚,以便它们独立于网格的大小。两种方法都可以。

 

了解这些锚是事先选定的,这很重要。它们是常量,在训练过程中它们不会改变。

 

由于锚只有宽度和高度,而且它们是预先选择的,YOLO的论文也称它们为“尺寸先验”。 (Darknet官方的YOLO源代码称它们为“偏置”,我认为这是“正确的” ——检测器偏向于预测某种形状的物体 - 但这个术语重用会令人混淆。)

 

YOLO通过在所有训练图像的所有边界框上运行k-means聚类来选择锚(k = 5,因此它找到五个最常见的目标形状)。因此,YOLO的锚是特定于您正在训练(和测试)的数据集的。

 

k-means算法找到了将所有数据点划分聚类的方法。这里的数据点是数据集中所有真实边界框的宽度和高度。如果我们从Pascal VOC数据集的框中运行k-means,我们会发现以下5个聚类:

 

目标检测入门

 

这些聚类表示存在于此数据集中的不同目标形状的五个“平均值”。您可以看到,k-means发现有应该将蓝色聚类中的很小的目标,红色聚类中的稍大的目标以及绿色的非常大的目标分别组合在一起。它决定将中等物体分成两组:一组边界框(黄色)宽大于高,另一个(紫色)高大于宽。

 

但5个锚是否最佳选择?我们可以在不同数量的聚类上多次运行k-means,并计算真实标签框与它们最接近的锚框之间的平均IOU。毫不奇怪,使用更多质心(k值越大)平均IOU越高,但这也意味着我们需要在每个网格单元中使用更多的检测器,并使模型运行速度变慢。对于YOLO v2,他们选择了5个锚作为召回率和模型复杂度之间的良好折衷。

 

目标检测入门

SSD不使用k-means来查找锚。相反,它使用数学公式来计算锚大小。因此,SSD的锚独立于数据集(顺便说一下,SSD的论文称它们为“默认框”)。你会认为特定于数据集的锚会给出更好的预测,但我不确定它是否真的很重要(YOLO作者似乎认为它确实重要)。

 

另一个小区别:YOLO的锚只有一个宽度和高度,但SSD的锚还有一个x,y位置。 YOLO只是假定锚的位置总是在网格单元的中心。 (对于SSD,这也是默认要处理的事)

 

由于有了锚,检测器不必非常努力地做出非常好的预测,因为假如预测的所有值都为零,意味着只需简单地输出锚框,这将与真实目标框(平均值)相当接近。这使得训练变得更容易!如果没有锚,每个检测器都必须从头开始学习不同的边界框形状是什么......这是一个非常困难的任务。

 

注意:当我在本文中谈论YOLO时,通常指的是YOLO v2或v3。如果你正在阅读2015-2016年左右的论文或博客文章,他们提到YOLO,他们经常谈论的YOLO v1,这是显着不同的。版本1有一个较小的网格(7×7,每个单元只有2个检测器),使用全连接的层而不是卷积层来预测网格,并且不使用锚。 YOLO版本现已过时。 v2和v3之间的差异要小得多。而随着V3的推出,YOLO在很多方面已经变得与SSD非常相似。

 

模型实际预测的是什么?

 

让我们看一下示例模型的输出。由于它只是一个卷积神经网络,所以正向传播是这样的:

 

目标检测入门

您输入一个416×416像素的RGB图像,卷积层对图像的像素应用各种变换,输出为13×13×125的特征图。由于这是一个回归输出,因此不会将激活函数应用于最终层。输出结果只有21,125个实数,我们必须以某种方式将这些数字转换为边界框。

 

它需要4个数字来描述边界框的坐标。有两种常用的方法可以做到这一点:无论是用xmin,ymin,xmax,ymax来描述框的边缘,还是用中心x,中心y,宽度,高度。这两种方法都很好,但我们将使用后者(知道框的中心在哪里可以更容易地将框与网格单元匹配)。

 

模型预测的每个边界框不是它们在图像中的绝对坐标,而是四个“增量”值或偏移量:

• delta_x,delta_y:网格单元格内框的中心

• delta_w,delta_h:锚框宽度和高度的比例因子

 

每个检测器都会预测出相对于它的锚的值。锚框应该已经是实际物体大小的一个相当不错的近似值(这就是我们使用它们的原因),但它并不准确。这就是为什么我们预测一个比例因子,表示框比锚大或小,以及一个位置偏移量,表示预测箱离该网格中心有多远。

 

为了得到像素坐标中边界框的实际宽度和高度,我们这样做:

 

box_w [i,j,b] = anchor_w [b] * exp(delta_w [i,j,b])* 32

box_h [i,j,b] = anchor_h [b] * exp(delta_h [i,j,b])* 32

 

其中i和j是网格中的行和列(0 - 12),b是检测器索引(0 - 4)。

 

可以预测的框比原始图像更宽和/或更高,但对于框具有负宽度或负高度没有意义。这就是为什么我们采用预测数字的指数值。

 

如果预测的delta_w小于0,则exp(delta_w)是介于0和1之间的数字,使得该框比锚框小。如果delta_w大于0,则exp(delta_w)数字> 1,这使得框变宽。如果delta_w恰好为0,那么exp(0)= 1,并且预测框与锚框的宽度完全相同。

 

顺便说一句,我们乘以32是因为锚坐标位于13×13网格中,每个网格单元覆盖了416×416输入图像中的32个像素。

 

注意:有趣的是,在损失函数中,我们实际上会使用上述公式的逆版本。我们将取真实值的log(),而不是对预测值进行exp()。

 

为了得到预测框在像素坐标中的中心x,y位置,使用:

 

  1. box_x [i,j,b] =(i + sigmoid(delta_x [i,j,b]))* 32
  2. box_y [i,j,b] =(j + sigmoid(delta_y [i,j,b]))* 32

 

YOLO的一个主要特点是,它鼓励检测器只在发现其中心位于检测器网格单元内部的目标时预测边界框。这有助于避免虚假检测,使得多个相邻网格单元不会全部都找到相同的目标。

 

为了强制执行此操作,delta_x和delta_y必须被限制为0到1之间的数字,该数字是网格单元格内的相对位置。这就是sigmoid函数的用途。

 

然后,我们添加网格单元坐标i和j(均为0 - 12),并乘以每个网格单元(32)的像素数。现在box_x和box_y是原始416×416图像空间中预测边界框的中心。

 

SSD的做法略有不同:

 

  1. box_x [i,j,b] =(anchor_x [b] + delta_x [i,j,b] * anchor_w [b])* image_w
  2. box_y [i,j,b] =(anchor_y [b] + delta_y [i,j,b] * anchor_h [b])* image_h

 

这里的预测增量值实际上是锚框宽度或高度的倍数,并且没有S形激活。这意味着目标的中心实际上可能位于具有SSD的网格单元之外。

 

另请注意,使用SSD时,预测的坐标是相对于锚框中心而不是网格单元的中心。在实践中,锚框的中心将与网格单元的中心完全对齐,但是它们使用不同的坐标系。 SSD的锚坐标在[0,1]范围内,以使它们与网格大小无关。 (这是因为SSD使用了多个不同大小的网格。)

 

正如你所看到的,尽管YOLO和SSD通常以相同的方式工作,但当你开始查看小细节时,它们是不同的。

 

除了坐标之外,该模型还预测了边界框的置信度分数。因为我们希望这是一个介于0和1之间的数字,所以使用标准技巧,并通过一个sigmoid:

 

confidence [i,j,b] = sigmoid(predicted_confidence [i,j,b])

 

回想一下,我们的示例模型总是预测845个边界框,不多也不少。但通常图像中只有少数物体。在训练过程中,我们只鼓励一个检测器对每个真实值进行预测,因此只有少数预测值具有较高的置信度。没有找到目标的检测器的预测(迄今为止其中大多数)应该具有非常低的置信度。

 

最后,我们预测类概率。对于Pasval VOC数据集,每个边界框是20个数字的向量。像往常一样,我们应用softmax使其成为一个很好的概率分布:

 

class[i,j,b] = softmax(predicted_classes [i,j,b])

 

你也可以使用sigmoid激活代替softmax。这使得它成为一个多标签分类器,在这种情况下,每个预测的边界框实际上可以同时具有多个类。 (这是SSD和YOLO v3所做的。)

 

请注意,SSD不使用这种置信度分数。相反,它为分类器添加了一个特殊的类 - “背景”。如果预测为背景类,则检测器未找到目标。这与YOLO给出低置信度分数是一样的。

 

由于我们需要更多的预测,而且大多数预测都不好,我们现在会用非常低的分数滤除预测结果。在YOLO,我们通过将框的置信度分数,即“这个框包含一个目标的可能性有多大”,与最大类别概率,即“框包含这个类的一个目标的可能性有多大“,相结合来做到这一点。

 

confidence_in_class [i,j,b] =class[i,j,b] .max()* confidence [i,j,b]

 

低置信度分数意味着模型不确定这个框是否真的包含一个目标;低类概率意味着该模型不确定该框中的目标是什么类型。为了得到严谨的预测,这两个分数都需要很高。

 

由于大多数框不包含任何目标,因此我们现在可以忽略所有confidence_in_class低于特定阈值(例如0.3)的框,然后对剩余框执行非最大抑制以消除重复。我们通常最终会有1到10个预测值。

 

它是卷积的!

检测器网格实际上是使用卷积神经网络的自然选择。

 

13×13网格是卷积层的输出。如您所知,卷积是一个滑过输入图像的小窗口(或内核)。这个内核的权重在每个输入位置都是相同的。我们的示例模型的最后一层有125个这样的内核。

 

目标检测入门

 

为什么125?有5个检测器,每个检测器有25个卷积核。这25个内核中的每一个预测检测器边界框的一个方面:x,y,宽度,高度,置信度分数,20个类别概率。

 

注意:一般来说,如果您的数据集具有K个类别,并且您的模型具有B个检测器,那么网格需要具有B×(4 + 1 + K)个输出通道。

 

这125个内核在13×13特征图的每个位置滑动,并在每个位置进行预测。然后,我们将这125个数字解释为构成5个预测的边界框以及该网格位置的类别分数(这是损失函数的工作,将在下面的内容介绍更多)。

 

最初,在每个网格位置得到预测的125个数字将是完全随机的和无意义的,但随着训练的进展,损失函数将指导模型学习做出更有意义的预测。

 

现在,尽管我一直说每个网格单元中有5个检测器,总体来说,对于845个检测器,但该模型实际上总共仅学习了5个检测器 - 而不是每个网格单元的5个检测器。这是因为卷积层的权重在每个位置都是相同的,因此在网格单元之间共享。

 

该模型实际上为每个锚学习一个检测器。它将这些检测器在图像上滑动以获得845个预测值,每个网格上有5个预测值。因此,即使我们总共只有5个单独的检测器,由于卷积,这些检测器与图像中的位置无关,因此可以检测物体,而不管它们位于何处。

 

它是给定位置的输入像素与该检测器/卷积核所学习的权重的组合,其决定了该位置处的最终边界框预测。

 

这也解释了为什么模型总是预测边界框相对于网格单元的中心的位置。由于这个模型的卷积性质,它不能预测绝对坐标。由于卷积核在图像上滑动,所以它们的预测总是相对于它们在特征图中的当前位置。

 

YOLO VS SSD

以上对一次性物体检测器如何工作的描述几乎适用于所有一次性检测算法。如何解释输出的精度可能存在细微差异(例如,对于类概率使用sigmoid而不是softmax),但总体思路是相同的。

不过,各种版本的YOLO和SSD之间存在一些有趣的架构差异。

 

以下是YOLO v2&v3和SSD的不同架构草图:

 

目标检测入门

 

正如你所看到的,YOLO v3和SSD在很高的级别上是非常相似的,虽然他们通过不同的方法达到了最终的网格尺寸(YOLO使用上采样,SSD下采样)。

 

在YOLO v2(以及我们的示例模型)只有一个13×13输出网格的情况下,SSD有几个不同尺寸的网格。 MobileNet + SSD版本有6个网格,大小分别为19×19,10×10,5×5,3×3,2×2和1×1。

 

所以SSD网格从非常精细到非常粗糙。它这样做是为了在更广泛的目标尺度上获得更准确的预测。

 

精细的19×19网格,其网格单元非常接近,负责最小的物体。由最后一层产生的1×1网格负责对基本上占据整个图像的大物体作出响应。来自其他层的网格覆盖它们之间的目标大小。

 

YOLO v2试图通过跳过连接做类似的事情,但这似乎效率不高。 YOLO v3更像SSD,它使用3个具有不同比例的网格来预测边界框。

 

像YOLO一样,每个SSD网格单元格都会进行多重预测。每个网格单元的检测器数量会有所不同:对于更大,更细粒度的特征图,SSD每个网格单元有3或4个检测器,而在较小的网格上,每个单元有6个检测器。 (YOLO v3在每个尺度上每个网格单元使用3个检测器。)

 

在SSD的论文中,坐标预测也与锚(称为“默认框”)相关 ——区别是SSD预测的中心坐标可能会超出其网格单元。锚框的中心在单元框内,但SSD不会将sigmoid应用于预测的x,y偏移量。因此,从理论上讲,模型右下角的一个方框可以预测一个中心位于图像的左上角的边界框(但实际上这可能不会发生)。

 

不像YOLO,SSD没有置信度分数。每个预测仅由4个边界框坐标和类概率组成。 YOLO使用置信度分数来表示这个预测是一个正确的目标的可能性。 SSD通过具有特殊的“背景”类别来解决这个问题:如果类别预测为背景类别,则意味着没有找到该检测器的目标。这与YOLO的低置信度分数相同。

 

SSD的锚与YOLO有些不同。由于YOLO必须从单个网格进行所有预测,因此它使用的锚范围从小(大约是单个网格单元的大小)到大(大约整个图像的大小)。

 

SSD更保守。 19×19网格上使用的锚框比10×10网格上的锚框小,而10X10中的锚框比5×5网格中的那些要小,以此类推。与YOLO不同,SSD不使用锚来使检测器专门预测物体大小,SSD使用不同的网格做到这点。

 

SSD锚主要用于使检测器专门针对物体形状的不同可能的高宽比,而不是其大小。如前所述,SSD的锚是用一个简单的公式计算出来的,而YOLO的锚是通过在训练数据上运行k-means聚类找到的。

 

由于SSD使用3到6个锚,而且它有六个网格而不是一个,所以它实际上总共使用了32个独特的检测器(根据您实际上使用的模型架构,此数量会有所变化)。

 

由于SSD具有更多的网格和检测器,因此它还输出更多的预测。 YOLO产生845个预测,而MobileNet-SSD产生1917个预测。一个更大的版本SSD512甚至可以输出24,564个预测!它的好处是你更有可能找到图像中的所有目标。缺点是你最终不得不做更多的后处理来确定你想保留哪些预测。

 

由于这些差异,SSD和YOLO在真实边界框与检测器匹配的方式有点不同。损失函数也略有不同。后面训练时会介绍这些内容。

 

注意:还有一个名为SSDLite的变体,它与SSD相同,但使用深度可分离的卷积而不是常规卷积层。由于这一点,它比普通SSD快得多,非常适合在移动设备上使用。

 

好的,这就是关于这些模型如何进行预测的足够理论。现在来看看训练目标检测模型需要的一些数据。