前言:Network Slimming剪枝过程让如下
1. 稀疏化
2. 剪枝
3. 反复迭代这个过程
一、稀疏化:
通过Network Slimming 的核心思想是:添加L1正则来约束BN层系数,从而剪掉那些贡献比较小的通道channel
原理如下:BN层的计算是这样的:
上边介绍了,Network Slimming的核心思想是剪掉那些贡献比较小的通道channel,它的做法是从BN层下手。BN层的计算公式如下:
通过BN层的计算公式可以看出每个channe的Zout的大小和系数γ正相关,因此我们可以拿掉哪些γ-->0的channel,但是由于正则化,我们训练一个网络后,bn层的系数是正态分布的。这样的话,0附近的值则很少,那剪枝的作用就很小了。因此要先给BN层加上L1正则化进行一步稀疏训练(为什么要用L1正则化可以看该博客:l1正则与l2正则的特点是什么,各有什么优势? - 知乎)。
为BN层加入L1正则化后,损失函数公式为:
上面第一项是正常训练的loss函数,第二项是约束对于L1正则化,g(s)=|s|,λ是正则系数,引入L1正则来控制γ, 要把稀疏表达加在γ 上, 得到每个特征的重要性λ
- 每个通道的特征对应的权重是 γ - 稀疏表达也是对 γ 来说的, 所以正则化系数 λ 也是针对 γ, 而不是 W- 稀疏化后, 做γ 值的筛选
因此在进行反向传播时候:????′=∑????′+????∑????′(????)=∑????′+????∑|????|′=∑????′+????∑????????????????(????)
那如何把程序加到yolov5呢?
在yolov5 train.py的程序中找到反向传播部分程序:
1.1 稀疏训练核心代码
将scaler.scale(loss).backward()注释,并添加下方代码:
代码如下:
# Backward# scaler.scale(loss).backward()loss.backward()# # ============================= sparsity training ========================== #srtmp = opt.sr*(1 - 0.9*epoch/epochs) # opt.sr=0.0001 随着epoch增多,把srtmp减小if opt.st: # 默认是true train with L1 sparsity normalization ignore_bn_list = []for k, m in model.named_modules():# print(
ame: {}, module: {}.format(k,m))