本文主要是介绍【网络裁剪】——通道剪枝问答/code解读,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
亮点:原理,code
论文和原理和参考上一篇博客:Learning Efficient Convolutional Networks through Network Slimming
- 通道裁剪在训练时需要做什么?
在训练的时候需要训练一个通道稀疏特性的模型,实现通道稀疏化需要将和一个通道有关联的所有输入和输出的连接都剪掉。
- 其如何训练一个通道稀疏的模型的?
利用BN层的缩放因子,引入缩放因子正则项之后,我们得到的模型中许多缩放因子都会趋于0。
code:
# ***********************稀疏训练(对BN层γ进行约束)**************************
def updateBN():for m in model.modules():if isinstance(m, nn.BatchNorm2d):if hasattr(m.weight, 'data'):m.weight.grad.data.add_(args.s * torch.sign(m.weight.data)) # L1正则optimizer.zero_grad()
loss.backward()# ***********************稀疏训练(对BN层γ进行约束)**************************
if args.sr:updateBN()
可以看到只是在训练的时候增加了一个updateBN,该函数就是对batchnorm的权重做L1正则化,而L1正则化可以使batchnorm.weight更稀疏化,也就是weight有更多的0。这也就是channel剪枝的目的。
- 为什么L1正则化会产生一个稀疏化的模型
参考自:l1正则与l2正则的特点是什么,各有什么优势?
L1-regularization 和 L2-regularization 便都是我们常用的正则项,两者公式的例子分别如下:
L1 正则项和 L2 正则项来进行求导,可得。
假设只有一个w1参数,画出L1,L2及其倒数的图:
于是会发现,在梯度更新时,不管 L1 的大小是多少(只要不是0)梯度都是1或者-1,所以每次更新时,它都是稳步向0前进。
而看 L2 的话,就会发现它的梯度会越靠近0,就变得越小。
也就是说加了 L1 正则的话基本上经过一定步数后很可能变为0,而 L2 几乎不可能,因为在值小的时候其梯度也会变小。于是也就造成了 L1 输出稀疏的特性。
所有上面的解释都是只有正则项时,那样会造成迭代一定的步数,权重为0.但是真实的是正则化只是一个补充项。让权重努力的向0靠拢
m.weight.grad.data.add_(args.s * torch.sign(m.weight.data)) # L1正则
- 裁剪后的模型需要微调吗?
原文的路线是可以有fine-tune的。
在cifar10这种小数据集上,不需要fine-tune效果也很好。
这篇关于【网络裁剪】——通道剪枝问答/code解读的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!