近几年来,目标检测模型,尤其是单阶段目标检测模型在工业场景中已经得到广泛应用。对于检测算法来说,模型的精度以及运行效率是实际使用时最受关注的指标。因此,我们对目前的单阶段目标检测器进行了全面的改进:从增强模型的特征提取能力和对各个组件的计算量进行均衡化,到使用动态的软标签来优化训练策略,再到对数据增强的效率和性能进行改进,我们对算法的各个方面都提出了新的优化方案。通过这些改进,我们得到了从 tiny 到 extra-large 大小的一系列高性能检测模型,我们将这套实时目标检测模型(Real-Time Models for object Detection)命名为 RTMDet。其中,RTMDet-x 取得了 52.8 mAP 的精度和 300+FPS 的运行速度,同时,RTMDet-tiny 在仅有 4M 参数量的情况下达到了 41.1 mAP 的精度,超越了同级别的所有模型。RTMDet 不仅仅在目标检测这一任务上性能优异,在实时实例分割以及旋转目标检测这两个任务中也同样达到了 SOTA 的水平!除了拥有超高的精度,RTMDet 的工程优化也非常全面:基于 MMDeploy,RTMDet 全系列已经支持了 ONNXRuntime 以及 TensorRT 等推理框架的部署。同时,为了节约广大炼丹师的宝贵时间,RTMDet 的训练效率也同样进行了大幅的优化,我们在 MMYOLO 中提供了高效训练版本的代码,RTMDet-s 训练 300 epoch 仅需 14 × 8GPU 时!检测和实例分割模型代码已开源至:
https://github.com/open-mmlab/mmdetection/tree/3.x/configs/rtmdet
基于 MMYOLO 的高效训练版本:
https://github.com/open-mmlab/mmyolo/tree/dev/configs/rtmdet
基于 MMRotate 的旋转框检测模型:
https://github.com/open-mmlab/mmrotate/tree/1.x/configs/rotated_rtmdet
技术报告链接:
https://arxiv.org/abs/2212.07784
话不多说,接下来就让我们来详细了解 RTMDet 在各方面的改进吧~算法和工程优化详解
模型结构设计
拥有一个高效的模型结构是设计实时目标检测器最关键的问题之一。自 YOLOv4 将 Cross Stage Partial Network 的结构引入 DarkNet 之后,CSPDarkNet 因其简洁高效而被广泛应用于 YOLO 系列的各个改进版中。而 RTMDet 也将 CSPDarkNet 作为基线,并使用同样构建单元组成的 CSPPAFPN 进行多尺度的特征融合,最后将特征输入给不同的检测头,进行目标检测、实例分割和旋转框检测等任务。整体的模型结构如下图所示:图 1. RTMDet 模型结构图整体的宏观架构与 YOLO 系列并没有太大区别,RTMDet 对模型的修改主要聚焦于两点:增加基本构建单元的特征提取能力,以及探索模型不同组件间的计算效率和精度的平衡。首先让我们回顾一下 DarkNet 基本的构建单元,如图 2.(a) 所示,它由 1 个 1x1 的卷积和 1 个 3x3 的卷积组成,以及残差连接组成。为了提升基本单元的特征提取能力,我们选择引入更大的卷积核来增大感受野。在经过对不同 kernel size 的消融实验(表 1)后我们发现,在基本单元中加入一个 5x5 的深度可分离卷积,取得了最好的计算效率与精度的平衡。新的基础单元结构如 图 2.(b) 所示。表 1. 不同 kernel size 的精度与速度的对比实验值得注意的是,最近提出的 YOLO 的不同改进版,如 YOLOv6,v7,以及 PPYOLO-E,都选择在基本单元中加入 RepVGG 的重参数化卷积模块,如图 2.(c),图 2.(d) 所示。图 2. CSPDarknet、RTMDet 、PPYOLOE、YOLOv6 的基本构建单元重参数化通过训练时使用多分支的结构,然后再在推理时融合成单分支的方式,在不增加推理计算量的情况下提升性能。
然而,重参数化也有其弊端,比如会明显增加训练的显存开销,同时也会导致使用低精度对模型进行量化时产生较大的性能下降。尽管可以通过 QAT 等方式解决量化掉点的问题,但这也使得从模型训练到部署的流程变得更为复杂。
因此,我们认为引入大卷积核增加感受野的方式相比引入重参数化来说,不论是从训练还是部署都能够提供更好的效果。除了基本构建单元的修改之外,RTMDet 还对整个模型的不同分辨率层级之间、以及 backbone 和 neck 之间的计算量分配上进行了全面的调整。由于在基本单元中引入了深度可分离卷积,使得模型整体的层数相比于 CSPDarkNet 来说变得更深,从而导致推理速度的减慢。为了解决这一问题,我们对模型不同分辨率层级的基本单元数量进行了调整,从原本 C2~C5 分别为 3-9-9-3 个 block,调整为了 3-6-6-3 个 block图 3. Backbone 结构改进同时为了保持模型的整体计算量不变,我们略微增大了模型的宽度,并且在每个 stage 之后增加一个 ChannelAttention 模块来提供通道注意力(如图 4)。图 4. 增加通道注意力前后的 C5 stage 特征对比如表 2 所示,在经过调整之后,模型的推理速度更快,并且能够保持相似的精度。表 2. Backbone 结构对比实验而对于用来进行多尺度特征融合的 neck 模块来说,以往的方法,如 EfficientDet、GiraffeDet 等,都是通过增加更多的特征融合次数,也就是加入更多的连接来提升性能。然而,过多的特征层之间的连接会显著增加显存的占用,也会因为访存问题而增加推理耗时。因此,我们选择仅通过增加 neck 模块的计算量占比来提升其性能,当 backbone 与 neck 的参数量调整至相似时,整个检测器的推理速度更快,性能也更高:表 3. Backbone neck 参数量分配对比实验除了 backbone 和 neck 之外,我们对模型的检测头也进行了调整。YOLO 系列往往在不同的特征层级上分别使用独立的检测头,这就导致了模型参数的利用率低下。因为对于不同的特征层级来说,其检测出的物体的特征,在相对的尺度大小下应当是相近的,而学术界常用的检测器(如 RetinaNet、FCOS)使用共享参数的检测头也正印证了这一点。但是,由于不同层级之间特征的统计量仍存在差异,Normalization layer 依然是必须的,由于直接在共享参数的检测头中引入 BN 会导致其滑动平均值产生误差,而引入 GN 又会增加推理时的开销,因此我们参考 NASFPN 的做法,让检测头共享卷积层,而 BN 则分别独立计算。在使用共享的检测头后,模型的参数量得到了减少,而且性能非但没有下降,反而还得到了略微的提升:表 4. Head 结构对比通过采用以上这些策略,我们又对通道和深度的超参数进行缩放,得到了 tiny、s、m、l、x 五种不同大小的模型,其参数量分别从 4M 到 90M 递增,以提供给不同的应用场景。训练策略优化
正负样本的标签分配策略是目标检测训练过程中最重要的一环,近几年来,标签分配策略从最初的基于 anchor IoU 的静态匹配方式,逐渐演进为使用代价函数进行动态标签分配。然而,目前主流的动态标签分配策略,如匈牙利匹配、OTA 等均使用与损失函数一致的函数计算代价矩阵。我们经过实验发现,与损失函数完全一致的代价矩阵计算方式并不是最优的。因此,RTMDet 基于 YOLOX 的 SimOTA 进行改进,使用了动态的软标签分配策略,其代价矩阵计算公式如下:它由三个代价函数组成,首先是分类代价函数,传统的分类代价往往使用 0-1 分布的二值化标签进行损失计算,这很容易导致,一个拥有很高分类置信度但是拥有错误检测框的低质量预测结果得到一个很低的分类代价,反之也是如此。因此我们参考 GFL,将预测框与 Ground Truth 的 IoU 得分作为软标签,并对不同得分的匹配进行了重新加权,使得分类代价的匹配结果更为准确和稳定,其公式如下:而对于回归代价,使用与损失函数一致的 GIoU,很容易导致一个低质量的匹配和一个高质量的匹配区分度不够高,这是因为对于 GIoU 函数来说,一个完全正确的检测框和一个完全错误的检测框,他们之间的 IoU 得分也只相差了 1 而已。因此,我们选择取对数来增大低质量与高质量匹配之间的差异:最后,我们还引入了一个“软化”的中心先验代价。与之前的众多方法使用固定的先验区域(如 ATSS,SimOTA)不同,中心先验代价将位置先验也引入代价矩阵的计算之中,一方面能够稳定收敛,另一方面也能够使匹配的正样本区域更为灵活。为了公平比较,我们在标准的 ResNet-50 12 epoch 的 setting 下与其他标签分配策略进行了对比,结果显示我们的方法取得了最优的精度:表 5. R50 1x setting 下的标签分配策略性能对比为了验证这套方法的通用性,我们也在 300 epoch 和强数据增强的情况下与 YOLOX 的 SimOTA 进行了对比,结果显示,我们的方法也同样得到了更高的精度:表 6. 使用 RTMDet-s 训练 300 epoch 的标签分配策略性能对比我们使用 MMYOLO 中提供的 GradCAM++ 可视化工具(demo/boxam_vis_demo.py)可视化了 neck 部分的特征图,从下图中可以看出,与 YOLOv6 相比,使用了动态软标签分配策略的 RTMDet 的检测目标的特征响应非常集中,且没有误检:图 5. 使用 GradCAM++ 对 neck 部分特征响应的可视化(左:RTMDet-l,右:YOLOv6-l)
*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。