Slim-neck by GSConv:自动驾驶车辆检测器架构的更好设计范式(文末附代码)

news2024/11/13 16:07:29

Slim-neck by GSConv:自动驾驶车辆检测器架构的更好设计范式

  • 摘要
  • 引言
  • 相关工作
  • 本文方法
        • GSConv的优势在于轻量级检测器,这些检测器通过添加DSC层和Shuffle来增加非线形表达能力。但是,如果GSConv在模型的所有阶段都使用,模型的网络层会变得更深,这些深层将加重数据流的阻力并显著增加推理时间,当这些特征图到达瓶颈阶段时,他们已经足够细(通道维度达到最大值,宽度和高度维度达到最小值),转换已经变得适度。因此,在瓶颈阶段 仅使用GSConv是更好的选择,使用CSConv处理连接的特征图是合适的:冗余的重复信息较少并且不需要压缩,同时注意力模块的效果更好(SPP或CA)
  • Slim-Neck
  • 代码

摘要

目标检测是计算机视觉中一项重要的下游任务。对于车载边缘计算平台来说,巨型模型难以实现实时检测要求,而且,由大量深度可分离卷积层构建的轻量级模型无法实现足够的准确率。引入了一种新的轻量级卷积技术 ——GSConv,以减轻模型负担同时保持准确性。GSConv在模型准确性速度之间达到了出色的权衡。而且,还提供了一种设计范式:Slim-neck,以实现检测器的更高计算成本效益。方法在二十多组对比实验中得到了稳健的验证。特别是,通过我们的方法改进的检测器相比于原始模型得到了最新进的结果。

引言

目标检测是自动驾驶汽车所需的基本感知能力。目前,深度学习的检测算法在该领域占据主导地位。根据检测器阶段的不同,这些算法可以分为一阶段检测器和两阶段检测器。两阶段检测器在检测小目标和获取更高的平均精度方面表现更好,这事通过稀疏检测的原理实现的,但这些检测器的性能需要以速度为代价。一阶段检测器在检测定位小目标方面,不如两阶段检测器有效,但在工作速度上比两阶段快,这对于工业应用非常重要。但是,随着Transformer在计算机视觉领域的应用,这种情况正在发生变化。从类脑研究的直观理解来看,神经元越多的模型具有更强的非线性表达能力。但不容忽视的是,生物大脑在处理信息方面具有强大的能力和低能耗,这远远超越了计算机。不能简单的通过增加模型参数的数量来构建强大的模型,在当前阶段,采用轻量级设计有效地减轻了高计算成本的负担。这一目的主要通过使用深度可分离卷积操作来实现(DSC)减少参数和浮点运算(FLOPs,乘加法的数量)来实现,其效果显著。然而,
DSC的缺点也很明显:在计算过程中,输入图像的通道信息被分离,下图 a,b展示了标准卷积核DSC的计算过程,这个缺陷导致DSC的特征提取和融合能力远低于SC。
在这里插入图片描述
对于自动驾驶汽车来说,速度和准确性同样重要,以前的轻量级工作,如xception、MobileNets和ShuffleNets,通过DSC操作大大提高了检测器的速度,但是,当这些模型应用于自动驾驶汽车时,他们的精度较低时令人担忧的。实际上,这些工作提出了一些方法来缓解DSC固有缺陷(也使其特殊性):

  • MobileNets使用大量的1X1密集卷积来融合通道信息,这些信息时独立计算的;
  • ShuffleNets使用“通道混洗”来实现通道信息的相互作用;
  • GhostNet使用了减半SC操作来保留通道之间的交互信息。
    但是:1X1密集卷积需要更多的计算资源,使用“通道混洗”的效果仍然无法与SC相提并论,而GhostNet或多或少又回到了SC的轨道上,影响可能来自各个方面。许多轻量级模型使用类似的思路来设计基本架构:只在深度神经网络的起点到终点使用DSC。然而,无论是用于图像分类还是目标检测,DSC的缺陷在骨干网络中直接放大。我们认为SC和DSC可以配合使用。我们注意到:仅通过对DSC的输出通道进行混洗来生成的特征图仍然是“深度分离的”
    为了使DSC的输出尽可能接近SC,引入了一种新的方法-使用SC、DSC和混洗的组合卷积,命名为GSConv。如下图所示:
    在这里插入图片描述
    我们使用混洗将SC(通道密集卷积操作)生成的信息渗透到DSC生成的每一部分信息中。混洗是一种统一的混合策略。该方法允许来自SC的信息通过统一的方式在不同通道上交换局部特征信息,完全混合到DSC的输出中,而不需要额外的修饰。下图显示了SC、DSC和GSConv的可视化结果。
    在这里插入图片描述
    GSConv的特征图与SC的相似性明显高于DSC与SC的相似性。
    在轻量级模型上,仅通过使用GSConv层替换SC层,我们实现了显著的精度提升,在其他模型上,当我们的骨干网络中使用SC,并在neck(slim-neck)中使用GSConv时,模型的精度与原始模型非常接近;如果我们加入一些技巧,模型的精度和速度将超过原始模型。
    GSConv结合Slim-Neck方法减小了DSC缺陷对模型的负面影响,并有效利用了DSC的优点。
    我们的主要贡献可总结如下:
  • 我们引入了一种新的轻量级卷积方法GSConv,该方法使卷积计算的输出尽量接近SC的输出,并降低了计算成本
  • 我们提出了一种设计范式,即使用Slim- Neck来进行自动驾驶汽车的检测器架构
  • 我们验证了在GSConv-Slim-Neck检测器上使用不同常用技巧的有效性

