0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

SCConv:即插即用的空间和通道重建卷积

CVer 来源:CVer公众号 2023-09-14 17:05 次阅读

介绍

本文作者提出了一种名为SCConv(Spatial and Channel reconstruction Convolution, 空间和通道重建卷积)的卷积模块,目的是减少卷积神经网络中特征之间的空间和通道冗余,从而压缩CNN模型并提高其性能。

作者设计的 SCConv 模块,包含两个单元。一个名为SRU (Spatial Reconstruction Unit, 空间重构单元),一个名为CRU (Channel Reconstruction Unit, 通道重构单元)。其中 SRU 通过分离-重构方法来减少空间冗余,CRU 则使用分割-转换-融合方法来减少通道冗余。这两个单元协同工作,以减少CNN中特征的冗余信息

作者指出,SCConv 是一种可以直接替代标准卷积操作的插件式卷积模块 ,可以应用于各种卷积神经网络中,从而降低冗余特征并减少计算复杂性。

在后续的实验中,文章作者认为相对于其他流行的 SOTA 方法,他们提出的 SCConv 可以以更低的计算成本获得更高的准确率。下图是 ResNet50 在 ImageNet 上的 Top1 准确性测试结果。

75a85640-524f-11ee-a25d-92fbcf53809c.jpg模块设计

SCConv

如下图,SCConv 由两个单元组成,即空间重构单元 (SRU) 和信道重构单元 (CRU) ,两个单元按顺序排列。输入的特征 X 先经过空间重构单元,得到空间细化的特征Xw。再经过通道重构单元,得到通道提炼的特征 Y 作为输出。

SCConv 模块利用了特征之间的空间冗余和信道冗余,模块可以无缝集成到任何 CNN 框架中,减少特征之间的冗余,提高 CNN 特征的代表性。

75c49a4e-524f-11ee-a25d-92fbcf53809c.jpg

作者对SRUCRU进行不同的组合,包括:

  1. 不使用 SRU 和 CRU

  2. 单独使用 SRU

  3. 单独使用 CRU

  4. 并行使用 SRU 和 CRU

  5. 先使用 CRU 再使用 SRU

  6. 先使用 SRU 在使用 CRU

最终发现先使用 SRU 再使用 CRU 的效果最好。

75d66ce2-524f-11ee-a25d-92fbcf53809c.jpg

下面详细介绍 SRU 和 CRU 这两个单元。

SRU 空间重建单元

75e38062-524f-11ee-a25d-92fbcf53809c.jpg

在作者的设计中,该单元采用分离-重构的方法。

分离操作的目的是将信息量大的特征图从信息量小的特征图中分离出来,与空间内容相对应。作者使用组归一化 (Group Normalization) 里的缩放因子来评估不同特征图中的信息含量。

75fb325c-524f-11ee-a25d-92fbcf53809c.png760c3160-524f-11ee-a25d-92fbcf53809c.png761b66a8-524f-11ee-a25d-92fbcf53809c.png

762656da-524f-11ee-a25d-92fbcf53809c.png

76363a50-524f-11ee-a25d-92fbcf53809c.jpg

764302e4-524f-11ee-a25d-92fbcf53809c.png

经过 SRU 处理后,信息量大的特征从信息量小的特征中分离出来,减少了空间维度上的冗余特征。

CRU 通道重建单元

764eae0a-524f-11ee-a25d-92fbcf53809c.jpg

在作者的设计中,该单元采用分割-转换-融合的方法。

76626f58-524f-11ee-a25d-92fbcf53809c.png

实验

消融实验

下图的消融实验确定了 SRU 和 CRU 的排列方式

7685d394-524f-11ee-a25d-92fbcf53809c.jpg

下图的消融实验确定了 CRU 中的拆分系数α

7692da94-524f-11ee-a25d-92fbcf53809c.jpg

图片分类实验

下图是与其他 SOTA 方法的比较,作者认为在所有的情况下,SCConv-embedded 模型的准确性都优于先前所有的网络。在某些模型中,对比同类模型在减少参数和 FLOPs 的同时还实现了更高的准确率

76ad88a8-524f-11ee-a25d-92fbcf53809c.jpg在CVer微信公众号后台回复:SCConv,可以下载本论文pdf和代码

相关代码中文注释

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)  # 打印模型输出的形状


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 模块
    +关注

    关注

    7

    文章

    2486

    浏览量

    46548
  • 神经网络
    +关注

    关注

    42

    文章

    4575

    浏览量

    98782
  • cnn
    cnn
    +关注

    关注

    3

    文章

    327

    浏览量

    21304

