CVPR2023 即插即用 SCConv (附代码)

news2024/11/18 2:51:17

论文地址:SSCONV

代码地址:https://github.com/cheng-haha/ScConv

1.是什么?

SCConv是一种高效的卷积模块,用于压缩卷积神经网络中的冗余特征,以减少计算负荷并提高模型性能。它由空间重构单元(SRU)和信道重构单元(CRU)两个单元组成,SRU用于抑制空间冗余,CRU用于减少信道冗余。SCConv可以直接用于替代各种卷积神经网络中的标准卷积,是一种即插即用的架构单元。实验结果表明,将SCConv嵌入模型可以通过减少冗余特征来获得更好的性能,并且显著降低了复杂度和计算成本。

2.为什么?

卷积神经网络(CNN)在各种计算机视觉任务中取得了显著的性能,但这是以巨大的计算资源为代价的,部分原因是卷积层提取冗余特征。最近的作品要么压缩训练有素的大型模型,要么探索设计良好的轻量级模型。在本文中,我们尝试利用特征之间的空间和通道冗余来进行CNN压缩,并提出了一种高效的卷积模块,称为SCConv (spatial and channel reconstruction convolution),以减少冗余计算并促进代表性特征的学习。提出的SCConv由空间重构单元(SRU)和信道重构单元(CRU)两个单元组成。SRU采用分离重构的方法来抑制空间冗余,CRU采用分离变换融合的策略来减少信道冗余。此外,SCConv是一种即插即用的架构单元,可直接用于替代各种卷积神经网络中的标准卷积。实验结果表明,scconvo嵌入模型能够通过减少冗余特征来获得更好的性能,并且显著降低了复杂度和计算成本。

3.怎么样?

3.1网络结构

如图所示的SCConv,它由空间重构单元(SRU)和通道重构单元(CRU)两个按顺序放置的单元组成。具体而言,对于瓶颈残差块中的中间输入特征X,首先通过SRU操作得到空间细化特征Xw,然后利用CRU操作得到通道细化特征Y。在SCConv模块中利用特征之间的空间和通道冗余,可以无缝集成到任何CNN架构中,以减少中间特征图之间的冗余,并提高CNN的特征表示。

3.2 模块

3.2.1SRU用于空间冗余

为了利用特征的空间冗余性,我们引入了空间重构单元(SRU),如图2所示,采用分离-重构操作。分离操作旨在将信息丰富的特征图与与空间内容对应的信息较少的特征图分离。利用组归一化(GN)层中的缩放因子来评估不同特征图的信息内容。具体来说,给定一个中间特征图X∈R N×C×H×W,其中N为批处理轴,C为通道轴,H和W为空间高度和宽度轴。我们首先通过减去均值µ除以标准差σ来标准化输入特征X,如下所示:

其中,μ和σ是X的均值和标准差,ε是一个为了稳定除法而添加的小的正数,γ和β是可训练的仿射变换。

注意到我们在GN层中利用可训练参数\gamma \epsilon R^{C}来衡量每个批次和通道的空间像素的方差。更丰富的空间信息反映了更多的空间像素的变化,从而贡献更大的γ 。归一化的相关权重W_{\gamma } \varepsilon R^{C}
通过等式获得,这表明了不同特征图的重要性。
 

 然后通过sigmoid函数将由W_{\gamma }重新加权的特征图的权重值映射到范围(0,1)并通过阈值进行门控。我们将高于阈值的权重设置为1以获得信息丰富的权重W_{1} ,而将它们设置为0以获得非信息丰富的权重W_{2}(在实验中阈值设置为0.5)。获取W 的整个过程可以由等式表示:

最后,我们将输入特征X分别乘以W_{1} 和W_{2} ,得到两个加权特征:信息丰富的特征X_{1}^{w}和信息较少的特征X_{2}^{w}。这样我们就成功地将输入特征分为两个部分:X_{1}^{w}具有信息丰富和表现力强的空间内容,而X_{2}^{w}几乎没有信息,被视为冗余。


 

