• 模型剪枝


    模型剪枝

    一. 基础回顾

    1. 首先回顾一下卷积的过程,输入:(x=[16,3,224,224]),卷积核:(k=[in\_chs=3,out\_chs=12,strides=1,kernel=1...]),输出;(y=[16,12,224,224])。对于剪枝(通道剪枝)而言,修剪的是 (out\_chs) 这个分支。

    2. 当修剪卷积通道之后,相应的后面卷积都应对应的调整。例如:(conv\_1=[in\_chs=3,out\_chs=12],conv\_2=[in\_chs=12,out\_chs=64]),对conv_1进行修剪四个通道,对应conv2也随之变化:(conv\_1=[in\_chs=3,out\_chs=8],conv\_2=[in\_chs=8,out\_chs=64])。当然修剪的通道具有Index信息,在操作过程得保留。

    3. 再回顾一下BN层的操作流程BN详解(公式+代码),这里的 (gamma) 表示尺度(乘积),当这个值很小时,BN的输出就很小。在剪枝过程可以把 (gamma) 看做是重要程度衡量参数。例如:(conv\_1=[in\_chs=3,out\_chs=12],BN=[12],conv\_2=[in\_chs=12,out\_chs=64]),对BN中的 (gamma) 进行排序,修剪掉最小的四个通道,那么结果为:(conv\_1=[in\_chs=3,out\_chs=8],BN=[8],conv\_2=[in\_chs=8,out\_chs=64]),同理修剪的时候是根据index进行的。

    4. (1)都是自己设计小网络然后进行蒸馏+量化增加精度和加速。(2)大网络进行剪枝,小网络剪枝效果很差。

    二. Pruning Filters for Efficient ConvNets

    论文:链接地址

    代码:链接地址

    论文比较简单,直接按照上面第一、第二点进行即可,具体操作可阅读源代码

    三. Learning Efficient Convolutional Networks through Network Slimming

    论文:链接地址

    代码:链接地址

    主要使用稀疏训练和BN层剪枝

    # 直接在原始梯度基础上增加L1梯度反向传播
    def updateBN():
        for m in model.modules():
            if isinstance(m, nn.BatchNorm2d):
                m.weight.grad.data.add_(args.s*torch.sign(m.weight.data))  # L1梯度反向传播替换
    # 也可使用torch hook机制修改层的梯度计算方式
    ******
    

    BN层的剪枝参考上面第三点方式进行

    关于Resnet等skip-connect的剪枝:

    # 预先定义channel_selection层,前向传播的时候不影响任何操作,在进行剪枝的时候如下所示
    # 不影响上一层的结果,但会选择通道和下一层对应
    if isinstance(old_modules[layer_id + 1], channel_selection):
        # If the next layer is the channel selection layer, 
        # then the current batchnorm 2d layer won't be pruned.
        m1.weight.data = m0.weight.data.clone()
        m1.bias.data = m0.bias.data.clone()
        m1.running_mean = m0.running_mean.clone()
        m1.running_var = m0.running_var.clone()
    
        # 这里是核心,将selectlayer里面的index更改为下一层的idx
        # We need to set the channel selection layer.
        m2 = new_modules[layer_id + 1]
        m2.indexes.data.zero_()
        m2.indexes.data[idx1.tolist()] = 1.0
    
        layer_id_in_cfg += 1
        start_mask = end_mask.clone()
        if layer_id_in_cfg < len(cfg_mask):
        	end_mask = cfg_mask[layer_id_in_cfg]
    

    四. Rethinking the Value of Network Pruning

    论文:链接地址

    代码:链接地址

    论文最主要表达的思想是:大模型训练->剪枝->微调->剪枝->微调->.....->结束,这种方式不一定比直接使用小模型进行训练效果好。

    那么问题来了?

    既然直接训练小模型比剪枝的效果更好,为什么还要剪枝这项比较复杂的工作呢?

    当前笔者查到的论文,基本都是这个 Eric 大神的作品,当前这篇推翻剪枝工作的论文也是其作品。

    到现在为止,终于发现剪枝在工作中算小众方向的原因了

  • 相关阅读:
    emWin 界面切换注意事项
    emWin 工程之汉字显示
    emWin 使用 GUIBuilder 放置标题 TEXT 注意
    【转】系统调用和驱动程序中相应函数的参数对应关系
    主机 & 虚拟机 & 开发板 相互通信
    电脑通过网口连接开发板
    【转】ARM交叉编译工具链
    【转】vi 写完文件保存时才发现是 readonly
    【转】ubuntu 12.04下如何开启 NFS 服务 & 设置
    安装完打开 eclipse 提示 JVM 版本较低
  • 原文地址:https://www.cnblogs.com/wjy-lulu/p/14143003.html
Copyright © 2020-2023  润新知