A Closer Look at Structured Pruning for Neural Network Compression

Overview

A Closer Look at Structured Pruning for Neural Network Compression

Code used to reproduce experiments in https://arxiv.org/abs/1810.04622.

To prune, we fill our networks with custom MaskBlocks, which are manipulated using Pruner in funcs.py. There will certainly be a better way to do this, but we leave this as an exercise to someone who can code much better than we can.

Setup

This is best done in a clean conda environment:

conda create -n prunes python=3.6
conda activate prunes
conda install pytorch torchvision -c pytorch

Repository layout

-train.py: contains all of the code for training large models from scratch and for training pruned models from scratch
-prune.py: contains the code for pruning trained models
-funcs.py: contains useful pruning functions and any functions we used commonly

CIFAR Experiments

First, you will need some initial models.

To train a WRN-40-2:

python train.py --net='res' --depth=40 --width=2.0 --data_loc= --save_file='res'

The default arguments of train.py are suitable for training WRNs. The following trains a DenseNet-BC-100 (k=12) with its default hyperparameters:

python train.py --net='dense' --depth=100 --data_loc= --save_file='dense' --no_epochs 300 -b 64 --epoch_step '[150,225]' --weight_decay 0.0001 --lr_decay_ratio 0.1

These will automatically save checkpoints to the checkpoints folder.

Pruning

Once training is finished, we can prune our networks using prune.py (defaults are set to WRN pruning, so extra arguments are needed for DenseNets)

python prune.py --net='res'   --data_loc= --base_model='res' --save_file='res_fisher'
python prune.py --net='res'   --data_loc= --l1_prune=True --base_model='res' --save_file='res_l1'

python prune.py --net='dense' --depth 100 --data_loc= --base_model='dense' --save_file='dense_fisher' --learning_rate 1e-3 --weight_decay 1e-4 --batch_size 64 --no_epochs 2600
python prune.py --net='dense' --depth 100 --data_loc= --l1_prune=True --base_model='dense' --save_file='dense_l1'  --learning_rate 1e-3 --weight_decay 1e-4 --batch_size 64  --no_epochs 2600

Note that the default is to perform Fisher pruning, so you don't need to pass a flag to use it.
Once finished, we can train the pruned models from scratch, e.g.:

python train.py --data_loc= --net='res' --base_file='res_fisher__prunes' --deploy --mask=1 --save_file='res_fisher__prunes_scratch'

Each model can then be evaluated using:

python train.py --deploy --eval --data_loc= --net='res' --mask=1 --base_file='res_fisher__prunes'

Training Reduced models

This can be done by varying the input arguments to train.py. To reduce depth or width of a WRN, change the corresponding option:

python train.py --net='res' --depth= --width= --data_loc= --save_file='res_reduced'

To add bottlenecks, use the following:

python train.py --net='res' --depth=40 --width=2.0 --data_loc= --save_file='res_bottle' --bottle --bottle_mult 

With DenseNets you can modify the depth or growth, or use --bottle --bottle_mult as above.

Acknowledgements

Jack Turner wrote the L1 stuff, and some other stuff for that matter.

Code has been liberally borrowed from many a repo, including, but not limited to:

https://github.com/xternalz/WideResNet-pytorch
https://github.com/bamos/densenet.pytorch
https://github.com/kuangliu/pytorch-cifar
https://github.com/ShichenLiu/CondenseNet

Citing this work

If you would like to cite this work, please use the following bibtex entry:

@article{crowley2018pruning,
  title={A Closer Look at Structured Pruning for Neural Network Compression},
  author={Crowley, Elliot J and Turner, Jack and Storkey, Amos and O'Boyle, Michael},
  journal={arXiv preprint arXiv:1810.04622},
  year={2018},
  }
Comments
  • Hi,how to define the maskBlock base on own model?

    Hi,how to define the maskBlock base on own model?

    my model include resnet18 as Backbone network and another three branches outputs, i want to prune the resnet18。 Now , how to define the maskBlock ? Thanks

    opened by cvJie 3
  • When you call `python train.py --deploy --eval <-other-commands->` the network is pruned at runtime (by the `if` statement on line 73) and then used.

    When you call `python train.py --deploy --eval <-other-commands->` the network is pruned at runtime (by the `if` statement on line 73) and then used.

    When you call python train.py --deploy --eval <-other-commands-> the network is pruned at runtime (by the if statement on line 73) and then used.

    If you would like to save the pruned model, you could put a:

    save_checkpoint({
                    'epoch': SD['epoch'],
                    'state_dict': model.state_dict(),
                    'error_history': SD['error_history'],
                }, filename=filename)
    

    after the call to pruner.compress(model) on line 89.

    However, it is better to leave the saved checkpoint in its original state, with the masks attached, to make it easier to recover the pruning trajectories. You can check the number of ops/params with get_inf_params(model) if you want an indication of compression rate. Whenever you want to use a pruned model for something, you then just need to run the code from lines 71 to 89 in train.py, followed by the task you want the pruned model to complete.

    Hope this helps.

    Originally posted by @jack-willturner in https://github.com/BayesWatch/pytorch-prunes/issues/1#issuecomment-541559480

    opened by cvJie 0
  • When you call `python train.py --deploy --eval <-other-commands->` the network is pruned at runtime (by the `if` statement on line 73) and then used.

    When you call `python train.py --deploy --eval <-other-commands->` the network is pruned at runtime (by the `if` statement on line 73) and then used.

    When you call python train.py --deploy --eval <-other-commands-> the network is pruned at runtime (by the if statement on line 73) and then used.

    If you would like to save the pruned model, you could put a:

    save_checkpoint({
                    'epoch': SD['epoch'],
                    'state_dict': model.state_dict(),
                    'error_history': SD['error_history'],
                }, filename=filename)
    

    after the call to pruner.compress(model) on line 89.

    However, it is better to leave the saved checkpoint in its original state, with the masks attached, to make it easier to recover the pruning trajectories. You can check the number of ops/params with get_inf_params(model) if you want an indication of compression rate. Whenever you want to use a pruned model for something, you then just need to run the code from lines 71 to 89 in train.py, followed by the task you want the pruned model to complete.

    Hope this helps.

    Originally posted by @jack-willturner in https://github.com/BayesWatch/pytorch-prunes/issues/1#issuecomment-541559480

    opened by cvJie 0
  • When you call `python train.py --deploy --eval <-other-commands->` the network is pruned at runtime (by the `if` statement on line 73) and then used.

    When you call `python train.py --deploy --eval <-other-commands->` the network is pruned at runtime (by the `if` statement on line 73) and then used.

    When you call python train.py --deploy --eval <-other-commands-> the network is pruned at runtime (by the if statement on line 73) and then used.

    If you would like to save the pruned model, you could put a:

    save_checkpoint({
                    'epoch': SD['epoch'],
                    'state_dict': model.state_dict(),
                    'error_history': SD['error_history'],
                }, filename=filename)
    

    after the call to pruner.compress(model) on line 89.

    However, it is better to leave the saved checkpoint in its original state, with the masks attached, to make it easier to recover the pruning trajectories. You can check the number of ops/params with get_inf_params(model) if you want an indication of compression rate. Whenever you want to use a pruned model for something, you then just need to run the code from lines 71 to 89 in train.py, followed by the task you want the pruned model to complete.

    Hope this helps.

    Originally posted by @jack-willturner in https://github.com/BayesWatch/pytorch-prunes/issues/1#issuecomment-541559480

    opened by cvJie 0
  • RuntimeError: running_mean should contain 57 elements not 64

    RuntimeError: running_mean should contain 57 elements not 64

    hi, I success to pruned and finetune the cifar res_model, have successed to finish the pruned model by own data and model, but and now need to finetune the pruned model ,happened some error:

    raceback (most recent call last): File "train_fashion.py", line 155, in log_dict_train=train(epoch,train_loader) File "train_fashion.py", line 117, in train log_dict_train, _ = trainer.train(epoch, train_loader) File "/fashiontrain/fashionprunes/lib/trains/base_trainer.py", line 103, in train return self.run_epoch('train', epoch, data_loader) File "/fashiontrain/fashionprunes/lib/trains/base_trainer.py", line 79, in run_epoch output, loss, loss_stats = model_with_loss(batch) File "/usr/local/lib/python3.6/dist-packages/torch/nn/modules/module.py", line 493, in call result = self.forward(*input, **kwargs) File "/fashiontrain/fashionprunes/lib/trains/base_trainer.py", line 19, in forward outputs = self.model(batch['input']) File "/usr/local/lib/python3.6/dist-packages/torch/nn/modules/module.py", line 493, in call result = self.forward(*input, **kwargs) File "/fashiontrain/fashionprunes/lib/models/networks/msra_resnet.py", line 372, in forward x = self.layer1(x) File "/usr/local/lib/python3.6/dist-packages/torch/nn/modules/module.py", line 493, in call result = self.forward(*input, **kwargs) File "/usr/local/lib/python3.6/dist-packages/torch/nn/modules/container.py", line 92, in forward input = module(input) File "/usr/local/lib/python3.6/dist-packages/torch/nn/modules/module.py", line 493, in call result = self.forward(*input, **kwargs) File "/fashiontrain/fashionprunes/lib/models/networks/msra_resnet.py", line 137, in forward out = self.bn1(out) File "/usr/local/lib/python3.6/dist-packages/torch/nn/modules/module.py", line 493, in call result = self.forward(*input, **kwargs) File "/usr/local/lib/python3.6/dist-packages/torch/nn/modules/batchnorm.py", line 83, in forward exponential_average_factor, self.eps) File "/usr/local/lib/python3.6/dist-packages/torch/nn/functional.py", line 1697, in batch_norm training, momentum, eps, torch.backends.cudnn.enabled RuntimeError: running_mean should contain 57 elements not 64

    can you give me some advices?? thank you

    opened by cvJie 2
