新宝6娱乐app下载-新宝6手机app下载-新宝6官网 > SEO算法 > 专栏 深度学习算法优化系列七 ICCV 2017的一篇模型剪枝论文也是2019年

专栏 深度学习算法优化系列七 ICCV 2017的一篇模型剪枝论文也是2019年

admin SEO算法 2020年02月11日

  原标题:专栏 深度学习算法优化系列七 ICCV 2017的一篇模型剪枝论文,也是2019年众多开源剪枝项目的理论基础

  具体原理已经讲过了,见上回的推文。 深度学习算法优化系列七 ICCV 2017的一篇模型剪枝论文,也是2019年众多开源剪枝项目的理论基础 。这篇文章是从源码实战的角度来解释模型剪枝,源码来自:。我这里主要是结合源码来分析每个模型的具体剪枝过程,新宝6娱乐app下载-新宝6手机app下载-新宝6官网希望能给你剪枝自己的模型一些启发。

  论文的想法是对于每一个通道都引入一个缩放因子 ,然后和通道的输出相乘。接着联合训练网络权重和这些缩放因子,最后将小缩放因子的通道直接移除,微调剪枝后的网络,特别地,目标函数被定义为:

  其中 代表训练数据和标签, 是网络的可训练参数,第一项是CNN的训练损失函数。 是在缩放因子上的乘法项, 是两项的平衡因子。论文的实验过程中选择 ,即 正则化,这也被广泛的应用于稀疏化。次梯度下降法作为不平滑(不可导)的L1惩罚项的优化方法,另一个建议是使用平滑的L1正则项取代L1惩罚项,尽量避免在不平滑的点使用次梯度。

  在 main.py 的实现中支持了稀疏训练,其中下面这行代码即添加了稀疏训练的惩罚系数 ,注意 是作用在BN层的缩放系数上的:

  最后训练,测试,保存Basline模型(包含VGG16,Resnet-164,DenseNet40)的代码如下,代码很常规就不过多解释这一节了:

  加载需要剪枝的模型,也即是稀疏训练得到的BaseLine模型,代码如下,其中 args.depth 用于指定VGG模型的深度,一般为 16 和 19 :

  首先确定剪枝的全局阈值,然后根据阈值得到剪枝后的网络每层的通道数 cfg_mask ,这个 cfg_mask 就可以确定我们剪枝后的模型的结构了,注意这个过程只是确定每一层那一些索引的通道要被剪枝掉并获得 cfg_mask ,还没有真正的执行剪枝操作。我给代码加了部分注释,应该不难懂。

  在预剪枝之后我们获得了每一个特征图需要剪掉哪些通道数的索引列表,接下来我们就可以按照这个列表执行剪枝操作了。剪枝的完整代码如下:

  # 注意卷积核Tensor维度为[n, c, w, h],两个卷积层连接,下一层的输入维度n就等于当前层的c

  # 注意卷积核Tensor维度为[n, c, w, h],两个卷积层连接,下一层的输入维度n就等于当前层的c

  到这里VGG16就被剪枝完了,剪枝完成后我们还需要对这个新模型进行Retrain,仍然是使用 main.py 即可,参数改一下,命令如下:

  这样就可以获得最终的模型了,VGG16在CIFAR10/100上剪枝并Retrain后最终的测试结果为:

  在 深度学习算法优化系列七 ICCV 2017的一篇模型剪枝论文,也是2019年众多开源剪枝项目的理论基础 提到对于ResNet和DenseNet这种每一层的输出会作为后续多个层的输入,且其BN层是在卷积层之前,在这种情况下,稀疏化是在层的输入末端得到的,一个层选择性的接受所有通道的子集去做下一步的卷积运算。为了在测试时节省参数和运行时间,需要放置一个通道选择层鉴别出重要的通道。再通俗的解释一下通道鉴别层的作用吧,对于ResNet的BN层来讲,如果这个BN层后面放置了通道鉴别层就不需要做剪枝了,通道鉴别层都是放在每一个残差模块的第一个BN层后面以及整个网络的最后一个BN层后面,这是因为这几个层的输入不仅仅和一个层相关还和多个层相关。所以为了保持网络的泛化能力,这几个BN层不剪枝,只剪枝其他的BN层。

  从BN层的输出中选择通道。它应该直接放在BN层之后,此层的输出形状由exes中的1的个数决定

  使用长度和通道数相同的全1向量初始化indexes, 剪枝过程中,将要剪枝的通道对应的indexes位置设为0

  将通道鉴别层按照前面介绍的方法放入ResNet中,代码在 models/presnet.py 中,如下注释部分是在原始的ResNet 部分BN层后面放入了通道鉴别层,其他都和原始模型一样。代码如下:

  和VGGNet几乎一致,新宝6娱乐app下载-新宝6手机app下载-新宝6官网只关注一个核心改变之处,就是正式剪枝的函数多了一点,这部分代码在根目录下的 resprune.py 中,我贴一下相比于VGG16的变化之处的代码,也就是正式剪枝时的代码,有注释,不难:

  前面说清楚了VGGNet和ResNet的剪枝,对于DenseNet的剪枝我们只需要关注和上面两个剪枝的区别即可。然后观察了一下,和ResNet完全一致,所以就不再赘述了。这里只看一下结果测试:

  上面介绍了3个主流的Backbone网络VGG16,Resnet164,DenseNet40的剪枝方法和细节,这三个网络在CIFAR10/100数据上保证精度不掉(多数情况还提高了精度)的情况下可以剪掉原始模型一半以上的参数,充分证明了这个算法的有效性,并且也是工程友好的。另外这个剪枝代码配合pytorch-onnx-移动端框架也是比较好移植的。

标签: