PocketFlow文档(三)

Channel Pruning

Introduction

通道剪枝是一种结构模型压缩方法,它不仅可以压缩模型大小,而且可以直接提高推理速度。PocketFlow使用(He et al., 2017)中提出的信道修剪算法对卷积层的每个信道进行一定比例的修剪,具体方法请参考 channel pruning paper。为了获得更好的性能和鲁棒性,我们对算法的某些部分进行了修改,以获得更好的结果。

PocketFlow为了获得更好的性能,可以利用reinforcement learning来寻找更好的压缩比(He et al., 2018)。用户还可以使用distilling(Hinton et al., 2015)和group tuning function来提高压缩后的精度。组调优是指将一定数量的层设置为组,然后依次对每个组进行修剪和细化/再培训。例如,我们可以将每3层设置为一个组,然后修剪前3层。在此之后,对整个模型进行精细/再培训,并修剪接下来的3层,以此类推。实验证明,在一定的压缩比下,提取和群优化(Distilling and group tunin)是提高压缩精度的有效方法。

Pruning Option

通道修剪的代码位于目录./learners/channel_pruning。使用通道修剪。用户可以设置--learners to channel。通道修剪支持cp_prune_option选项设置的3种修剪方式。

Uniform Channel Pruning

一种是均匀层剪枝,即用户可以通过--cp_prune_option=uniform来设置每个被剪枝的卷积层的一个uniform pruning比例,并设置这个比例(例如:--cp_uniform_preserve_ratio=0.5)。请注意,对于一个层,如果该层和前一层的修剪比都是0.5,那么实际保留的FLOPs是原始FLOPs的1/4。因为通道修剪只修剪卷积的c_out通道和下一个卷积的c_in通道,如果c_in和c_out通道都被修剪0.5,只保留原来计算成本的1/4。对于没有residual blocks的逐层卷积网络,如果用户将cp_uniform_preserve_ratio设置为0.5,则整个模型将是原始模型的0.25计算。然而对于residual networks,一些卷积只能对其c_in或c_out通道进行修剪,这意味着总的预估计算比可能远远大于0.25。

Example:

$ ./scripts/run_seven.sh nets/resnet_at_cifar10_run.py \
    --learner channel \
    --batch_size_eval 64 \
    --cp_uniform_preserve_ratio 0.5 \
    --cp_prune_option uniform \
    --resnet_size 20

List Channel Pruning

另一个修剪选项是使用指定的ratio.list的比率来修剪相应的层。该文件名可以通过--cp_prune_list_file选项设置。the ratio value必须用逗号分隔。用户可以设置--cp_prune_option=list来按列表比例修剪模型。

Example: Add list 1.0, 0.1875, 0.1875, 0.1875, 0.1875, 0.1875, 0.1875, 0.1875, 1.0, 0.25, 1.0, 0.25, 0.21875, 0.21875, 0.21875, 1.0, 0.5625, 1.0, 0.546875, 0.546875, 0.546875, 1 in ./ratio.list

$ ./scripts/run_seven.sh nets/resnet_at_cifar10_run.py \
    --learner channel \
    --batch_size_eval 64 \
    --cp_prune_option list \
    --cp_prune_list_file ./ratio.list \
    --resnet_size 20

Automatic Channel Pruning

最后一个剪枝选项是通过强化学习搜索更好的剪枝率,您只需要给出一个值,该值表示您希望压缩模型保留的total FLOPs/Computation。

您可以设置--cp_prune_option=auto并设置保存比率数,例--cp_preserve_ratio=0.5。用户还可以使用cp_nb_rlouts_min来控制强化学习warm up迭代,这意味着RL代理在迭代之后开始学习,默认值为50。用户还可以使用cp_nb_rlouts_min来控制要搜索的总迭代RL代理,默认值为200。如果用户想要控制代理的其他参数,请参考加reinforcement component page。

Example:

$ ./scripts/run_seven.sh nets/resnet_at_cifar10_run.py \
    --learner channel \
    --batch_size_eval 64 \
    --cp_preserve_ratio 0.5 \
    --cp_prune_option auto \
    --resnet_size 20

Channel pruning parameters

通道剪枝的实现采用Lasso算法进行通道选择,线性回归进行特征映射重构。在这两个阶段中,对feature map进行采样,以降低计算成本。用户可以使用--cp_nb_points_per_layer来设置每一层有多少个采样点,默认值是10。对于某些数据集,如果图像包含太多的零像素,eg.黑色),值应该更大。用户还可以通过cp_nb_batch设置使用多少批进行通道选择和特性重构,默认值为60。cp_nb_batch的值过小可能会导致过拟合,值大可能会降低求解速度,所以一个好的值取决于网络和数据集。为了更实际的使用,用户可以考虑使每一层的通道数是移动设备快速推理的四倍。在这种情况下,用户可以将--cp_quadruple设置为True,使压缩的模型具有四倍数量的通道。

Distilling

在大多数情况下,利用PocketFlow进行分类是提高压缩模型最终精度的有效方法。用户可以设置--enbl_dst=True以启用蒸馏。

Group Tuning

如上所述,PocketFlow团队提出了组优化,发现它对于提高模型压缩的性能非常有用。在PocketFlow中,用户可以设置--cp_finetune=True来启用组finetuning,并通过--cp_list_group设置组号,默认值为1000。在小值和大值之间存在权衡,因为如果值为1,Pocketflow会根据每一层对卷积和finetune/retrain进行修剪,效果可能会更好,但会更耗时。如果我们把值设大,函数的效率就会降低。用户还可以通过cp_nb_iters_ft_ratio设置finetune迭代次数, cp_nb_iters_ft_ratio是finetuning中使用的总迭代次数的比率。finetuning的学习率可以通过cp_lrn_rate_ft来设置。

 

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值