相关工作

通常,基于卷积神经网络的检测器由三部分组成:骨干网络、颈部和头部,骨干网络用于提取输入的特征,颈部将这些特征优化和合并后传递给头部,头部通过颈部的特征进行对对象检测。
对于骨干网络:AlexNet展示了CNN的强大特征提取能力。之后,检测器或分类器的骨干网络开始使用SC进行设计,例如VGG、ResNet和DarkNet。然而,这些**“笨重”**的模型对于边缘计算设备来说是非常不友好的。在模型结构设计方面,研究人员为边缘设备提出了经典的轻量级模型,如MobileNet、ShuffleNet和GhostNet。
在颈部方面:FPN通过独立地对不同尺度的特征图层执行预测操作,提高了对象检测模型的速度和准确率
对于头部:主要的区别在于模型使用基于锚点或者无锚点的方法来完成对象定位任务,前者可能对设计师和用户更可控,但必须使用NMS过滤出具有更高IoU阈值得分的预测框,后者更加灵活,无需手动控制更多参数,但这也导致了模型的不稳定性增加。锚点法或无锚点法的选择并不是本文的重点,但值得注意的是,目前SOTA模型仍然使用锚点法。
此外,注意力机制,如SPP、SE、CBAM、CA可以提高检测器的效率和性能,特别是对于轻量级的检测器,通过适当使用这些模块,可以获得更好的性价比。

本文方法

目标:构建一个简单高效的检测器连接部分,因此要考虑许多因素,包括卷积方法、特征融合结构、计算效率和计算代价效益以及其他许多因素。
为了加快CNN中预测计算的速度,图像经常需要在骨干网络中经历类似的转换过程:空间信息逐步传递到通道中,**每次对特征图进行空间压缩和通道扩展都会导致语义信息的损失。**通道稠密卷积计算最大程度的保留了每个通道之间的隐藏连接,但通道稀疏卷积完全断开了这些连接。GSConv则通过更低的时间复杂度尽可能的保留了这些连接。通常卷积计算的时间复杂度由FLOPs定义。因此,SC(通道稠密卷积)、DSC(通道稀疏卷积)和GSConv的时间复杂度:
在这里插入图片描述
下表,比较了五种不同的卷积块对模型性能的贡献:
在这里插入图片描述
在GSConv中,我们希望以尽可能简单的方式完成shuffle操作,并且不增加额外的FLOPs消耗。其中一种选择是通过转制操作平均混合特征,然后将他们重构到原始大小,以这种方式不增加额外的FLOPs消耗,但严格来说,在某些设备上不支持。
另一种选择是使用线性操作进行shuffle任务,这种方式计算成本较低,并且所有支持卷积计算的设备都可以支持。下表报告了对这两种shuffle方法性能的消融研究结果。
在这里插入图片描述

GSConv的优势在于轻量级检测器,这些检测器通过添加DSC层和Shuffle来增加非线形表达能力。但是,如果GSConv在模型的所有阶段都使用,模型的网络层会变得更深,这些深层将加重数据流的阻力并显著增加推理时间,当这些特征图到达瓶颈阶段时,他们已经足够细(通道维度达到最大值,宽度和高度维度达到最小值),转换已经变得适度。因此,在瓶颈阶段 仅使用GSConv是更好的选择,使用CSConv处理连接的特征图是合适的:冗余的重复信息较少并且不需要压缩,同时注意力模块的效果更好(SPP或CA)

Slim-Neck

