Split to Be Slim: 论文复现

这篇具有很好参考价值的文章主要介绍了Split to Be Slim: 论文复现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

摘要:在本论文中揭示了这样一种现象:一层内的许多特征图共享相似但不相同的模式。

本文分享自华为云社区《Split to Be Slim: 论文复现》,作者: 李长安 。

Split to Be Slim: An Overlooked Redundancy in Vanilla Convolution 论文复现

1、问题切入

已经提出了许多有效的解决方案来减少推理加速模型的冗余。然而,常见的方法主要集中在消除不太重要的过滤器或构建有效的操作,同时忽略特征图中的模式冗余。

在本论文中揭示了这样一种现象:一层内的许多特征图共享相似但不相同的模式。但是,很难确定具有相似模式的特征是否是冗余的或包含基本细节。因此,论文作者不是直接去除不确定的冗余特征,而是提出了一种基于分割的卷积操作,即 SPConv,以容忍具有相似模式但需要较少计算的特征。

具体来说,论文将输入特征图分为Representative部分和不Uncertain冗余部分,其中通过相对繁重的计算从代表性部分中提取内在信息,而对不确定冗余部分中的微小隐藏细节进行一些轻量级处理手术。为了重新校准和融合这两组处理过的特征,我们提出了一个无参数特征融合模块。此外,我们的 SPConv 被制定为以即插即用的方式替换 vanilla 卷积。在没有任何花里胡哨的情况下,基准测试结果表明,配备 SPConv 的网络在 GPU 上的准确性和推理时间上始终优于最先进的基线,FLOPs 和参数急剧下降。

2、特征冗余问题

然而,如上图所示,同一层的特征中存在相似模式,也就是说存在特征冗余问题。但同时,并未存在完全相同的两个通道特征,进而导致无法直接剔除冗余通道特征。 因此,可以选择一些有代表性的特征图来补充内在信息,而剩余的冗余只需要补充微小的不同细节。

3、SPConv详解

在现有的滤波器中,比如常规卷积、GhostConv、OctConv、HetConv均在所有输入通道上执行k*k卷积。然而,如上图所示,同一层的特征中存在相似模式,也就是说存在特征冗余问题。但同时,并未存在完全相同的两个通道特征,进而导致无法直接剔除冗余通道特征。

受此现象启发,作者提出将所有输入特征按比例拆分为两部分:

  1. Representative部分执行k*k卷积提取重要信息;
  2. Uncertain部分执行1*1卷积补充隐含细节信息。

因此该过程可以描述为(见SPConv的左侧部分),公式如下图所示:

3.1 Further Reduction for Reprentative

在将所有输入通道分成两个主要部分后,代表部分之间可能存在冗余。换句话说,代表通道可以分为几个部分,每个部分代表一个主要类别的特征,例如颜色和纹理。因此,我们在代表性通道上采用组卷积以进一步减少冗余,如图 2 的中间部分所示。我们可以将组卷积视为具有稀疏块对角卷积核的普通卷积,其中每个块对应于通道,并且分区之间没有连接。这意味着,在组卷积之后,我们进一步减少了代表性部分之间的冗余,同时我们还切断了可能不可避免地有用的跨通道连接。我们通过在所有代表性通道上添加逐点卷积来弥补这种信息丢失。与常用的组卷积后点卷积不同,我们在相同的代表性通道上进行 GWC 和 PWC。然后我们通过直接求和来融合这两个结果特征,因为它们具有相同的通道来源,从而获得了额外的分数(这里我们将组大小设置为 2)。所以方程2的代表部分可以表述为方程3:

3.2 Parameter Free Feature Fusion Module

到目前为止,我们已经将 vanilla 3×3 卷积拆分为两个操作:对于代表部分,我们进行 3×3 组卷积和 1×1 逐点卷积的直接求和融合,以抵消分组信息丢失;对于冗余部分,我们应用 1 × 1 内核来补充一些微小的有用细节。结果,我们得到了两类特征。因为这两个特征来自不同的输入通道,所以需要一种融合方法来控制信息流。与等式 2 的直接求和融合不同,我们为我们的 SP-Conv 设计了一个新颖的特征融合模块,无需导入额外的参数,有助于实现更好的性能。如图 2 右侧所示,

3.3 代码复现

import paddle
import paddle.nn as nn
def conv3x3(in_planes, out_planes, stride=1, groups=1, dilation=1):
 """3x3 convolution with padding"""
 return nn.Conv2D(in_planes, out_planes, kernel_size=3, stride=stride,
                     padding=dilation, groups=groups, dilation=dilation)
