即插即用模块详解SCConv:用于特征冗余的空间和通道重构卷积

本文主要是介绍即插即用模块详解SCConv:用于特征冗余的空间和通道重构卷积,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

一、摘要

二、创新点说明

2.1 Methodology

 2.2SRU for Spatial Redundancy​编辑

2.3CRU for Channel Redundancy

三、实验

3.1基于CIFAR的图像分类

3.2基于ImageNet的图像分类

3.3对象检测

四、代码详解

五、总结


论文:https://openaccess.thecvf.com/content/CVPR2023/papers/Li_SCConv_Spatial_and_Channel_Reconstruction_Convolution_for_Feature_Redundancy_CVPR_2023_paper.pdf

代码:GitHub - cheng-haha/ScConv: SCConv: Spatial and Channel Reconstruction Convolution for Feature Redundancy

一、摘要

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

论文贡献总结:

       1. 提出了一种空间重构单元SRU,该单元根据权重分离冗余特征并进行重构,以抑制空间维度上的冗余,增强特征的表征能力。
       2. 我们提出了一种信道重构单元,称为CRU,它利用分裂变换和融合策略来减少信道维度的冗余以及计算成本和存储。
        3.我们设计了一种名为SCConv的即插即用操作,将SRU和CRU以顺序的方式组合在一起,以取代标准卷积,用于在各种骨干cnn上操作。结果表明,SCConv可以大大节省计算负荷,同时提高模型在挑战性任务上的性能。

二、创新点说明

2.1 Methodology

SCConv,它由两个单元组成,空间重建单元(SRU)和通道重建单元(CRU),以顺序的方式放置。具体而言,对于瓶颈残差块中的中间输入特征X,我们首先通过SRU运算获得空间细化特征Xw,然后利用CRU运算获得信道细化特征Y。我们在SCConv模块中利用了特征之间的空间冗余和通道冗余,可以无缝集成到任何CNN架构中,以减少中间特征映射之间的冗余并增强CNN的特征表示。

 2.2SRU for Spatial Redundancy

为了利用特征的空间冗余,我们引入了空间重构单元(SRU),如图2所示,它利用了分离和重构操作。分离操作的目的是将信息丰富的特征图与空间内容对应的信息较少的特征图分离开来。

2.3CRU for Channel Redundancy

为了利用特征的信道冗余,我们引入了信道重构单元(CRU),如图3所示,它利用了分裂-转换-融合策略。

三、实验

3.1基于CIFAR的图像分类

3.2基于ImageNet的图像分类

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_numself.group_num  = group_num  # 设置分组数量self.gamma      = nn.Parameter(torch.randn(c_num, 1, 1))  # 创建可训练参数 gammaself.beta       = nn.Parameter(torch.zeros(c_num, 1, 1))  # 创建可训练参数 betaself.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,  # 分组数,默认为16gate_treshold:float = 0.5,  # 门控阈值,默认为0.5torch_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 xdef 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) * outout1, 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 xif __name__ == '__main__':x       = torch.randn(1, 32, 16, 16)  # 创建随机输入张量model   = ScConv(32)  # 创建 ScConv 模型print(model(x).shape)  # 打印模型输出的形状

五、总结

在本文中,我们提出了一种新的空间和信道重构模块(SCConv),这是一种有效的架构单元,可以降低计算成本和模型存储,同时通过减少标准卷积中广泛存在的空间和信道冗余来提高CNN模型的性能。我们使用两个不同的模块SRU和CRU来减少特征映射中的冗余,在减少大量计算负载的同时实现了相当大的性能改进。此外,SCConv是一个即插即用的模块,可以替代标准的卷积,不需要任何模型架构的调整。此外,各种SOTA方法在图像分类和目标检测方面的大量实验表明,scconvn嵌入模型在性能和模型效率之间取得了更好的平衡。最后,我们希望所提出的方法可以启发研究更有效的建筑设计。

参考:大佬

这篇关于即插即用模块详解SCConv:用于特征冗余的空间和通道重构卷积的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/909344

相关文章

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

python: 多模块(.py)中全局变量的导入