为了进一步减少空间冗余,我们提出了一种Reconstruct操作,将富含信息的特征与信息较少的特征相加,以生成更丰富的信息特征并节省空间。我们没有直接将这两个部分相加,而是采用交叉重建操作来充分结合加权的两个不同的信息丰富的特征,并加强它们之间的信息流。之后我们将交叉重建后的特征X^{w1}X^{w2 } 连接起来以获得空间细化特征图X^{w}。Reconstruct操作的整体过程可以表示为:

其中⊗ 表示逐元素相乘,⊕表示逐元素相加,∪ 表示拼接。将SRU应用于中间输入特征X XX后,我们不仅将信息丰富的特征与信息较少的特征分离,而且对它们进行了重构以增强代表性特征并抑制空间维度中的冗余特征。然而,空间细化特征图X^{w}在通道维度上仍然存在冗余。

3.2.2. CRU用于通道冗余

为了利用特征的通道冗余,我们引入了通道重建单元(CRU),如图3所示,它利用了“分割-转换-融合”的策略。通常,我们使用重复的标准k \times k卷积来提取特征,导致一些相对冗余的特征图沿着通道维度。让我们M^{k}\epsilon R^{c*k*k}表示一个k \times k卷积核,X,Y\varepsilon R^{c*k*k} 表示输入和卷积后的输出特征。一个标准卷积可以定义为Y = M^{k}X。具体来说,我们将标准卷积替换为CRU,它通过三个运算符-Split、Transform和Fuse来实现。

Split:对于给定的空间细化特征X^{w}\varepsilon R^{c*k*k},我们首先将X^{w}的通道分成两部分,其中一部分具有αC个通道,另一部分具有( 1 − α ) C 个通道,如图3中的分割部分所示,其中0 ≤ α ≤ 1 是一个分割比例。随后,我们进一步利用1 \times 1卷积来压缩特征图的通道以提高计算效率。这里我们引入一个压缩比例r来控制CRU的特征通道以平衡计算成本(实验中典型的r设置为2)。在分割和压缩操作之后,我们将空间细化特征X^{w}分为上部分X_{up} 和下部分X_{low}

Transform:X_{up} 被输入到上转换阶段,作为“丰富的特征提取器”。我们采用高效的卷积操作(即GWC和PWC)来代替昂贵的标准k \times k卷积来提取高级代表性信息,同时降低计算成本。由于稀疏卷积连接,GWC减少了参数和计算量,但切断了通道组之间的信息流。而PWC弥补了信息的损失并帮助信息在特征通道之间流动。因此,我们在相同的X_{up}上执行k × k  GWC(在实验中我们将组大小g = 2 g=2g=2)和1 × 1  PWC操作。之后,我们将输出相加形成合并代表特征图Y_{1} ,如图3中的Transform部分所示。上转换阶段可以表示为:

其中M^{G}\epsilon \mathbb{R}^{\frac{ac}{gr}*k*k*c},M^{P_{1}}\epsilon \mathbb{R}^{\frac{ac}{r}*1*1*c} 是GWC和PWC的可学习权重矩阵,X_{up}\epsilon \mathbb{R}^{\frac{ac}{r}*1*1*c}
 和Y_{1}\epsilon \mathbb{R}^{c*h*w} 分别是上输入和输出特征图。简而言之,上转换阶段利用GWC和PWC在相同的特征图X_{up}上的组合来以较少的计算成本提取丰富的代表性特征Y_{1}   。
X_{low }被输入到底部转换阶段,其中我们应用廉价的1 × 1  PWC操作生成具有浅层隐藏细节的特征图,作为丰富特征提取器的补充。此外,我们重用特征X_{low }​以获取更多的特征图而不增加额外成本。最后,我们将生成的和重用的特征连接起来形成底部阶段的输出Y_{2} ,如下所示:

其中M^{P_{2}}\epsilon \mathbb{R}^{\frac{(1-a)c}{r}*1*1*(1-\frac{1-a}{r})*c}是PWC的可学习权重矩阵,∪是连接操作,X_{low}\epsilon \mathbb{R}^{\frac{(1-a)c}{r}*h*w}Y_{2}\epsilon \mathbb{R}^{c*h*w}分别是底部输入和输出特征图。总之,底部转换阶段重用前面的特征X_{low }并利用廉价的1 × 1 PWC来获取具有补充详细信息的特征Y_{2}

