Slim-Neck by GSConv

paper:Slim-neck by GSConv: A better design paradigm of detector architectures for autonomous vehicles

official implementation:https://github.com/alanli1997/slim-neck-by-gsconv

背景

目标检测计算机视觉中一个重要的下游任务。对于车载边缘计算平台,一个较大的模型难以实现实时检测的要求。大量的深度可分离卷积(depth-wise separable convolution, DSC)层建立轻量级模型又不能达到足够的精度。而且DSC的缺陷也很明显:输入图像的通道信息在计算过程中被分离开来。如1(a)(b)分别展示了标准卷积(SC, standard convolution)和DSC的计算过程。这一缺陷导致DSC的特征提取和融合能力比SC要低得多。

实际上,许多轻量模型都提出了一些方法来缓解DSC的固有缺陷:MobileNets使用大量的1x1卷积来融合独立计算的通道信息;ShuffleNets使用“channel shuffle”操作进行通道信息的交互;GhostNets使用减半的SC来保留通道之间的信息交互。但1x1卷积占用了更多的计算资源,使用channel shuffle的效果仍然不如SC,而GhostNet或多或少的又回到了SC的道路上。

许多轻量网络都使用类似的思想来设计基本架构:从网络的开始到结束只使用DSC。但DSC的缺陷在backbone中被放大了,无论是用于分类还是检测。

本文的创新点

  • 本文提出了一种新的轻量级卷积方法,即GSConv。该方法使卷积计算的输出尽可能接近SC,并降低了计算成本。
  • 本文为自动驾驶的检测架构提供了一个设计范式,即标准backbone和slim-neck。
  • 本文验证了各种广泛使用的trick在GSConv-Slim-Neck Detector上的有效性,为该领域的研究提供了参考。

方法介绍

GSConv

作者认为标准卷积SC和深度可分离卷积DSC可以一起使用。仅通过shuffle深度可分离卷积的输出通道得到的特征图仍然是"depth-wise separated",为了使DSC的输出尽可能接近SC,作者提出了一种新的方法GSConv,它是一种将SC、DSC、shuffle混合到一起的卷积。如图2所示,我们通过shuffle操作将SC得到的信息permeate到DSC生成信息的每个部分中。shuffle是一种统一的混合策略。这种方法将来自SC的信息完全混合到DSC的输出中,通过均匀地交换不同通道上的局部特征信息,而无需附加操作。

图3展示了SC、DSC和GSConv的可视化结果,可以看出GSConv的特征图明显更类似于SC,而不是DSC。

 

在轻量级模型上,我们只使用GSConv层代替SC层就显著提高了精度;在其他模型中,当我们在backbone中使用SC并在neck中使用GSConv时,模型的精度非常接近原模型;如果加上一些trick,精度和速度都超过了原模型。采用GSConv的slim-neck最大限度地减少了DSC缺陷对模型的负面影响,并有效地利用了DSC的好处。

Why GSConv

在CNN中,输入图片总是在backbone中经历类似的转换过程:空间信息一步一步的转换到通道,每次空间维度的压缩(宽度和高度)和通道维度的扩展都会导致语义信息的部分丢失。通道密集channel-dense的卷积计算最大限度的保留了通道之间的隐藏连接,而通道稀疏channel-sparse的卷积完全切断了这些连接。GSConv以较低的时间复杂度尽可能的保留这些连接。通常,卷积的时间复杂度用FLOPs来表示,则SC(channle-dense convolution)、DSC(channel-sparse convolution)和GSConv的时间复杂度表示如下 

其中 \(W\) 是输出特征图的宽度,\(H\) 是输出特征图的高度,\(K_{1}\cdot K_{2}\) 是卷积核大小,\(C_{1}\) 是每个卷积核的通道数也是输入特征图的通道数,\(C_{2}\) 是输出特征图的通道数。实验中的表3展示了5种不同卷积block对模型性能的贡献。

GSConv的优点对轻量级检测模型更为明显,这得益于通过增加DSC和shuffle而增强的非线性表达能力。但如果在模型的各个阶段都使用GSConv,网络会变得更深,加剧对data flow的阻力并显著增加推理时间。当特征图到neck部分时,它们已经变得足够细了(通道达到最大,宽度和深度达到最小),转换也变得适中。因此更好的选择是只在neck部分使用GSConv(slim-neck + standard backbone)。在这个阶段使用GSConv处理拼接的特征图正合适:冗余的重复信息更少也不需要再压缩,注意力模块在这里也效果更好,例如SPP和CA。

The Slim-neck

作者研究了提高CNN学习能力的一些方法如DenseNet、VoVNet、CSPNet,然后根据这些方法的理论设计了slim-neck的结构。作者设计slim neck来减少计算复杂度和推理时间同时保持精度。GSConv完成了降低计算复杂度的任务,而减少推理时间和保持精度的任务需要新的模型。

The element modules of the slim-neck

GSConv的计算成本大约是SC的50%,但对模型学习能力的贡献与后者相当。作者在GSConv的基础上提出了GS bottleneck,如图4(a)所示。然后又使用one-shot aggregation(就是VoVNet,具体介绍见VoVNet(CVPR workshop 2019)原理与代码解析-CSDN博客)方法设计了cross stage partial network(GSCSP)模块,VoV-GSCSP。图4(b),(c),(d)展示了VoV-GSCSP的三种设计方案。其中(b)简单直接推理速度快,(c)(d)的特征重用率更高。

The slim-neck for the YOLO family

YOLO系列由于其高效的检测能力在工业中得到了广泛的应用。作者使用slim-neck来替换Scaled-YOLOv4l和YOLOv5l中的neck,改造后的neck和原始neck部分结构比较如下 

 

实验结果

作者在PASCAL VOC 2007+12数据集上测试了用五种不同卷积构建的YOLOv5n模型,结果如表3所示,GSConv取得了最好的结果。 

表5展示了图4中三种不同VoV-GSCSP结构的效果,可以看到,VoV-GSCSP1的性能最好且延迟最低。 

表6展示了YOLOv5n中使用不同注意力模块的实验结果。Part I中的所有模型使用slim-neck + slim-backbone的结构,Part II中的模型只使用slim-neck。作者发现使用不同的注意力模块对参数量和推理时间的影响差异不大,但对精度的影响是显著的。其中CA*3+SPPF*1在所有情况下就取得了最高的精度(关于CA的介绍见Coordinate Attention(CVPR 2021)-CSDN博客)。 此外当推理时间接近时,slim-neck的精度要远好于slim-backbone-neck结构。

代码

这里实现非常简单,就不作解释了。

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(c1, c_, k, s, None, g, act)
        self.cv2 = Conv(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)

 


http://www.niftyadmin.cn/n/5423879.html

相关文章

基于shardingsphere实现分库分表

数据按某个关键字段做分库分表,比如按userid,此处以userId为例,分为16个库(1-16),16个表(1-16)。 分库分表逻辑为: 分库:userId% 161(此处1-16所…

springboot3.x集成SpringDoc Swagger3

近期将springboox2.x升级到了3.x&#xff0c;索性将swagger2也同步升级到swagger3&#xff0c;具体过程如下。 一、添加maven依赖 <dependency><groupId>org.springdoc</groupId><artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>…

医疗康复行业发展前景好,还是小家电行业发展前景好?

大家好&#xff0c;我是记得诚。 读者问了一个问题&#xff0c;是这样的。 读者&#xff1a;你觉得目前是医疗康复行业发展前景好&#xff0c;还是小家电行业发展前景好&#xff1f; 记得诚&#xff1a;医疗康复和医疗诊断设备&#xff0c;是不是还是有点区别&#xff1f; …

干货!不懂Python的math模块和random模块操作还不赶紧来学!

1.导入math模块 import math 2.向上取整&#xff1a;math.ceil() num 9.12print(math.ceil(num)) # 10 3.向下取整&#xff1a;math.floor() num1 9.99print(math.floor(num1)) # 9 4.开平方&#xff1a;math.sqrt()​​​​​​​ num2 16print(math.sqrt(num…

从SPI协议学习PX4源码

一、SPI类 SPI类的参数&#xff1a;设备名称&#xff0c;devname设备节点名称&#xff0c;总线&#xff0c;device片选信号线&#xff0c;SPI模式&#xff0c;时钟频率&#xff0c;中断。SPI类继承VDev类。 SPI协议在spi.cpp文件中&#xff0c;涉及到了cdev和device的操作。c…

【每日八股】Java基础中面试你必须要掌握问题1

&#x1f525; 个人主页: 黑洞晓威 &#x1f600;你不必等到非常厉害&#xff0c;才敢开始&#xff0c;你需要开始&#xff0c;才会变的非常厉害。## 如何解决浮点数运算的精度丢失问题&#xff1f; BigDecimal 可以解决精度问题的原因在于它是一个精确的十进制数学运算类&…

Spring Cloud Alibaba微服务从入门到进阶(二)

Spring Boot配置管理 1、application.properties 2、application.yml 1.内容格式比较&#xff1a; .properties文件&#xff0c;通过 . 来连接&#xff0c;通过 来赋值&#xff0c;结构上&#xff0c;没有分层的感觉&#xff0c;但比较直接。 .yml文件&#xff0c;通过 &…

个人商城系统开源(配置支付宝支付!)

原文地址&#xff1a;个人商城系统开源&#xff08;配置支付宝支付&#xff01;&#xff09; - Pleasure的博客 下面是正文内容&#xff1a; 前言 由于近期实在没有什么话题可写和一些有趣的项目教程可以分享。所以我只能决定将我自己亲手编写的一个迷你迷你商城系统进行开源…