YOLO11 改进 – 主干网络_ RepViT重访移动端CNN的ViT视角:轻量级设计分离Token与Channel混合器,优化移动端实时检测
前言
本文介绍了将轻量级卷积神经网络RepViT与YOLOv11相结合的方法。RepViT通过引入轻量级视觉变换器的高效架构设计,提升了移动设备上的计算机视觉任务性能。其采用结构重参数化技术,核心模块RepViT Block分离Token Mixer和Channel Mixer,有效处理空间和通道信息。我们将RepViT引入YOLOv11,对相关代码进行修改和注册,并配置了yolov11 - RepViT.yaml文件。实验脚本显示,该结合方式在目标检测任务中展现出一定效果。
文章目录: YOLOv11改进大全:卷积层、轻量化、注意力机制、损失函数、Backbone、SPPF、Neck、检测头全方位优化汇总
专栏链接: YOLOv11改进专栏
文章目录
[TOC]
介绍
摘要
近期,轻量级视觉Transformer(Vision Transformers, ViTs)在资源受限的移动设备部署中展现出相较于轻量级卷积神经网络(CNNs)更优异的性能表现与更低的推理延迟。尽管已有研究揭示了轻量级ViTs与轻量级CNNs之间存在诸多结构性关联,但两者在模块结构、宏观架构设计及微观实现层面的显著差异尚未得到系统性探究。本研究从ViT架构视角重新审视轻量级CNN的高效设计范式,并着重强调其在移动计算平台上的巨大应用潜力。具体而言,通过融合轻量级ViTs的高效架构设计理念,逐步优化标准轻量级CNN(如MobileNetV3)的移动友好特性,最终构建出一个全新的轻量级CNN模型家族,命名为 RepViT 。大量实验验证表明,RepViT在多种视觉任务中均超越现有轻量级ViTs的性能表现,并展现出理想的延迟特性。特别地,在ImageNet数据集上,RepViT首次实现在iPhone 12移动设备上以1.0毫秒延迟达到超过80%的Top-1分类精度,突破了轻量级模型的性能极限。此外,将RepViT与SAM(Segment Anything Model)相结合后,RepViT-SAM的推理速度相较于先进的MobileSAM实现近10倍的显著提升。相关代码与预训练模型已在 https://github.com/THU-MIG/RepViT 开源发布。
文章链接
论文地址: 论文地址
代码地址: 代码地址
基本原理:
RepViT(Revisiting Mobile CNN From ViT Perspective)是一种新型的轻量级卷积神经网络(CNN),旨在通过引入轻量级视觉变换器(ViT)的高效架构设计,提升移动设备上的计算机视觉任务性能。RepViT的设计灵感来源于对现有轻量级CNN(如MobileNetV3)的“现代化”改造,结合了ViT的结构优势,形成了一种新的轻量级CNN家族。
RepViT的技术原理
-
架构设计 : RepViT通过将轻量级ViT的高效设计理念融入到MobileNetV3的架构中,逐步增强其移动友好性。具体来说,RepViT采用了结构重参数化技术,使得模型在训练期间能够更好地学习,同时在推理时减少计算和内存开销。
-
RepViT Block : RepViT Block是RepViT的核心构建模块,其设计包括以下几个关键要素:
-
分离的Token Mixer和Channel Mixer :RepViT Block将token混合器和通道混合器分开处理,这样可以更有效地利用空间信息和通道信息。具体来说,深度可分离卷积(DW卷积)被放置在前面,以便更好地处理空间信息,而可选的挤压与激励(SE)层则在DW卷积之后,以增强模型的表达能力。
-
结构重参数化 :通过结构重参数化技术,RepViT Block在推理时消除了与跳跃连接相关的计算和内存成本,这对于资源受限的移动设备尤为重要。
-
高效的卷积操作 :RepViT Block使用了高效的卷积操作,确保在保持较低延迟的同时,能够实现较高的准确率。
-
-
性能表现 : RepViT在多个计算机视觉任务中表现出色。例如,在ImageNet数据集上,RepViT能够在1.0毫秒的延迟下达到超过80%的Top-1准确率。此外,RepViT的最大模型RepViT-M2.3在仅2.3毫秒的延迟下获得了83.7%的准确率,显示出其在移动设备上的高效性。
-
与SAM的结合 : RepViT还与Segment Anything Model(SAM)结合,形成RepViT-SAM模型,显著提高了在移动设备上的推理速度,几乎比现有的MobileSAM快10倍,同时保持了良好的零-shot迁移能力。
核心代码
class RepViT(nn.Module):
def __init__(self, cfgs):
super(RepViT, self).__init__()
# setting of inverted residual blocks
self.cfgs = cfgs
# building first layer
input_channel = self.cfgs[0][2]
patch_embed = torch.nn.Sequential(Conv2d_BN(3, input_channel // 2, 3, 2, 1), torch.nn.GELU(),
Conv2d_BN(input_channel // 2, input_channel, 3, 2, 1))
layers = [patch_embed]
# building inverted residual blocks
block = RepViTBlock
for k, t, c, use_se, use_hs, s in self.cfgs:
output_channel = _make_divisible(c, 8)
exp_size = _make_divisible(input_channel * t, 8)
layers.append(block(input_channel, exp_size, output_channel, k, s, use_se, use_hs))
input_channel = output_channel
self.features = nn.ModuleList(layers)
self.channel = [i.size(1) for i in self.forward(torch.randn(1, 3, 640, 640))]
def forward(self, x):
input_size = x.size(2)
scale = [4, 8, 16, 32]
features = [None, None, None, None]
for f in self.features:
x = f(x)
if input_size // x.size(2) in scale:
features[scale.index(input_size // x.size(2))] = x
return features
def switch_to_deploy(self):
replace_batchnorm(self)
实验
脚本
import warnings
warnings.filterwarnings('ignore')
from ultralytics import YOLO
if __name__ == '__main__':
# 修改为自己的配置文件地址
model = YOLO('/root/ultralytics-main/ultralytics/cfg/models/11/yolov11-RepViT.yaml')
# 修改为自己的数据集地址
model.train(data='/root/ultralytics-main/ultralytics/cfg/datasets/coco8.yaml',
cache=False,
imgsz=640,
epochs=10,
single_cls=False, # 是否是单类别检测
batch=8,
close_mosaic=10,
workers=0,
optimizer='SGD',
# amp=True,
project='runs/train',
name='RepViT',
)