Owner
Bayesian and Neural Systems Group
Machine learning research group @ University of Edinburgh
Bayesian and Neural Systems Group
code for `Look Closer to Segment Better: Boundary Patch Refinement for Instance Segmentation`

Look Closer to Segment Better: Boundary Patch Refinement for Instance Segmentation (CVPR 2021) Introduction PBR is a conceptually simple yet effective

H.Chen 143 Jan 5, 2023
PyTorch implementation of the R2Plus1D convolution based ResNet architecture described in the paper "A Closer Look at Spatiotemporal Convolutions for Action Recognition"

R2Plus1D-PyTorch PyTorch implementation of the R2Plus1D convolution based ResNet architecture described in the paper "A Closer Look at Spatiotemporal

Irhum Shafkat 342 Dec 16, 2022
Look Closer: Bridging Egocentric and Third-Person Views with Transformers for Robotic Manipulation

Look Closer: Bridging Egocentric and Third-Person Views with Transformers for Robotic Manipulation Official PyTorch implementation for the paper Look

Rishabh Jangir 20 Nov 24, 2022
Group Fisher Pruning for Practical Network Compression(ICML2021)

Group Fisher Pruning for Practical Network Compression (ICML2021) By Liyang Liu*, Shilong Zhang*, Zhanghui Kuang, Jing-Hao Xue, Aojun Zhou, Xinjiang W

Shilong Zhang 129 Dec 13, 2022
An implementation of based on pytorch and mmcv

FisherPruning-Pytorch An implementation of <Group Fisher Pruning for Practical Network Compression> based on pytorch and mmcv Main Functions Pruning f

Peng Lu 15 Dec 17, 2022
YOLOv5 Series Multi-backbone, Pruning and quantization Compression Tool Box.

YOLOv5-Compression Update News Requirements 环境安装 pip install -r requirements.txt Evaluation metric Visdrone Model mAP mAP@50 Parameters(M) GFLOPs FPS@