我们研究了增强卷积神经网络学习能力的广义方法,如DenseNet、VoVNet和CSPNet,并根据这些方法的理论设计了Slim-neck的结构。我们设计Slim-neck来降低检测器的计算复杂度和推理时间,同时保持准确性。GSConv完成了降低计算复杂度的任务,而降低推理时间和保持准确性的任务需要新的模型

GSConv的计算成本约为SC的50%,但其对模型的学习能力的贡献与后者相当。在GSConv的基础上,我们进一步引入了GS瓶颈,下图展示了GS瓶颈模块的结构。
在这里插入图片描述
上图b、c、d分别展示了VoV GSCSP的三种设计方案。其中b简单直观、推理速度更快,而c、d对特征的重用率特别高,事实上,由于邮件友好性,更简单的结构模块更容易被使用。下表报告了三种结构的消融结果实验,b显示出更高的性价比,最后,我们需要有灵性的使用这四个模块。
在这里插入图片描述

代码

from conv import autopad

# ---------------------------GSConv Begin---------------------------
class Conv_Mish(nn.Module):
    # Standard convolution
    def __init__(self, c1, c2, k=1, s=1, p=None, g=1, act=True):  # ch_in, ch_out, kernel, stride, padding, groups
        super().__init__()
        self.conv = nn.Conv2d(c1, c2, k, s, autopad(k, p), groups=g, bias=False)
        self.bn = nn.BatchNorm2d(c2)
        self.act = nn.Mish() if act else nn.Identity()

    def forward(self, x):
        return self.act(self.bn(self.conv(x)))

    def forward_fuse(self, x):
        return self.act(self.conv(x))