merge:在进行转换之后,我们不是直接连接或添加两种类型的特征,而是利用简化的SKNet方法自适应地合并上转换阶段和下转换阶段的输出特征Y_{1} 和Y_{2},如图3的Fuse部分所示。我们首先应用全局平均池化(Pooling)来收集全局空间信息,通道统计信息S_{m}\varepsilon R^{c*1*1}计算如下:

接下来,我们将上部分和下部分的全局通道描述子S_{1},S_{2}堆叠在一起,并使用通道注意力操作来生成特征重要性向量\beta _{1},\beta _{2} \epsilon \mathbb{R}^{C} ,如下所示:

最后,在特征重要性向量\beta _{1},\beta _{2}的指导下,通过以通道的方式合并上特征Y_{1} 和下特征Y_{2}
 来获得通道精细化特征Y ,如下所示:
 

简而言之,我们采用CRU,使用Split-Transform-and-Fuse策略,以进一步减少空间细化特征图X^{w}在通道维度上的冗余。此外,CRU通过轻量级卷积操作提取丰富的代表性特征,同时使用廉价操作和特征重用方案进行冗余特征的处理。总体而言,CRU可以单独使用或与SRU操作结合使用。通过以顺序方式排列SRU和CRU,建立了提出的SCConv,它具有高效率且能够替代标准卷积操作。

3.3代码实现

import torch  # 导入 PyTorch 库
import torch.nn.functional as F  # 导入 PyTorch 的函数库
import torch.nn as nn  # 导入 PyTorch 的神经网络模块
 
# 自定义 GroupBatchnorm2d 类,实现分组批量归一化
class GroupBatchnorm2d(nn.Module):
    def __init__(self, c_num:int, group_num:int = 16, eps:float = 1e-10):
        super(GroupBatchnorm2d,self).__init__()  # 调用父类构造函数
        assert c_num >= group_num  # 断言 c_num 大于等于 group_num
        self.group_num  = group_num  # 设置分组数量
        self.gamma      = nn.Parameter(torch.randn(c_num, 1, 1))  # 创建可训练参数 gamma
        self.beta       = nn.Parameter(torch.zeros(c_num, 1, 1))  # 创建可训练参数 beta
        self.eps        = eps  # 设置小的常数 eps 用于稳定计算
 
    def forward(self, x):
        N, C, H, W  = x.size()  # 获取输入张量的尺寸
        x           = x.view(N, self.group_num, -1)  # 将输入张量重新排列为指定的形状
        mean        = x.mean(dim=2, keepdim=True)  # 计算每个组的均值
        std         = x.std(dim=2, keepdim=True)  # 计算每个组的标准差
        x           = (x - mean) / (std + self.eps)  # 应用批量归一化
        x           = x.view(N, C, H, W)  # 恢复原始形状
        return x * self.gamma + self.beta  # 返回归一化后的张量
 