ZhangYuan 719 Jan 2, 2023
This repo contains the official implementations of EigenDamage: Structured Pruning in the Kronecker-Factored Eigenbasis

EigenDamage: Structured Pruning in the Kronecker-Factored Eigenbasis This repo contains the official implementations of EigenDamage: Structured Prunin

Chaoqi Wang 107 Apr 20, 2022
Revisiting Discriminator in GAN Compression: A Generator-discriminator Cooperative Compression Scheme (NeurIPS2021)

Revisiting Discriminator in GAN Compression: A Generator-discriminator Cooperative Compression Scheme (NeurIPS2021) Overview Prerequisites Linux Pytho

Shaojie Li 34 Mar 31, 2022
An Image compression simulator that uses Source Extractor and Monte Carlo methods to examine the post compressive effects different compression algorithms have.

ImageCompressionSimulation An Image compression simulator that uses Source Extractor and Monte Carlo methods to examine the post compressive effects o

James Park 1 Dec 11, 2021
A curated list of neural network pruning resources.

A curated list of neural network pruning and related resources. Inspired by awesome-deep-vision, awesome-adversarial-machine-learning, awesome-deep-learning-papers and Awesome-NAS.

Yang He 1.7k Jan 9, 2023
Code for PackNet: Adding Multiple Tasks to a Single Network by Iterative Pruning

PackNet: https://arxiv.org/abs/1711.05769 Pretrained models are available here: https://uofi.box.com/s/zap2p03tnst9dfisad4u0sfupc0y1fxt Datasets in Py

Arun Mallya 216 Jan 5, 2023
Network Pruning That Matters: A Case Study on Retraining Variants (ICLR 2021)

Network Pruning That Matters: A Case Study on Retraining Variants (ICLR 2021)

Duong H. Le 18 Jun 13, 2022
Ensemble Knowledge Guided Sub-network Search and Fine-tuning for Filter Pruning

Ensemble Knowledge Guided Sub-network Search and Fine-tuning for Filter Pruning This repository is official Tensorflow implementation of paper: Ensemb

Seunghyun Lee 12 Oct 18, 2022
Stacked Hourglass Network with a Multi-level Attention Mechanism: Where to Look for Intervertebral Disc Labeling

⚠️ ‎‎‎ A more recent and actively-maintained version of this code is available in ivadomed Stacked Hourglass Network with a Multi-level Attention Mech

Reza Azad 14 Oct 24, 2022
PyTorch Implementation of [1611.06440] Pruning Convolutional Neural Networks for Resource Efficient Inference

PyTorch implementation of [1611.06440 Pruning Convolutional Neural Networks for Resource Efficient Inference] This demonstrates pruning a VGG16 based

Jacob Gildenblat 836 Dec 26, 2022
Channel Pruning for Accelerating Very Deep Neural Networks (ICCV'17)

Channel Pruning for Accelerating Very Deep Neural Networks (ICCV'17)

Yihui He 1k Jan 3, 2023
Code of paper "CDFI: Compression-Driven Network Design for Frame Interpolation", CVPR 2021

CDFI (Compression-Driven-Frame-Interpolation) [Paper] (Coming soon...) | [arXiv] Tianyu Ding*, Luming Liang*, Zhihui Zhu, Ilya Zharkov IEEE Conference

Tianyu Ding 95 Dec 4, 2022
PyTorch implementation of ARM-Net: Adaptive Relation Modeling Network for Structured Data.

A ready-to-use framework of latest models for structured (tabular) data learning with PyTorch. Applications include recommendation, CRT prediction, healthcare analytics, and etc.

null 48 Nov 30, 2022
Pytorch implementation of COIN, a framework for compression with implicit neural representations 🌸

COIN ?? This repo contains a Pytorch implementation of COIN: COmpression with Implicit Neural representations, including code to reproduce all experim

Emilien Dupont 104 Dec 14, 2022