class GSConv(nn.Module):
    # GSConv https://github.com/AlanLi1997/slim-neck-by-gsconv
    def __init__(self, c1, c2, k=1, s=1, g=1, act=True):
        super().__init__()
        c_ = c2 // 2
        self.cv1 = Conv_Mish(c1, c_, k, s, None, g, act)
        self.cv2 = Conv_Mish(c_, c_, 5, 1, None, c_, act)

    def forward(self, x):
        x1 = self.cv1(x)
        x2 = torch.cat((x1, self.cv2(x1)), 1)
        # shuffle
        # y = x2.reshape(x2.shape[0], 2, x2.shape[1] // 2, x2.shape[2], x2.shape[3])
        # y = y.permute(0, 2, 1, 3, 4)
        # return y.reshape(y.shape[0], -1, y.shape[3], y.shape[4])

        b, n, h, w = x2.data.size()
        b_n = b * n // 2
        y = x2.reshape(b_n, 2, h * w)
        y = y.permute(1, 0, 2)
        y = y.reshape(2, -1, n // 2, h, w)

        return torch.cat((y[0], y[1]), 1)


class GSConvns(GSConv):
    # GSConv with a normative-shuffle https://github.com/AlanLi1997/slim-neck-by-gsconv
    def __init__(self, c1, c2, k=1, s=1, g=1, act=True):
        super().__init__(c1, c2, k=1, s=1, g=1, act=True)
        c_ = c2 // 2
        self.shuf = nn.Conv2d(c_ * 2, c2, 1, 1, 0, bias=False)

    def forward(self, x):
        x1 = self.cv1(x)
        x2 = torch.cat((x1, self.cv2(x1)), 1)
        # normative-shuffle, TRT supported
        return nn.ReLU(self.shuf(x2))


class GSBottleneck(nn.Module):
    # GS Bottleneck https://github.com/AlanLi1997/slim-neck-by-gsconv
    def __init__(self, c1, c2, k=3, s=1, e=0.5):
        super().__init__()
        c_ = int(c2 * e)
        # for lighting
        self.conv_lighting = nn.Sequential(
            GSConv(c1, c_, 1, 1),
            GSConv(c_, c2, 3, 1, act=False))
        self.shortcut = Conv_Mish(c1, c2, 1, 1, act=False)

    def forward(self, x):
        return self.conv_lighting(x) + self.shortcut(x)


class VoVGSCSP(nn.Module):
    # VoVGSCSP module with GSBottleneck
    def __init__(self, c1, c2, n=1, shortcut=True, g=1, e=0.5):
        super().__init__()
        c_ = int(c2 * e)  # hidden channels
        self.cv1 = Conv_Mish(c1, c_, 1, 1)
        self.cv2 = Conv_Mish(c1, c_, 1, 1)
        # self.gc1 = GSConv(c_, c_, 1, 1)
        # self.gc2 = GSConv(c_, c_, 1, 1)
        # self.gsb = GSBottleneck(c_, c_, 1, 1)
        self.gsb = nn.Sequential(*(GSBottleneck(c_, c_, e=1.0) for _ in range(n)))
        self.res = Conv_Mish(c_, c_, 3, 1, act=False)
        self.cv3 = Conv_Mish(2 * c_, c2, 1)  #

    def forward(self, x):
        x1 = self.gsb(self.cv1(x))
        y = self.cv2(x)
        return self.cv3(torch.cat((y, x1), dim=1))


class GSBottleneckC(GSBottleneck):
    # cheap GS Bottleneck https://github.com/AlanLi1997/slim-neck-by-gsconv
    def __init__(self, c1, c2, k=3, s=1):
        super().__init__(c1, c2, k, s)
        self.shortcut = DWConv(c1, c2, k, s, act=False)


class VoVGSCSPC(VoVGSCSP):
    # cheap VoVGSCSP module with GSBottleneck
    def __init__(self, c1, c2, n=1, shortcut=True, g=1, e=0.5):
        super().__init__(c1, c2)
        c_ = int(c2 * 0.5)  # hidden channels
        self.gsb = GSBottleneckC(c_, c_, 1, 1)
# ---------------------------GSConv End---------------------------

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1013784.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Django系列:Django开发环境配置与第一个Django项目

Django系列 Django开发环境配置与第一个Django项目 作者:李俊才 (jcLee95):https://blog.csdn.net/qq_28550263 邮箱 :291148484163.com 本文地址:https://blog.csdn.net/qq_28550263/article/details/1328…

三维模型3DTile格式轻量化压缩处理的数据质量提升方法分析

三维模型3DTile格式轻量化压缩处理的数据质量提升方法分析 在处理三维模型3DTile格式的轻量化压缩时,如何在减少数据量的同时,保证或提升数据质量是一大挑战。以下为一些提升数据质量的方法分析: 改进几何简化算法:在进行几何简化…

精品SpringCloud的B2C模式在线学习网微服务分布式

《[含文档PPT源码等]精品基于SpringCloud实现的B2C模式在线学习网站-微服务-分布式》该项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程等 软件开发环境及开发工具: 开发语言:Java 框架:springcloud JDK版本&#xf…

基于matlab中点放炮各类地震波时距曲线程序

完整程序&#xff1a; clear all dx50;x-500:dx:500;%炮检距 h100;V11500; theta25*pi/180; V2V1/sin(theta); t1sqrt(x.*x4*h*h)/V1;%反射波时距曲线 t2abs(x)./V1;%直达波时距曲线 %折射波时距曲线 xm2*h*tan(theta);%求盲区 k1; for i1:length(x) if x(i)<-xm …

Python提取JSON数据中的键值对并保存为.csv文件

本文介绍基于Python&#xff0c;读取JSON文件数据&#xff0c;并将JSON文件中指定的键值对数据转换为.csv格式文件的方法。 在之前的文章Python提取JSON文件中的指定数据并保存在CSV或Excel表格文件内&#xff08;https://blog.csdn.net/zhebushibiaoshifu/article/details/132…

Mac电脑安装Zulu Open JDK 8 使用 spring-kafka 消费不到Kafka Partition中的消息

一、现象描述 使用Mac电脑本地启动spring-kakfa消费不到Kafka的消息&#xff0c;监控消费组的消息偏移量发现存在Lag的消息&#xff0c;但是本地客户端就是拉取不到&#xff0c;通过部署到公司k8s容器上消息却能正常消费&#xff01; 本地启动的服务消费组监控 公司k8s容器服…

安防监控视频系统EasyCVR+AI算法智能分析网关助力智慧校园建设

学生是祖国的未来&#xff0c;学校就是培育学生的地方。随着校园信息化建设的不断发展&#xff0c;信息服务在校园管理中的作用也越来越强。在保障学生安全与校园高效管理上&#xff0c;人工智能做出了极大贡献&#xff0c;旭帆科技安防监控系统/视频汇聚/云存储/AI智能视频分析…

java面试题基础第七天

一、java面试题第七天 1.throw和throws的区别&#xff1f; throw&#xff1a; 用于抛出一个异常对象throws&#xff1a;写在方法体上面&#xff0c;将方法体里面的异常&#xff0c;抛给上层 2. 通过故事讲清楚NIO 下面通过一个例子来讲解下。 假设某银行只有10个职员。该银…

【多光谱与高光谱图像融合:金字塔混洗Transformer】

PSRT: Pyramid Shuffle-and-Reshuffle Transformer for Multispectral and Hyperspectral Image Fusion &#xff08;PSRT&#xff1a;用于多光谱与高光谱图像融合的金字塔混洗Transformer&#xff09; Transformer在计算机视觉中受到了很多关注。由于Transformer具有全局自关…

使用Docker构建轻量级Linux容器

Docker是一个开源的容器化平台&#xff0c;可以帮助用户快速创建、部署和管理应用程序的轻量级Linux容器。通过Docker&#xff0c;用户可以将应用程序及其所有依赖项打包成一个独立的容器镜像&#xff0c;并在各种环境中运行&#xff0c;无需担心环境差异和依赖冲突。下面将详细…

【多线程】CAS 详解

CAS 详解 一. 什么是 CAS二. CAS 的应用1. 实现原子类2. 实现自旋锁 三. CAS 的 ABA 问题四. 相关面试题 一. 什么是 CAS CAS: 全称Compare and swap&#xff0c;字面意思:”比较并交换“一个 CAS 涉及到以下操作&#xff1a; 我们假设内存中的原数据 V&#xff0c;旧的预期值…

c++ vs2019 cpp20规范 模板function 源码解析

以下是文字结论&#xff1a; 这个函数模板&#xff0c;可以把函数类型&#xff0c;和对象函数类型&#xff08;就是类里定义了operator()运算符函数&#xff09;统一成一个类型&#xff0c;反正都是可调用对象。 代码注释完有900行&#xff0c;也挺多的。选择最重要的结论贴出…

腾讯mini项目-【指标监控服务重构】2023-08-21

今日已办 PPT 汇报 答辩的时间需要把控人员的分配不够合理效果展示不够清晰&#xff0c;不够熟练重点的调研测试对比报告还未产出 项目待办 50字总结项目意义&#xff0c;top3 难点watermill 和 profile 正则处理otel-sdk 隐式&#xff0c;可扩展接入云 clickhouse 集群&am…

[maven] scopes 管理 profile 测试覆盖率

[maven] scopes & 管理 & profile & 测试覆盖率 这里将一些其他的特性和测试覆盖率&#xff08;主要是 jacoco&#xff09; scopes maven 的 scope 主要就是用来限制和管理依赖的传递性&#xff0c;简单的说就是&#xff0c;每一个 scope 都有其对应的特性&…

大语言模型如何生成内容

大语言模型生成内容主要基于语言模型算法。语言模型是一种机器学习算法&#xff0c;它可以根据给定文本来预测下一个词语或字符的出现的概率。语言模型通过大量的文本数据来学习语言的统计特征&#xff0c;进而生成具有相似统计特征的新文本。其核心目标是建立一个统计模型&…

zemax像散与消像散

打开zemax自带的例子 点列图可以观察到像散 我们旋转3D视图 这个角度似乎聚焦在像平面上&#xff0c;我们旋转90度 可以看到这一方向上其实已经聚焦 像散就是光斑在像面上子午方向和弧矢方向的不一致性 从光纤光扇图中可以具体的看出&#xff0c;两者不一致&#xff1a; 消除…

安卓毕业设计各种app项目,Android毕设设计,Android课程设计,毕业论文

作为一位从事软件开发多年的专业人士&#xff0c;您积累了丰富的经验和技能&#xff0c;解决了许多不同类型的问题。除了开发原创项目&#xff0c;您还愿意分享您的知识&#xff0c;指导实习生和在校生。这种乐于助人的行为对于行业的发展和新一代软件开发者的成长都起着积极的…

腾讯云镜像TencentOS Server操作系统介绍、性能稳定性测评

腾讯云TencentOS Server镜像是腾讯云推出的Linux操作系统&#xff0c;完全兼容CentOS生态和操作方式&#xff0c;TencentOS Server操作系统为云上运行的应用程序提供稳定、安全和高性能的执行环境&#xff0c;TencentOS可以运行在腾讯云CVM全规格实例上&#xff0c;包括黑石物理…

系列七、Nginx负载均衡配置

一、目标 浏览器中访问http://{IP地址}:9002/edu/index.html&#xff0c;浏览器交替打印清华大学8080、清华大学8081. 二、步骤 2.1、在tomcat8080、tomcat8081的webapps中分别创建edu文件夹 2.2、将index.html分别上传至edu文件夹 注意事项&#xff1a;tomcat8080的edu文件…

lv4 嵌入式开发-9 静态库与动态库的使用

目录 1 库的概念 2 库的知识 3 静态库特点 4 静态库 4.1静态库创建 4.2 编译生成目标文件 4.3 创建静态库 hello 4.4 查看库中符号信息 4.5 链接静态库 5 共享库特点 6 共享库 6.1 共享库创建 6.2 编译生成目标文件 6.3 创建共享库 common 6.4为共享库文件创建…