在 TorchVision v0.9 版本中,我们发布了一系列适用于分类、目标检测和语义分割的移动友好型模型。在本文中,我们将深入探讨这些模型的代码,分享一些值得注意的实现细节,解释我们如何配置和训练它们,并突出我们在调整过程中做出的重要权衡。我们的目标是公开那些通常在模型的原始论文和代码库中未记录的技术细节。
网络架构
MobileNetV3 架构的实现紧密遵循原始论文。它是可定制的,为构建分类、目标检测和语义分割骨干网络提供了不同的配置。它被设计成与 MobileNetV2 具有相似的结构,两者共享共同的构建模块。
现成产品中,我们提供论文中描述的两个变体:大号和小号。它们都使用相同的代码构建,唯一的区别在于它们的配置,这描述了块的数量、大小、激活函数等。
配置参数
虽然可以编写自定义的 InvertedResidual 设置并将其直接传递给 MobileNetV3 类,但对于大多数应用,我们可以通过传递参数到模型构建方法来适配现有的配置。一些关键配置参数如下:
-
width_mult
参数是一个乘数,它影响模型的通道数。默认值为 1,通过增加或减少它,可以改变所有卷积的滤波器数量,包括第一层和最后一层的滤波器。该实现确保滤波器的数量总是 8 的倍数。这是一个硬件优化技巧,可以使操作更快地矢量化。 -
The
reduced_tail
parameter halves the number of channels on the last blocks of the network. This version is used by some Object Detection and Semantic Segmentation models. It’s a speed optimization which is described on the MobileNetV3 paper and reportedly leads to a 15% latency reduction without a significant negative effect on accuracy. -
The
dilated
parameter affects the last 3 InvertedResidual blocks of the model and turns their normal depthwise Convolutions to Atrous Convolutions. This is used to control the output stride of these blocks and has a significant positive effect on the accuracy of Semantic Segmentation models.
Implementation details
Below we provide additional information on some notable implementation details of the architecture. The MobileNetV3 class is responsible for building a network out of the provided configuration. Here are some implementation details of the class:
-
最后的卷积块将最后一个 InvertedResidual 块的输出扩展了 6 倍。该实现与论文中描述的大型和小型配置保持一致,并可以适应不同的乘数参数值。
-
与 MobileNetV2 等其他模型类似,在分类器的最终线性层之前放置了一个 dropout 层。
InvertedResidual 类是网络的主要构建块。以下是该块的几个显著实现细节及其可视化,这些内容来自论文的第 4 图:
-
如果输入通道和扩展通道相同,则没有扩展步骤。这种情况发生在网络的第一个卷积块中。
-
即使扩展通道与输出通道相同,也始终存在一个投影步骤。
-
深度可分离块(depthwise block)的激活方法被放置在 Squeeze-and-Excite 层之前,这样做可以略微提高准确率。