文章目录 global关键字可变类型和不可变类型数据的内存地址单模块(单个py文件)的全局变量示例总结 多模块(多个py文件)的全局变量from x import x导入全局变量示例 import x导入全局变量示例 总结 global关键字 global 的作用范围是模块(.py)级别: 当你在一个模块(文件)中使用 global 声明变量时,这个变量只在该模块的全局命名空

深入探索协同过滤:从原理到推荐模块案例

文章目录 前言一、协同过滤1. 基于用户的协同过滤(UserCF)2. 基于物品的协同过滤(ItemCF)3. 相似度计算方法 二、相似度计算方法1. 欧氏距离2. 皮尔逊相关系数3. 杰卡德相似系数4. 余弦相似度 三、推荐模块案例1.基于文章的协同过滤推荐功能2.基于用户的协同过滤推荐功能 前言     在信息过载的时代,推荐系统成为连接用户与内容的桥梁。本文聚焦于

OpenHarmony鸿蒙开发( Beta5.0)无感配网详解

1、简介 无感配网是指在设备联网过程中无需输入热点相关账号信息,即可快速实现设备配网,是一种兼顾高效性、可靠性和安全性的配网方式。 2、配网原理 2.1 通信原理 手机和智能设备之间的信息传递,利用特有的NAN协议实现。利用手机和智能设备之间的WiFi 感知订阅、发布能力,实现了数字管家应用和设备之间的发现。在完成设备间的认证和响应后,即可发送相关配网数据。同时还支持与常规Sof

6.1.数据结构-c/c++堆详解下篇(堆排序,TopK问题)

上篇:6.1.数据结构-c/c++模拟实现堆上篇(向下,上调整算法,建堆,增删数据)-CSDN博客 本章重点 1.使用堆来完成堆排序 2.使用堆解决TopK问题 目录 一.堆排序 1.1 思路 1.2 代码 1.3 简单测试 二.TopK问题 2.1 思路(求最小): 2.2 C语言代码(手写堆) 2.3 C++代码(使用优先级队列 priority_queue)

MOLE 2.5 分析分子通道和孔隙

软件介绍 生物大分子通道和孔隙在生物学中发挥着重要作用,例如在分子识别和酶底物特异性方面。 我们介绍了一种名为 MOLE 2.5 的高级软件工具,该工具旨在分析分子通道和孔隙。 与其他可用软件工具的基准测试表明,MOLE 2.5 相比更快、更强大、功能更丰富。作为一项新功能,MOLE 2.5 可以估算已识别通道的物理化学性质。 软件下载 https://pan.quark.cn/s/57

K8S(Kubernetes)开源的容器编排平台安装步骤详解

K8S(Kubernetes)是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序。以下是K8S容器编排平台的安装步骤、使用方式及特点的概述: 安装步骤: 安装Docker:K8S需要基于Docker来运行容器化应用程序。首先要在所有节点上安装Docker引擎。 安装Kubernetes Master:在集群中选择一台主机作为Master节点,安装K8S的控制平面组件,如AP

嵌入式Openharmony系统构建与启动详解

大家好,今天主要给大家分享一下,如何构建Openharmony子系统以及系统的启动过程分解。 第一:OpenHarmony系统构建      首先熟悉一下,构建系统是一种自动化处理工具的集合,通过将源代码文件进行一系列处理,最终生成和用户可以使用的目标文件。这里的目标文件包括静态链接库文件、动态链接库文件、可执行文件、脚本文件、配置文件等。      我们在编写hellowor

LabVIEW FIFO详解

在LabVIEW的FPGA开发中,FIFO(先入先出队列)是常用的数据传输机制。通过配置FIFO的属性,工程师可以在FPGA和主机之间,或不同FPGA VIs之间进行高效的数据传输。根据具体需求,FIFO有多种类型与实现方式,包括目标范围内FIFO(Target-Scoped)、DMA FIFO以及点对点流(Peer-to-Peer)。 FIFO类型 **目标范围FIFO(Target-Sc

019、JOptionPane类的常用静态方法详解

目录 JOptionPane类的常用静态方法详解 1. showInputDialog()方法 1.1基本用法 1.2带有默认值的输入框 1.3带有选项的输入对话框 1.4自定义图标的输入对话框 2. showConfirmDialog()方法 2.1基本用法 2.2自定义按钮和图标 2.3带有自定义组件的确认对话框 3. showMessageDialog()方法 3.1