# 自定义 SRU(Spatial and Reconstruct Unit)类
class SRU(nn.Module):
    def __init__(self,
                 oup_channels:int,  # 输出通道数
                 group_num:int = 16,  # 分组数,默认为16
                 gate_treshold:float = 0.5,  # 门控阈值,默认为0.5
                 torch_gn:bool = False  # 是否使用PyTorch内置的GroupNorm,默认为False
                 ):
        super().__init__()  # 调用父类构造函数
 
         # 初始化 GroupNorm 层或自定义 GroupBatchnorm2d 层
        self.gn = nn.GroupNorm(num_channels=oup_channels, num_groups=group_num) if torch_gn else GroupBatchnorm2d(c_num=oup_channels, group_num=group_num)
        self.gate_treshold  = gate_treshold  # 设置门控阈值
        self.sigomid        = nn.Sigmoid()  # 创建 sigmoid 激活函数
 
    def forward(self, x):
        gn_x        = self.gn(x)  # 应用分组批量归一化
        w_gamma     = self.gn.gamma / sum(self.gn.gamma)  # 计算 gamma 权重
        reweights   = self.sigomid(gn_x * w_gamma)  # 计算重要性权重
 
        # 门控机制
        info_mask    = reweights >= self.gate_treshold  # 计算信息门控掩码
        noninfo_mask = reweights < self.gate_treshold  # 计算非信息门控掩码
        x_1          = info_mask * x  # 使用信息门控掩码
        x_2          = noninfo_mask * x  # 使用非信息门控掩码
        x            = self.reconstruct(x_1, x_2)  # 重构特征
        return x
 
    def reconstruct(self, x_1, x_2):
        x_11, x_12 = torch.split(x_1, x_1.size(1) // 2, dim=1)  # 拆分特征为两部分
        x_21, x_22 = torch.split(x_2, x_2.size(1) // 2, dim=1)  # 拆分特征为两部分
        return torch.cat([x_11 + x_22, x_12 + x_21], dim=1)  # 重构特征并连接
 
# 自定义 CRU(Channel Reduction Unit)类
class CRU(nn.Module):
    def __init__(self, op_channel:int, alpha:float = 1/2, squeeze_radio:int = 2, group_size:int = 2, group_kernel_size:int = 3):
        super().__init__()  # 调用父类构造函数
 
        self.up_channel     = up_channel = int(alpha * op_channel)  # 计算上层通道数
        self.low_channel    = low_channel = op_channel - up_channel  # 计算下层通道数
        self.squeeze1       = nn.Conv2d(up_channel, up_channel // squeeze_radio, kernel_size=1, bias=False)  # 创建卷积层
        self.squeeze2       = nn.Conv2d(low_channel, low_channel // squeeze_radio, kernel_size=1, bias=False)  # 创建卷积层
 
        # 上层特征转换
        self.GWC            = nn.Conv2d(up_channel // squeeze_radio, op_channel, kernel_size=group_kernel_size, stride=1, padding=group_kernel_size // 2, groups=group_size)  # 创建卷积层
        self.PWC1           = nn.Conv2d(up_channel // squeeze_radio, op_channel, kernel_size=1, bias=False)  # 创建卷积层
 
        # 下层特征转换
        self.PWC2           = nn.Conv2d(low_channel // squeeze_radio, op_channel - low_channel // squeeze_radio, kernel_size=1, bias=False)  # 创建卷积层
        self.advavg         = nn.AdaptiveAvgPool2d(1)  # 创建自适应平均池化层
 
    def forward(self, x):
        # 分割输入特征
        up, low = torch.split(x, [self.up_channel, self.low_channel], dim=1)
        up, low = self.squeeze1(up), self.squeeze2(low)
 
        # 上层特征转换
        Y1 = self.GWC(up) + self.PWC1(up)
 
        # 下层特征转换
        Y2 = torch.cat([self.PWC2(low), low], dim=1)
 
        # 特征融合
        out = torch.cat([Y1, Y2], dim=1)
        out = F.softmax(self.advavg(out), dim=1) * out
        out1, out2 = torch.split(out, out.size(1) // 2, dim=1)
        return out1 + out2
 
# 自定义 ScConv(Squeeze and Channel Reduction Convolution)模型
class ScConv(nn.Module):
    def __init__(self, op_channel:int, group_num:int = 16, gate_treshold:float = 0.5, alpha:float = 1/2, squeeze_radio:int = 2, group_size:int = 2, group_kernel_size:int = 3):
        super().__init__()  # 调用父类构造函数
 
        self.SRU = SRU(op_channel, group_num=group_num, gate_treshold=gate_treshold)  # 创建 SRU 层
        self.CRU = CRU(op_channel, alpha=alpha, squeeze_radio=squeeze_radio, group_size=group_size, group_kernel_size=group_kernel_size)  # 创建 CRU 层
 
    def forward(self, x):
        x = self.SRU(x)  # 应用 SRU 层
        x = self.CRU(x)  # 应用 CRU 层
        return x
 
if __name__ == '__main__':
    x       = torch.randn(1, 32, 16, 16)  # 创建随机输入张量
    model   = ScConv(32)  # 创建 ScConv 模型
    print(model(x).shape)  # 打印模型输出的形状


 

参考:

CVPR 2023 | SCConv: 即插即用的空间和通道重建卷积(附源码)

SCConv:用于特征冗余的空间和通道重构卷积

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

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

相关文章

如何保障单病种上报的填报效率、质量监控及数据安全

在国家平台对单病种病例进行手工直报&#xff0c;是大多数医院最初获知《关于进一步加强单病种质量管理与控制工作的通知》后的首选方式。随着医院对上报流程与内容的逐步熟练&#xff0c;质控管理的需求开始凸显并占据主要地位&#xff0c;同时为了能更好地适应国家平台的频繁…

基于STM32设计的万能红外遥控器(学习型)

一、项目设计 基于STM32设计的万能红外遥控器(学习型) 随着智能家居和物联网技术的发展,红外遥控器作为传统的智能设备控制方式逐渐被淘汰,但在某些场景下,红外遥控器仍然是一种快速、简单的操作方式,当前介绍了一种基于STM32微控制器设计的红外遥控器,支持接收解码功能和…

谁在成为产业供应链的“新发动机”?

京东供应链金融路径不仅是金融的助力和加持&#xff0c;也更是京东供应链金融科技在产业侧的更有价值表达&#xff0c;推动当下产业数字互联从点到线&#xff0c;再到网的更大程度协同。 作者|皮爷 出品|产业家 2022年&#xff0c;一款名为“海油e融”的融资产品出现在市面…

CSS色域、色彩空间、CSS Color 4新标准 | 京东云技术团队

引言 近期&#xff0c;三大主流浏览器引擎均发布最新版本&#xff0c;支持W3C的CSS Color 4标准&#xff0c;包含新的取色方法color()和相应语法&#xff0c;可展示更多的色域及色彩空间&#xff0c;这意味着web端能展示更丰富更高清的色彩。虽然目前只有最新版本的现代浏览器…

非对称加密算法RSA的深度解析,在CTF中RSA题目

一、背景 现代密码体系中&#xff0c;主要分为两类&#xff0c;对称加密和非对称加密两大类。在安全性方面上&#xff0c;非对称加密以安全可靠&#xff0c;在互联网中特别广泛的使用&#xff0c;就如我们平时接触到的https的TLS等一些证书的实现&#xff0c;也深得非对称加密…

showdoc 文件上传 (cnvd-2020-26585)

showdoc 文件上传 &#xff08;cnvd-2020-26585&#xff09; 描述 ShowDoc是一个非常适合IT团队的在线API文档、技术文档工具。通过showdoc&#xff0c;你可以方便地使用markdown语法来书写出美观的API文档、数据字典文档、技术文档、在线excel文档等等。 api_page存在任意文…

漏洞复现-showdoc文件上传_v2.8.3_(CNVD-2020-26585)

showdoc文件上传_v2.8.3_CNVD-2020-26585 漏洞信息 showdoc 2.8.3 以下版本中存在安全漏洞CNVD-2020-26585文件上传漏洞 描述 ShowDoc是一个非常适合IT团队的在线API文档、技术文档工具。通过showdoc&#xff0c;你可以方便地使用markdown语法来书写出美观的API文档、数据字…

做国外问卷调查的工作靠谱吗?

哈喽大家好&#xff0c;我是橙河网络&#xff0c;最近网上都在传做问卷能赚美金的项目&#xff0c;也就是“海外问卷调查”&#xff0c;我在这跟大家简单唠唠它是个啥&#xff0c;做国外问卷调查的工作靠谱吗&#xff1f; 海外问卷调查&#xff0c;顾名思义&#xff0c;就是我…

开始学习Go编程

探索Go编程中的语法、数据类型和控制流 Go&#xff0c;又称为Golang&#xff0c;因其简单性、性能和效率而广受欢迎。在本文中&#xff0c;我们将深入研究构成Go编程语言基础的基本概念。从理解其语法和数据类型到掌握控制流和函数&#xff0c;我们将为您提供启动Go编程之旅所…

芋道前后端分离项目跳过登录

后端接口 1. nacos配置 根据以上两图可以发现芋道的跳过登录配置在nacos或者yml可以配置成如下样式 将所有需要跳过登录的方法写在permit-all_urls下级即可 2. PermitAll注解&#xff1a;不管登入,不登入 都能访问 注&#xff1a;如果一个页面有多个接口那么所有接口均需要写…

【算法-数组1】二分查找 和 移除元素

今天&#xff0c;带来XXX的讲解。文中不足错漏之处望请斧正&#xff01; 理论基础 二分查找 给定一个 n 个元素有序的&#xff08;升序&#xff09;整型数组 nums 和一个目标值 target &#xff0c;写一个函数搜索 nums 中的 target&#xff0c;如果目标值存在返回下标&#…

AMEYA360:炬玄智能车规级RTC芯片JXR191T为车载BMS提供16年稳态输出

北京炬玄智能科技有限公司聚焦于集成电路时钟芯片研发及生产&#xff0c;以高精度、高稳定性、集成化芯片和系统设计为主要方向&#xff0c;以实时时钟芯片(RTC)及模组为切入点&#xff0c;逐步将产品拓展到以TCXO、OCXO为代表的高端晶振芯片领域&#xff0c;最终打通整个时钟产…

探讨Java多线程调度:如何实现两线程并行,一线程等待?

亲爱的小伙伴们&#xff0c;大家好&#xff01;我是小米&#xff0c;很高兴再次和大家分享一些关于Java编程的有趣技巧和知识。今天&#xff0c;我们将探讨一个有趣且常见的面试问题&#xff1a;如何让两个线程同时执行&#xff0c;而第三个线程必须等待前两个线程结束后才能开…

trucksim常见问题

一、Error: Unable to load .vs data from “D:\Users\Public\Documents\TruckSim2019.0 Data\Results\Run_e24aa2… LastRun.vs”.Reason for failure: Invalid character OxFFFFFFB2 in string"" on line 4.Would you like to continue receiving alerts of this t…

RPA厂商大比拼,哪家才更适合您?

引言&#xff1a;随着数字化时代的到来&#xff0c;自动化已成为推动企业数字化发展的关键举措之一&#xff0c;RPA作为自动化中的重要技术之一&#xff0c;可为企业提供了实现业务流程自动化的强大工具。然而&#xff0c;如何选择适合自己的RPA厂商也是各大企业现在面临的难题…

调试-Debug

0.1 Debug环境介绍 Microsoft Visual Studio 2022中&#xff1a; Debug版本的可执行程序称为调试版本&#xff0c;包含调试信息&#xff0c;不作任何优化&#xff0c;便于程序员进行调试。 Release版本的可执行程序称为发布版本&#xff0c;进行了各种优化&#xff0c;不可调…

小红书内容运营包含哪些,内容种草攻略

在这个社交属性&#xff0c;强势泛滥的年代&#xff0c;兼具了社交和电商两大功能的小红书&#xff0c;已经成为品牌方的兵家必争之地。今天来为大家分享下小红书内容运营包含哪些&#xff0c;内容种草攻略&#xff01; 1、确定账号定位 这是做好小红书内容运营的第一步。一个有…

扫地机器人,不相信视觉导航

不可置否&#xff0c;激光雷达已经成为扫地机器人的“耶路撒冷”。 导航技术的从无到有 回顾扫地机器人的兴衰&#xff0c;本质是导航技术的从无到有、从弱到强、从少到多&#xff0c;而在这个过程中&#xff0c;激光雷达无疑发挥了无可替代的作用。2010年&#xff0c;第一台…

实时嵌入式系统环境中敏捷的基础

不同的人使用敏捷一词的含义不同。在计算中&#xff0c;该术语最初用于描述执行项目开发的轻量级方法&#xff0c;而最初的术语极限编程&#xff08;XP&#xff09;未能激发受托管理开发项目的众多管理人员。 基本上&#xff0c;敏捷软件开发指的是一组松散集成的原则和实践&a…

Vue echarts 折线图 背景颜色渐变 (两种实现方式)

需求 实现方式 两种方法 方法一&#xff1a;color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{}&#xff0c;{}&#xff0c;{}]) 方法二&#xff1a;避开new echarts&#xff0c;color: {x: 0, y: 0, x2: 0, y2: 1,colorStops: [{}&#xff0c;{}&#xff0c;{}]} …