class SPConv_3x3(nn.Layer):
 def __init__(self, inplanes=32, outplanes=32, stride=1, ratio=0.5):
 super(SPConv_3x3, self).__init__()
 self.inplanes_3x3 = int(inplanes*ratio)
 self.inplanes_1x1 = inplanes - self.inplanes_3x3
 self.outplanes_3x3 = int(outplanes*ratio)
 self.outplanes_1x1 = outplanes - self.outplanes_3x3
 self.outplanes = outplanes
 self.stride = stride
 self.gwc = nn.Conv2D(self.inplanes_3x3, self.outplanes, kernel_size=3, stride=self.stride,
                             padding=1, groups=2)
 self.pwc = nn.Conv2D(self.inplanes_3x3, self.outplanes, kernel_size=1)
 self.conv1x1 = nn.Conv2D(self.inplanes_1x1, self.outplanes,kernel_size=1)
 self.avgpool_s2_1 = nn.AvgPool2D(kernel_size=2,stride=2)
 self.avgpool_s2_3 = nn.AvgPool2D(kernel_size=2, stride=2)
 self.avgpool_add_1 = nn.AdaptiveAvgPool2D(1)
 self.avgpool_add_3 = nn.AdaptiveAvgPool2D(1)
        self.bn1 = nn.BatchNorm2D(self.outplanes)
        self.bn2 = nn.BatchNorm2D(self.outplanes)
 self.ratio = ratio
 self.groups = int(1/self.ratio)
 def forward(self, x):
 # print(x.shape)
        b, c, _, _ = x.shape
        x_3x3 = x[:,:int(c*self.ratio),:,:]
        x_1x1 = x[:,int(c*self.ratio):,:,:]
        out_3x3_gwc = self.gwc(x_3x3)
 if self.stride ==2:
            x_3x3 = self.avgpool_s2_3(x_3x3)
        out_3x3_pwc = self.pwc(x_3x3)
        out_3x3 = out_3x3_gwc + out_3x3_pwc
        out_3x3 = self.bn1(out_3x3)
        out_3x3_ratio = self.avgpool_add_3(out_3x3).squeeze(axis=3).squeeze(axis=2)
 # use avgpool first to reduce information lost
 if self.stride == 2:
            x_1x1 = self.avgpool_s2_1(x_1x1)
        out_1x1 = self.conv1x1(x_1x1)
        out_1x1 = self.bn2(out_1x1)
        out_1x1_ratio = self.avgpool_add_1(out_1x1).squeeze(axis=3).squeeze(axis=2)
        out_31_ratio = paddle.stack((out_3x3_ratio, out_1x1_ratio), 2)
        out_31_ratio = nn.Softmax(axis=2)(out_31_ratio)
        out = out_1x1 * (out_31_ratio[:,:,1].reshape([b, self.outplanes, 1, 1]).expand_as(out_1x1))\
 + out_3x3 * (out_31_ratio[:,:,0].reshape([b, self.outplanes, 1, 1]).expand_as(out_3x3))
 return out
# paddle.summary(SPConv_3x3(), (1,32,224,224))
spconv = SPConv_3x3()
tmp = paddle.randn([1, 32, 224, 224])
conv_out1 = spconv(tmp)
print(conv_out1.shape) 
W0724 22:30:03.841145 13041 gpu_resources.cc:61] Please NOTE: device: 0, GPU Compute Capability: 7.0, Driver API Version: 11.2, Runtime API Version: 10.1
W0724 22:30:03.845882 13041 gpu_resources.cc:91] device: 0, cuDNN Version: 7.6.
[1, 32, 224, 224]
/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/paddle/nn/layer/norm.py:654: UserWarning: When training, we now always track global mean and variance.
 "When training, we now always track global mean and variance.")

4、消融实验

为验证所提方法的有效性,设置SPConv中的卷积核k=3,g=2,同时整个网络设置统一的全局超参数(不同阶段设置不同的会更优,但会过于精细)。

在小尺度数据集Cifar10、resnet18网络进行对比分析,为公平对比,所有实验均在含1个NVIDIA Tesla V100GPU的服务器上从头开始训练,且采用默认的数据增广与训练策略,不包含其他额外Tricks。

import paddle
from paddle.metric import Accuracy
from paddle.vision.transforms import Compose, Normalize, Resize, Transpose, ToTensor
from sp_resnet import resnet18_sp
callback = paddle.callbacks.VisualDL(log_dir='visualdl_log_res_sp')
normalize = Normalize(mean=[0.5, 0.5, 0.5],
                    std=[0.5, 0.5, 0.5],
 data_format='HWC')
