由瓦西利斯·弗里尼奥蒂斯

在上一篇文章中,我们讨论了 SSD 算法的工作原理,介绍了其实现细节,并展示了其训练过程。如果您还没有阅读上一篇博客文章,我鼓励您在继续之前先阅读一下。

在本系列的第二部分,我们将关注 SSD 的移动友好版本——SSDlite。我们的计划是首先介绍算法的主要组件,突出与原始 SSD 不同的部分,然后讨论发布模型的训练过程,最后提供我们探索的所有新目标检测模型的详细基准。

SSDlite 网络架构

SSDlite 是 SSD 的一种改编,最初在 MobileNetV2 论文中简要介绍,后来在 MobileNetV3 论文中再次使用。由于这两篇论文的主要重点是介绍新的 CNN 架构,因此 SSDlite 的大部分实现细节都没有得到明确说明。我们的代码遵循了两篇论文中提出的所有细节,并在必要时填补了官方实现中的空白。

如前所述,SSD 是一个模型系列,因为可以配置不同的骨干网络(如 VGG、MobileNetV3 等)和不同的头部(如使用常规卷积、可分离卷积等)。因此,SSDlite 中的许多组件保持不变。以下我们将讨论那些不同的部分

分类和回归头部

遵循 MobileNetV2 论文的第 6.2 节,SSDlite 将原始头部中使用的常规卷积替换为可分离卷积。因此,我们的实现引入了使用 3x3 深度卷积和 1x1 投影的新头部。由于 SSD 方法的所有其他组件保持不变,为了创建 SSDlite 模型,我们的实现初始化 SSDlite 头部并将其直接传递给 SSD 构造函数。

骨干网络特征提取器

我们的实施引入了一个新的类来构建 MobileNet 特征提取器。遵循 MobileNetV3 论文的第 6.3 节,骨干网络返回 Inverted Bottleneck 块的扩展层输出,该输出步长为 16,以及池化层之前的层的输出,该输出步长为 32。此外,所有额外的骨干块都被替换为使用 1x1 压缩、步长为 2 的可分离 3x3 卷积和 1x1 扩展的轻量级等效块。最后,为了确保即使使用小的宽度乘数时头部也有足够的预测能力,所有卷积的最小深度大小由 min_depth 超参数控制。

SSDlite320 MobileNetV3-Large 模型

本节讨论了提供的 SSDlite 预训练模型的配置以及为了尽可能接近论文结果而遵循的训练过程。

训练过程

所有用于在 COCO 数据集上训练模型的超参数和脚本都可以在我们的参考文献文件夹中找到。在这里,我们讨论了训练过程中的最显著细节。

调优超参数

尽管论文没有提供用于训练模型(如正则化、学习率和批大小)的超参数信息,但官方仓库中的配置文件中列出的参数是良好的起点,我们通过交叉验证调整它们到最佳值。所有这些都使我们比基线 SSD 配置有了显著的提升。

数据增强

与 SSD 相比,SSDlite 的关键重要区别在于其骨干网络只有后者权重的一小部分。这就是为什么在 SSDlite 中,数据增强更注重使模型对大小可变的对象具有鲁棒性,而不是试图避免过拟合。因此,SSDlite 仅使用 SSD 变换的一部分,从而避免了模型的过度正则化。

学习率方案

由于依赖于数据增强来使模型对小型和中型对象具有鲁棒性,我们发现使用大量 epoch 对于训练方案特别有益。更具体地说,通过使用比 SSD 大约 3 倍多的 epoch,我们能够将精度提高 4.2mAP 点,通过使用 6 倍乘数,我们提高了 4.9mAP。进一步增加 epoch 似乎会产生递减的回报,并使训练变得太慢且不切实际,尽管如此,根据模型配置,似乎论文的作者使用了等效的 16 倍乘数。

权重初始化 & 输入缩放 & ReLU6

一系列最终优化使我们的实现非常接近官方版本,并帮助我们缩小了准确度差距,包括从头开始训练骨干网络而不是从 ImageNet 初始化,调整我们的权重初始化方案,更改我们的输入缩放,并将所有添加在 SSDlite 头部上的标准 ReLU 替换为 ReLU6。请注意,由于我们从随机权重开始训练模型,我们还额外应用了论文中描述的骨干网络使用缩减尾部进行速度优化的方法。

