剪枝论文一(Network Slimming)
本文介绍一种经典的模型压缩方法Network Slimming
,可以实现:
- 减小模型大小
- 减少运行时的内存占用
- 在不影响精度的同时,降低计算操作数
论文中提供的示意图如下,可以看到左侧BN
层中橙色的神经元权重较小,因此剪枝之后就去掉了这些层的连接。论文的思路即通过去掉BN
层中权重较小的神经元来达到精简网络的目的。
实现去掉权重较小的神经元的流程如下:
1. sparsity regularization
论文提出,在训练的时候增加稀疏正则化方法。
主要作用:令BN
层中权值为0
的神经元尽可能多,以达到更好的剪枝效果。
实现方式:添加一个新的loss
,其大小为BN
层中所有神经元的权值和,使用梯度下降法使这个新的loss
尽可能小。
# sparsity-induced惩罚项的附加次梯度下降
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
2. 划分保留层和剪枝层
步骤为:
- 给定要保留层的比例,记下所有
BN
层大于该比例的权重。 - 根据比例设置阈值,根据阈值建立一个
mask
,大于阈值的部分为1
,小于阈值的部分为0
。 - 利用
mask
提取保留的神经元。
# 将这些权重排序
y, i = torch.sort(bn) # 这些权重排序
thre_index = int(total * args.percent) # 要保留的数量
thre = y[thre_index] # 最小的权重值# ===================================预剪枝====================================
pruned = 0
cfg = []
cfg_mask = []
for k, m in enumerate(model.modules()):if isinstance(m, nn.BatchNorm2d):weight_copy = m.weight.data.abs().clone()# 小于权重thre的为0,大于的为1,即保留的部分mask = weight_copy.gt(thre).float().cuda()# 统计被剪枝的权重的总数pruned = pruned + mask.shape[0] - torch.sum(mask)# 权重和偏置分别对应相乘m.weight.data.mul_(mask) m.bias.data.mul_(mask)# 记录每个batchnorm保留的权重和权重数cfg.append(int(torch.sum(mask))) cfg_mask.append(mask.clone())print('layer index: {:d} \t total channel: {:d} \t remaining channel: {:d}'.format(k, mask.shape[0], int(torch.sum(mask))))elif isinstance(m, nn.MaxPool2d):cfg.append('M')
3. 进行BN层的剪枝
进行BN
层的剪枝,即丢弃小于阈值的参数;
# ===================================正式剪枝====================================
# 层数
layer_id_in_cfg = 0
start_mask = torch.ones(3)
end_mask = cfg_mask[layer_id_in_cfg]
for [m0, m1] in zip(model.modules(), newmodel.modules()):# 对BN层进行剪枝if isinstance(m0, nn.BatchNorm2d):# 获取大于0的所有数据的索引,使用squeeze变成向量idx1 = np.squeeze(np.argwhere(np.asarray(end_mask.cpu().numpy())))if idx1.size == 1: # 只有一个要变成数组的1个idx1 = np.resize(idx1,(1,))# 用经过剪枝后的层参数的替换原来的# x = (x - mean)/war*weight + datam1.weight.data = m0.weight.data[idx1.tolist()].clone()m1.bias.data = m0.bias.data[idx1.tolist()].clone()m1.running_mean = m0.running_mean[idx1.tolist()].clone()m1.running_var = m0.running_var[idx1.tolist()].clone()# 下一层layer_id_in_cfg += 1# 当前在处理的层的maskstart_mask = end_mask.clone()# 全连接层不做处理if layer_id_in_cfg < len(cfg_mask):end_mask = cfg_mask[layer_id_in_cfg]
4. 进行卷积层剪枝
根据前后BN
层的保留层,可以计算得到卷积层保留的卷积核大小(上层BN
层输出,下层BN
层输入),保留前后BN
的对应保留的元素,其余剪枝。
# 对卷积层进行剪枝elif isinstance(m0, nn.Conv2d):# 上一层BN层对应的输出mask为start_maskidx0 = np.squeeze(np.argwhere(np.asarray(start_mask.cpu().numpy())))# 下一层BN层对应的输入mask为start_maskidx1 = np.squeeze(np.argwhere(np.asarray(end_mask.cpu().numpy())))print('In shape: {:d}, Out shape {:d}.'.format(idx0.size, idx1.size))if idx0.size == 1:idx0 = np.resize(idx0, (1,))if idx1.size == 1:idx1 = np.resize(idx1, (1,))# 剪枝[c_out, c_int, k, k]w1 = m0.weight.data[:, idx0.tolist(), :, :].clone()w1 = w1[idx1.tolist(), :, :, :].clone()m1.weight.data = w1.clone()
5. 对FC层进行剪枝
由于FC
层的输出是固定的(分类类数),因此只对FC
层的输入维度进行剪枝,也是根据上一层BN
层的输出,对应保留的元素,其余剪枝。
# 对全连接层进行剪枝elif isinstance(m0, nn.Linear):idx0 = np.squeeze(np.argwhere(np.asarray(start_mask.cpu().numpy())))if idx0.size == 1:idx0 = np.resize(idx0, (1,))# 剪枝m1.weight.data = m0.weight.data[:, idx0].clone()m1.bias.data = m0.bias.data.clone()
源代码
剪枝论文一(Network Slimming)相关推荐
- Network Slimming——有效的通道剪枝方法(Channel Pruning)
"Learning Efficient Convolutional Networks through Network Slimming"这篇文章提出了一种有效的结构性剪枝方法,即规 ...
- 【剪枝算法】通过网络瘦身学习高效的卷积网络Learning Efficient Convolutional Networks through Network Slimming论文翻译
此论文翻译仅仅用于自己方便学习.译文来自其他处. 在许多实际应用中部署深度卷积神经网络(CNN)很大程度上受到其计算成本高的限制.在本文中,我们提出了一种新的CNNs学习方案,能同时1)减小模型大小; ...
- 模型剪枝经典论文解读:《Learning Efficient Convolutional Networks through Network Slimming》
Learning Efficient Convolutional Networks through Network Slimming 摘要: CNN在落地中的部署,很大程度上受到其高计算成本的限制.在 ...
- 论文复现:Learning Efficient Convolutional Networks through Network Slimming
论文核心 论文提出了一种结构化剪枝策略,剪枝对象为 channel ,对 channel 重要性的评价标准使用的是 Batch Normalization 层中的缩放因子,这不会给网络带来额外的开销. ...
- vision transformer 剪枝论文汇总
Vision Transformer Pruning 这篇论文的核心思想很简单,就是剪维度,也就是说剪的是这个d. 具体方法就是通过一个gate,如图中的dimension pruning,输出0或者 ...
- Network Slimming
Network Slimming-Learning Efficient Convolutional Networks through Network Slimming](https://arxiv.o ...
- 通过Network Slimming学习高效卷积网络
1.文章信息 本文是2017年发表在计算机视觉领域顶会ICCV的一篇文章,被引量已经达到了1214次,是引用比较广泛的一种模型剪枝方法,作者来自清华大学.英特尔中国实验室.复旦大学和科内尔大学. 2. ...
- 微软研究院研究员Ryan Beckett 博士论文《Network Control Plane Synthesis and Verification》下载—2018ACM最佳博士论文题目奖
欢迎关注微信公众号[计算机视觉联盟] 获取更多前沿AI.CV资讯 论文下载 关注微信公众号[计算机视觉联盟],回复关键词[Ryan]即可下载全文! 论文封面 论文目录 目前,Beckett 是微软研究 ...
- 【论文精读1】基于BN的模型剪枝-Learning Efficient Convolution Networks through Network Slimming
原论文下载地址 论文思想:先结构剪枝后微调.
最新文章
- 几十亿打水漂!世界最大移动通信展MWC因疫情33年来首次取消,多方损失惨重...
- hybriddb mysql移植_HybridDB for MySQL 实现在线与离线数据分离的实践
- 修改mysql导入sql大小限制_修改phpMyAdmin导入SQL文件的大小限制
- Zookeeper集群的搭建及遇到的问题
- python的md5
- Linux操作系统定时任务系统 Cron
- linux 命令案例学习——文件搜索
- ad中电容用什么封装_【AD封装】VH3.96mm插件座子(带3D)
- WinCEService项目
- bat文件备份MySQL数据库
- 特征图注意力_CV注意力机制论文阅读笔记
- 现代浏览器:WebM 格式/网络视频的广泛应用
- 电商数据分析常见的指标汇总
- 怎么打开和修改dll文件的?如何调用和编辑?
- /sdcard目录详解
- CF1428F-Fruit Sequences
- java 消息摘要_java – 使用BouncyCastle签名消息摘要
- linux交换分区的命令,LInux下的交换分区以及相关查看命令
- 【宝贝,既然你爱了,那就敞开心扉】
- 脑机接口科普0003——Hans Berger