原文标题:CVPR 2023 | 涨点神器!SCConv:即插即用的空间和通道重建卷积

文章出处:【微信号:CVer,微信公众号:CVer】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    即插即用和热插拔的区别

    本帖最后由 eehome 于 2013-1-5 10:01 编辑 “即插即用”是指安装了设备之后系统可以自动配置和管理设备,不需要人工处理即可使用。“热插拔”是指可以在开机状态下将设备与主机
    发表于 10-23 10:26

    LabView的IMAQ中如何调用非即插即用摄像头

    本帖最后由 Konzen 于 2013-8-13 09:03 编辑 以前用的CCD是即插即用(即Windows系统的驱动程序即可驱动)的,用IMAQ可以直接调用,现在换了个厂商自己开发的驱动程序的CCD,求各位大神告知怎么用Labview调用啊?
    发表于 08-12 09:31

    即插即用移动电源管理芯片

    即插即用移动电源管理芯片
    发表于 11-25 10:35

    即插即用的REV001主板

    描述索引即插即用主板 REV001这是拾放机器通用控制器的第二遍!此版本使用 32 位 ARM 芯片 STM32F407VET6,这是对之前使用的 ATMega2560 的巨大升级。它现在还
    发表于 06-20 09:10

    PCI与即插即用

    PCI与即插即用 即插即用 是从英文“Plug and Play”翻译过来的,缩写为 PnP 。即插即用功能只有在同时具备了符合以下4个条件时才可以:即插即
    发表于 12-09 13:51 2014次阅读

    什么是即插即用

    什么是即插即用              支持即插即用是一种使您可以快速简易安装某硬件设备而无需安装设备驱动程序或重新
    发表于 12-28 11:17 2041次阅读

    赛灵思推出即插即用高清电视参考设计

    赛灵思推出即插即用高清电视参考设计  全球可编程逻辑解决方案领导厂商赛灵思公司(Xilinx, Inc.)近日推出一款全新的消费视频增强参考设计。该款参考设计基于一个
    发表于 01-27 09:52 659次阅读

    基于转换模块的空间即插即用综合电子系统研究

    针对空间即插即用技术特点,本文研究了一种转换模块,实现了将传统航天器单机向具有标准即插即用接口与驱动的标准单机的转换。文中给出了转换模块的主要功能、信息交互流程、
    发表于 07-24 16:48 0次下载
    基于转换模块的<b class='flag-5'>空间</b><b class='flag-5'>即插即用</b>综合电子系统研究

    Linux下即插即用设备的安装

    即插即用,在Linux底下?不好办,你还是换老的非即插即用设备吧。这是我初次接触Linux时,那些Linux高手们告诉我的。可是,我觉得总该有办法的。经过不懈的努力,我发现了两种方法。一是先从DOS
    发表于 11-07 10:28 0次下载

    详细剖析OPC和即插即用技术

    要介绍OPC和即插即用技术,重点对OPC实际应用标准的发展、技术、特点及适用范围与接口应用作分折说明。
    的头像 发表于 01-26 15:18 5717次阅读
    详细剖析OPC和<b class='flag-5'>即插即用</b>技术

    Bluetechnix演示即插即用摄像机系统

    本视频展示了一种基于Blackfin处理器的即插即用摄像机系统,由Bluetechnix GmbH开发。
    的头像 发表于 06-04 13:47 1853次阅读

    90 W即插即用100米5e类电缆的以太网供电

    90 W即插即用100米5e类电缆的以太网供电
    发表于 05-15 19:40 7次下载
    90 W<b class='flag-5'>即插即用</b>100米5e类电缆的以太网供电

    索引即插即用主板REV001

    电子发烧友网站提供《索引即插即用主板REV001.zip》资料免费下载
    发表于 07-18 17:09 3次下载
    索引<b class='flag-5'>即插即用</b>主板REV001

    索引即插即用主板REV000

    电子发烧友网站提供《索引即插即用主板REV000.zip》资料免费下载
    发表于 07-27 11:27 4次下载
    索引<b class='flag-5'>即插即用</b>主板REV000

    电源系统设计:非完全“即插即用

    电源系统设计:非完全“即插即用
    发表于 11-07 08:07 1次下载
    电源系统设计:非完全“<b class='flag-5'>即插即用</b>”