transform = Compose([ToTensor(), Normalize(), Resize(size=(224,224))])
cifar10_train = paddle.vision.datasets.Cifar10(mode='train',
                                               transform=transform)
cifar10_test = paddle.vision.datasets.Cifar10(mode='test',
                                              transform=transform)
# 构建训练集数据加载器
train_loader = paddle.io.DataLoader(cifar10_train, batch_size=128, shuffle=True, drop_last=True)
# 构建测试集数据加载器
test_loader = paddle.io.DataLoader(cifar10_test, batch_size=128, shuffle=True, drop_last=True)
res_sp = paddle.Model(resnet18_sp(num_classes=10))
optim = paddle.optimizer.Adam(learning_rate=3e-4, parameters=res_sp.parameters())
res_sp.prepare(
 optim,
 paddle.nn.CrossEntropyLoss(),
 Accuracy()
 )
res_sp.fit(train_data=train_loader,
 eval_data=test_loader,
        epochs=10,
        callbacks=callback,
        verbose=1
 )
import paddle
from paddle.metric import Accuracy
from paddle.vision.transforms import Compose, Normalize, Resize, Transpose, ToTensor
from paddle.vision.models import resnet18
callback = paddle.callbacks.VisualDL(log_dir='visualdl_log_res_18')
normalize = Normalize(mean=[0.5, 0.5, 0.5],
                    std=[0.5, 0.5, 0.5],
 data_format='HWC')
transform = Compose([ToTensor(), Normalize(), Resize(size=(224,224))])
cifar10_train = paddle.vision.datasets.Cifar10(mode='train',
                                               transform=transform)
cifar10_test = paddle.vision.datasets.Cifar10(mode='test',
                                              transform=transform)
# 构建训练集数据加载器
train_loader = paddle.io.DataLoader(cifar10_train, batch_size=128, shuffle=True, drop_last=True)
# 构建测试集数据加载器
test_loader = paddle.io.DataLoader(cifar10_test, batch_size=128, shuffle=True, drop_last=True)
res_18 = paddle.Model(resnet18(num_classes=10))
optim = paddle.optimizer.Adam(learning_rate=3e-4, parameters=res_18.parameters())
res_18.prepare(
 optim,
 paddle.nn.CrossEntropyLoss(),
 Accuracy()
 )
res_18.fit(train_data=train_loader,
 eval_data=test_loader,
        epochs=10,
        callbacks=callback,
        verbose=1
 )

5、实验结果分析

最后,我们再来看一下消融实验结果,见下图。可以看到:

  • 添加了SPConV模块的ResNet18效果反而不如原始的ResNet18

在原作中,作者给出了ResNet20、VGG16在数据集Cifar10上的对比结果,原因也可能在于本实验中模型迭代次数不够,但是相比来看,特征图在进行了去冗余操作之后(类似于剪枝),精度下降似乎是正确的。

6、总结

在该文中,作者重新对常规卷积中的信息冗余问题进行了重思考,为缓解该问题,作者提出了一种新颖的SPConv,它将输入特征拆分为两组不同特征并进行不同的处理,最后采用简化版SK进行融合。最后作者通过充分的实验分析说明了所提方法的有效性,在具有更高精度的时候具有更快的推理速度、更少的FLOPs与参数量。

所提SPConv是一种“即插即用”型单元,它可以轻易与其他网络架构相结合,同时与当前主流模型压缩方法互补,如能精心组合设计,有可能得到更轻量型的模型。

7、参考资料

即插即用!北邮&南开大学开源SPConv:精度更高、速度更快的卷积

Split to Be Slim: An Overlooked Redundancy in Vanilla Convolution

 

点击关注,第一时间了解华为云新鲜技术~文章来源地址https://www.toymoban.com/news/detail-423767.html