分类
在本节中,我们提供了预训练模型的基准测试以及它们配置、训练和量化细节。
基准测试
这里是如何初始化预训练模型的:
large = torchvision.models.mobilenet_v3_large(pretrained=True, width_mult=1.0, reduced_tail=False, dilated=False)
small = torchvision.models.mobilenet_v3_small(pretrained=True)
quantized = torchvision.models.quantization.mobilenet_v3_large(pretrained=True)
下面是新旧模型之间的详细基准测试。正如我们所见,MobileNetV3-Large 对于愿意牺牲一点准确度以换取大约 6 倍速度提升的用户来说是一个可行的 ResNet50 替代品:
Model | Acc@1 | Acc@5 | CPU 上推理(秒) | # 参数(M) |
---|---|---|---|---|
MobileNetV3-Large | 74.042 | 91.340 | 0.0411 | 5.48 |
MobileNetV3-Small | 67.668 | 87.402 | 0.0165 | 2.54 |
量化 MobileNetV3-Large | 73.004 | 90.858 | 0.0162 | 2.96 |
MobileNetV2 | 71.880 | 90.290 | 0.0608 | 3.50 |
ResNet50 | 76.150 | 92.870 | 0.2545 | 25.56 |
ResNet18 | 69.760 | 89.080 | 0.1032 | 11.69 |
注意,这里的推理时间是在 CPU 上测量的。它们不是绝对基准,但允许在模型之间进行相对比较。
训练过程
所有预训练模型均配置为宽度乘数为 1,具有完整尾部,非膨胀,并在 ImageNet 上进行了拟合。大模型和小模型均使用相同的超参数和脚本进行训练,这些脚本可以在我们的参考文献文件夹中找到。以下我们将提供关于训练过程中最显著方面的详细信息。
实现快速且稳定的训练
正确配置 RMSProp 对于实现快速且数值稳定的训练至关重要。论文的作者在其实验中使用了 TensorFlow,并在他们的运行中报告了使用相当高的 rmsprop_epsilon
与默认值相比。通常这个超参数取较小的值,因为它用于避免零除数,但在这个特定模型中,选择正确的值似乎很重要,以避免损失中的数值不稳定性。
另一个重要的细节是,尽管 PyTorch 和 TensorFlow 的 RMSProp 实现通常表现相似,但在我们的设置中存在一些差异,其中最值得注意的是对 epsilon 超参数的处理方式。更具体地说,PyTorch 在平方根计算之外添加 epsilon,而 TensorFlow 在其中添加。这种实现细节的结果是,在移植论文中的超参数时,需要调整 epsilon 的值。可以使用公式 PyTorch_eps = sqrt(TF_eps)
进行合理的近似。
通过调整超参数和改进训练方案来提高我们的准确度
在将优化器配置为快速稳定训练后,我们转向优化模型的准确性。我们采用了一些技术来实现这一点。首先,为了避免过拟合,我们使用 AutoAugment 算法增强我们的数据,随后是 RandomErasing。此外,我们还调整了参数,如使用交叉验证的权重衰减。我们还发现,在训练结束后进行不同 epoch 检查点的权重平均也是有益的。最后,尽管我们没有在我们的发布训练方案中使用,但我们发现使用标签平滑、随机深度和 LR 噪声注入可以将整体准确性提高超过 1.5 个百分点。
图表和表格展示了提高 MobileNetV3 Large 变体准确性的最重要的迭代过程的简化总结。请注意,在训练模型时实际进行的迭代次数要大得多,并且准确性的进步并不总是单调递增的。另外,请注意,图表的 Y 轴从 70%开始而不是从 0%,以便使迭代之间的差异更明显:

迭代 | Acc@1 | Acc@5 |
---|---|---|
基线配置采用“MobileNetV2-style”超参数 | 71.542 | 90.068 |
+ 使用默认 eps 的 RMSProp | 70.684 | 89.38 |
+ 调整 eps 和 LR 方案的 RMSProp | 71.764 | 90.178 |
+ 数据增强与调整超参数 | 73.86 | 91.292 |
+ 检查点平均 | 74.028 | 91.382 |
+ 标签平滑 & 随机深度 & LR 噪声 | 75.536 | 92.368 |
注意,一旦我们达到了可接受的准确率,我们就验证了模型在之前未用于训练或超参数调整的保留测试数据集上的性能。这个过程有助于我们检测过拟合,并且在所有预训练模型发布之前都会执行。
量化
我们目前为 MobileNetV3-Large 变体的 QNNPACK 后端提供量化权重,这提供了 2.5 倍的加速。为了量化模型,使用了量化感知训练(QAT)。训练模型所使用的超参数和脚本可以在我们的参考资料文件夹中找到。
注意,QAT 允许我们模拟量化的影响并调整权重,从而提高模型精度。这相当于与简单的后训练量化相比,精度提高了 1.8 个百分点:
量化状态 | Acc@1 | Acc@5 |
---|---|---|
非量化 | 74.042 | 91.340 |
量化感知训练 | 73.004 | 90.858 |
训练后量化 | 71.160 | 89.834 |
目标检测
在本节中,我们首先将提供已发布模型的基准测试,然后讨论如何使用 MobileNetV3-Large 骨干网络结合 FasterRCNN 检测器在特征金字塔网络中进行目标检测。我们还将解释如何训练和调整该网络,以及我们不得不做出的任何权衡。我们不会详细介绍如何与 SSDlite 一起使用,因为这将在未来的文章中讨论。
基准测试
下面是如何初始化模型的:
high_res = torchvision.models.detection.fasterrcnn_mobilenet_v3_large_fpn(pretrained=True)
low_res = torchvision.models.detection.fasterrcnn_mobilenet_v3_large_320_fpn(pretrained=True)
下面是一些新旧模型之间的基准测试。正如我们所见,使用 MobileNetV3-Large FPN 骨干网络的高分辨率 Faster R-CNN 似乎对于那些愿意牺牲一些准确度以换取 5 倍速度提升的用户来说是一个可行的替代方案:
Model | 平均精度(mAP) | CPU 上推理(秒) | # 参数(M) |
---|---|---|---|
Faster R-CNN MobileNetV3-Large FPN(高分辨率) | 32.8 | 0.8409 | 19.39 |
Faster R-CNN MobileNetV3-Large 320 FPN(低分辨率) | 22.8 | 0.1679 | 19.39 |
Faster R-CNN ResNet-50 FPN | 37.0 | 4.1514 | 41.76 |
RetinaNet ResNet-50 FPN | 36.4 | 4.8825 | 34.01 |
实现细节
该检测器使用 FPN 风格的骨干网络,从 MobileNetV3 模型的不同卷积中提取特征。默认情况下,预训练模型使用第 13 个 InvertedResidual 块的输出以及池化层之前的卷积层的输出,但实现支持使用更多阶段的输出。
网络中提取的所有特征图都通过 FPN 块投影到 256 个通道,这大大提高了网络的运行速度。这些由 FPN 骨干提供的特征图被 FasterRCNN 检测器用于在不同尺度上提供框和类别预测。
训练与调优过程
我们目前提供两种预训练模型,能够在不同分辨率下进行目标检测。这两个模型都是在 COCO 数据集上使用相同的超参数和脚本进行训练的,这些脚本可以在我们的参考资料文件夹中找到。
高分辨率检测器使用 800-1333px 的图像进行训练,而适合移动端的低分辨率检测器使用 320-640px 的图像进行训练。我们提供两组独立的预训练权重的原因是因为直接在较小的图像上训练检测器,与将小图像传递给预训练的高分辨率模型相比,可以提高 5 mAP 的精度。两个骨干网络都初始化为在 ImageNet 上拟合的权重,并在训练过程中对其最后 3 个阶段的权重进行了微调。
可以通过调整 RPN NMS 阈值对移动友好型模型进行额外的速度优化。我们仅牺牲了 0.2 mAP 的精度,就能将模型的 CPU 速度提高约 45%。优化的详细信息如下:
调优状态 | 平均精度(mAP) | CPU 推理时间(秒) |
---|---|---|
之前 | 23.0 | 0.2904 |
之后 | 22.8 | 0.1679 |
以下我们提供了一些可视化 Faster R-CNN MobileNetV3-Large FPN 模型预测结果的示例:

语义分割
在本节中,我们将首先提供一些已发布预训练模型的基准测试。然后,我们将讨论如何将 MobileNetV3-Large 骨干网络与分割头如 LR-ASPP、DeepLabV3 和 FCN 结合进行语义分割。我们还将解释网络的训练过程,并提出一些针对速度关键应用的优化技术。
基准测试
这是如何初始化预训练模型的:
lraspp = torchvision.models.segmentation.lraspp_mobilenet_v3_large(pretrained=True)
deeplabv3 = torchvision.models.segmentation.deeplabv3_mobilenet_v3_large(pretrained=True)
下面是新旧模型之间的详细基准测试。正如我们所见,使用 MobileNetV3-Large 作为背骨的 DeepLabV3 在大多数应用中是 FCN 和 ResNet50 的可行替代品,因为它以 8.5 倍的速度实现了相似的精度。我们还观察到 LR-ASPP 网络在所有指标上都优于等效的 FCN:
Model | mIoU | 全局像素准确率 | CPU 上推理(秒) | # 参数(M) |
---|---|---|---|---|
LR-ASPP MobileNetV3-Large | 57.9 | 91.2 | 0.3278 | 3.22 |
DeepLabV3 MobileNetV3-Large | 60.3 | 91.2 | 0.5869 | 11.03 |
FCN MobileNetV3-Large(尚未发布) | 57.8 | 90.9 | 0.3702 | 5.05 |
DeepLabV3 ResNet50 | 66.4 | 92.4 | 6.3531 | 39.64 |
FCN ResNet50 | 60.5 | 91.4 | 5.0146 | 32.96 |
实现细节
在本节中,我们将讨论测试分割头的重要实现细节。请注意,本节中描述的所有模型都使用 dilated MobileNetV3-Large 作为骨干网络。
LR-ASPP
LR-ASPP 是 MobileNetV3 论文作者提出的 Reduced Atrous Spatial Pyramid Pooling 模型的轻量级变体。与 TorchVision 中的其他分割模型不同,它不使用辅助损失。相反,它使用低级和高级特征,分别具有 8 和 16 的输出步长。
与使用可变步长的 49x49 平均池化层的论文不同,我们的实现使用 AdaptiveAvgPool2d
层来处理全局特征。这是因为论文的作者将头部定制为 Cityscapes 数据集,而我们的重点是提供一个通用的实现,该实现可以在多个数据集上工作。最后,我们的实现总是在返回输出之前进行双线性插值,以确保输入和输出图像的大小完全匹配。
DeepLabV3 & FCN
MobileNetV3 与 DeepLabV3 和 FCN 的组合在与其他模型的组合和阶段估计方面非常接近,这些方法的阶段估计与 LR-ASPP 相同。唯一的显著区别是,我们不是使用高、低层次特征,而是将正常损失附加到输出步长为 16 的特征图上,并在输出步长为 8 的特征图上附加辅助损失。
最后,我们应该指出,该模型的 FCN 版本并未发布,因为它在速度和准确性方面完全被 LR-ASPP 所取代。预训练的权重仍然可用,并且可以通过对代码进行最小修改来使用。
训练与调整过程
我们目前提供两种 MobileNetV3 预训练模型,可以进行语义分割:LR-ASPP 和 DeepLabV3。这些模型的骨干网络使用 ImageNet 权重初始化,并进行了端到端训练。这两个架构都使用相同的脚本和类似的超参数在 COCO 数据集上进行了训练。它们的详细信息可以在我们的参考文献文件夹中找到。
通常,在推理过程中,图像会被调整到 520 像素。一种可选的加速优化是使用高分辨率预训练权重构建模型的低分辨率配置,并将推理调整大小减少到 320 像素。这将使 CPU 执行时间提高约 60%,但会牺牲一些 mIoU 点。这种优化的详细数字可以在下表找到:
低分辨率配置 | mIoU 差异 | 速度提升 | mIoU | 全局像素准确率 | CPU 推理(秒) |
---|---|---|---|---|---|
LR-ASPP MobileNetV3-Large | -2.1 | 65.26% | 55.8 | 90.3 | 0.1139 |
DeepLabV3 MobileNetV3-Large | -3.8 | 63.86% | 56.5 | 90.3 | 0.2121 |
FCN MobileNetV3-Large(尚未发布) | -3.0 | 57.57% | 54.8 | 90.1 | 0.1571 |
以下是一些可视化 LR-ASPP MobileNetV3-Large 模型预测结果的示例:

我们希望您觉得这篇文章很有趣。我们期待您的反馈,看看这是否是您希望我们更频繁发布的内容类型。如果社区认为这类帖子很有用,我们将很高兴发布更多关于新引入的机器学习模型实现细节的文章。