实现差异

将上述实现与官方仓库中的实现进行比较,我们发现了一些差异。其中大部分都是微小的,它们与我们初始化权重的方式(例如正态初始化与截断正态)有关,以及我们如何参数化 LR 调度(例如较小的预热率与较大的预热率,较短的训练与较长的训练)等。最大的已知差异在于我们计算分类损失的方式。更具体地说,官方仓库中 SSDlite 使用 MobileNetV3 作为骨干网络的实现没有使用 SSD 的多框损失,而是使用了 RetinaNet 的 focal 损失。这与论文有相当大的偏差,并且由于 TorchVision 已经提供了 RetinaNet 的完整实现,我们决定使用正常的多框 SSD 损失来实现 SSDlite。

关键精度改进的分解

如前文所述,复现研究论文并将其移植到代码中并非单调递增准确性的旅程,尤其是在不知道完整训练和实现细节的情况下。通常,这个过程涉及大量的回溯,因为需要从那些对准确性有显著影响的实现细节和参数中识别出那些没有影响的参数。以下我们尝试可视化那些从基线开始提高我们准确性的最重要的迭代:

迭代 平均精度均值(mAP)
基于“SSD-style”超参数的基线 10.6
+ 调优超参数 14.2
+ SSDlite 数据增强 15.2
+ 3 倍学习率方案 19.4
+ 6 倍学习率方案 20.1
+ 权重初始化 & 输入缩放 & ReLU6 21.3

上述提出的优化顺序是准确的,尽管在某些情况下有些理想化。例如,虽然在超参数调整阶段测试了不同的调度器,但它们都没有提供显著的改进,因此我们保留了基线中使用的 MultiStepLR。然而,在后来尝试不同的 LR 方案时,我们发现切换到 CosineAnnealingLR 是有益的,因为它需要的配置更少。因此,我们认为上述总结的主要启示应该是,即使从同一系列模型中正确的实现和一组最优超参数开始,通过优化训练方案和调整实现,仍然可以找到准确度提升的点。诚然,上述是一个极端案例,准确度翻倍了,但仍然在许多情况下,有许多优化可以帮助我们显著提高准确度。

基准测试

下面是如何初始化两个预训练模型的:

ssdlite = torchvision.models.detection.ssdlite320_mobilenet_v3_large(pretrained=True)
ssd = torchvision.models.detection.ssd300_vgg16(pretrained=True)

下面是新模型和选定的先前检测模型之间的基准测试:

Model mAP CPU 上推理(秒) # 参数(M)
SSDlite320 MobileNetV3-Large 21.3 0.0911 3.44
SSD300 VGG16 25.1 0.8303 35.64
SSD512 VGG16(未发布) 28.8 2.2494 37.08
SSD512 ResNet50(尚未发布) 30.2 1.1137 42.70
Faster R-CNN MobileNetV3-Large 320 FPN(低分辨率) 22.8 0.1679 19.39
Faster R-CNN MobileNetV3-Large FPN(高分辨率) 32.8 0.8409 19.39

如我们所见,SSDlite320 MobileNetV3-Large 模型迄今为止是最快且最小的模型,因此它是现实世界移动应用的绝佳候选者。尽管其准确率低于预训练的低分辨率 Faster R-CNN 相当,但 SSDlite 框架具有适应性,可以通过引入具有更多卷积的重型头部来提高其准确率。

另一方面,SSD300 VGG16 模型相当慢且精度较低。这主要是因为它的 VGG16 骨干网络。虽然 VGG 架构非常重要且具有影响力,但如今已经相当过时。因此,尽管这个特定模型具有历史和科研价值,因此被包含在 TorchVision 中,我们建议想要为现实世界应用提供高分辨率检测器的用户,要么将 SSD 与替代骨干网络结合(参见如何创建一个示例),要么使用 Faster R-CNN 预训练模型之一。

希望您喜欢 SSD 系列的第二部分和最后一部分。我们期待您的反馈。