到了这里,关于Split to Be Slim: 论文复现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 论文摘要生成器手机版?论文修改神器

    宝子们在做科学基金项目申请书时,特别强调的一点是宝子们必须明确说明课题相对于现有研究成果的 独特学术价值和应用潜力 。这意味着, 所提出的学术和应用价值不应是泛泛之谈,而应突出其独特性,这正是通过深入分析学术历史和最新研究动态得出的。 因此,为了有

    2024年04月25日
    浏览(52)
  • 基于BERT-PGN模型的中文新闻文本自动摘要生成——文本摘要生成(论文研读)

    基于BERT-PGN模型的中文新闻文本自动摘要生成(2020.07.08) 针对文本自动摘要任务中生成式摘要模型对句子的上下文理解不够充分、生成内容重复的问题,基于BERT 和指针生成网络(PGN),提出了一种面向中文新闻文本的生成式摘要模型——BERT-指针生成网络(BERTPGN)。首先,

    2024年02月01日
    浏览(52)
  • 数学建模论文写作学习——论文题目、关键词、摘要写作学习

    目录 一、论文题目 二、 三、摘要内容(具有独立性、代表性) 第一部分:摘要前言 第二部分:摘要正文 ①简述问题 ②建模思路(一定写关键步骤,不要写思维引导) ③模型求解 ④结果分析(联系赛题) 第三部分:摘要结尾 ①应尽量涵盖论文研究的主要对象或研

    2024年02月08日
    浏览(61)
  • ResearchRabbit.ai: 学术论文摘要研究工具

    【产品介绍】   ResearchRabbit是一个帮助研究人员发现、跟踪和分享学术论文的平台。可以根据你的兴趣和收藏提供个性化的推荐和摘要,并且可以让你可视化论文和作者之间的网络关系。   Researchrabbit.ai是一个基于人工智能的文献搜索和管理工具,它可以帮助你:   Resea

    2024年02月05日
    浏览(44)
  • 软件工程顶会——ICSE '24 论文清单、摘要

    1、A Comprehensive Study of Learning-based Android Malware Detectors under Challenging Environments 近年来,学习型Android恶意软件检测器不断增多。这些检测器可以分为三种类型:基于字符串、基于图像和基于图形。它们大多在理想情况下取得了良好的检测性能。然而,在现实中,检测器常常面临

    2024年03月08日
    浏览(55)
  • 【论文阅读】Dynamic Split Computing for Efficient Deep Edge Intelligence

    作者:Arian Bakhtiarnia, Nemanja Milošević, Qi Zhang, Dragana Bajović, Alexandros Iosifidis 发表会议: ICML 2022 DyNN Workshop ICASSP 2023 发表单位: ∗DIGIT, Department of Electrical and Computer Engineering, Aarhus University, Denmark. †Faculty of Sciences, University of Novi Sad, Serbia. ‡Faculty of Technical Sciences, University of N

    2024年02月11日
    浏览(58)
  • [晓理紫]每日论文推送(有中文摘要,源码或项目地址)--机器人、视觉相关

    VX关注{晓理紫},每日更新论文,如感兴趣,请转发给有需要的同学,谢谢支持 VX关注晓理紫,并留下邮箱可免费获取每日论文推送服务 分类: 大语言模型LLM 视觉模型VLM 扩散模型 视觉导航 具身智能,机器人 强化学习 开放词汇,检测分割 作者: Frank Regal, Chris Suarez, Fabian Parr

    2024年01月18日
    浏览(54)
  • ]每日论文推送(有中文摘要或代码或项目地址)---强化学习,机器人,视觉导航

    [晓理紫]每日论文推送(有中文摘要或代码或项目地址) 每日更新论文,请转发给有需要的同学 [晓理紫] VX关注晓理紫,获取每日新论文 VX关注晓理紫,并留下邮箱可免费获取每日论文推送服务 {晓理紫}喜分享,也很需要你的支持,喜欢留下痕迹哦! 大语言模型LLM 视觉模型VL

    2024年01月19日
    浏览(48)
  • 【论文指导】计算机毕业设计,摘要如何写?15篇案例把你安排明白

    作者主页 :Designer 小郑 作者简介 :Java全栈软件工程师一枚,来自浙江宁波,负责开发管理公司OA项目,专注软件前后端开发(Vue、SpringBoot和微信小程序)、系统定制、远程技术指导。CSDN学院、蓝桥云课认证讲师,全栈领域优质创作者。热爱技术、专注业务、开放合作、乐

    2024年02月05日
    浏览(46)
  • 【论文阅读】DEPCOMM:用于攻击调查的系统审核日志的图摘要(S&P-2022)

    Xu Z, Fang P, Liu C, et al. Depcomm: Graph summarization on system audit logs for attack investigation[C]//2022 IEEE Symposium on Security and Privacy (SP). IEEE, 2022: 540-557. 1 摘要 ​ 提出了 DEPCOMM,这是一种图摘要方法,通过将大图划分为以进程为中心的社区并为每个社区提供摘要,从依赖图生成摘要图。每个社

    2024年02月13日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包