Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
78 commits
Select commit Hold shift + click to select a range
c9e7f0c
delete default model saving code (for saving memory)
jysohn1108 Apr 7, 2022
53da0dd
adding exec file for full runs
ksreenivasan Apr 7, 2022
f07f256
config for cifar10
jysohn1108 Apr 7, 2022
60efd95
Merge branch 'master' of https://github.com/ksreenivasan/pruning_is_e…
jysohn1108 Apr 7, 2022
f910251
minor fix to exec script
Apr 8, 2022
648e8cd
run cifar10 hparam selection and final run
jysohn1108 Apr 8, 2022
4ba4f21
resnet18 best config
Apr 8, 2022
070aabc
resnet50, tinyimgnet, best hparam
Apr 8, 2022
a69ab8c
caltech101
Apr 8, 2022
3b288d3
val/train/test for tinyimgnet
jysohn1108 Apr 8, 2022
cf94059
Merge branch 'master' of https://github.com/ksreenivasan/pruning_is_e…
jysohn1108 Apr 8, 2022
c76961e
run final for tinyimgnet, resnet18
Apr 8, 2022
a42b9fd
adding code to print wallclock time at beginning, mid and end of process
Apr 8, 2022
8df0eec
Merge branch 'master' of github.com:ksreenivasan/pruning_is_enough
ksreenivasan Apr 8, 2022
2acc1bd
adding print_time for IMP
ksreenivasan Apr 8, 2022
86e6f59
setting up imp for logging time
ksreenivasan Apr 8, 2022
ce05860
dropping determinism for performance
ksreenivasan Apr 9, 2022
dac22cf
adding cifar_exec for wideresnet28
Apr 9, 2022
2431c9d
modifying conf for wideresnet28 hyp tuning
ksreenivasan Apr 9, 2022
4f8b091
updating exec for wideresnet28
ksreenivasan Apr 10, 2022
1c7ac7f
updating exec for wideresnet sp20
ksreenivasan Apr 10, 2022
84a1a1f
pushing exec for mobilenet
ksreenivasan Apr 10, 2022
b789e41
updating readme file
ksreenivasan Apr 10, 2022
2dd2b22
Update README.md
ksreenivasan Apr 11, 2022
9a59614
Delete related_works.md
jysohn1108 Apr 11, 2022
cdb3888
adding code for resnet32 cifar100
ksreenivasan Apr 11, 2022
6cd6a73
cifar100 bugfixes
ksreenivasan Apr 12, 2022
832af75
changing resnet last layer for cifar100
ksreenivasan Apr 12, 2022
f9961fa
changing last layer for resnet32
ksreenivasan Apr 12, 2022
9779755
pushing configs and exec script
ksreenivasan Apr 12, 2022
8306c9a
Merge pull request #31 from ksreenivasan/cifar100
ksreenivasan Apr 21, 2022
76e4948
adding config and exec for wt on cifar100 resnet32_double
ksreenivasan Apr 21, 2022
eff2a09
imp for resnet32 (double), cifar100
jysohn1108 Apr 21, 2022
e408df3
trying ddp demo
ksreenivasan Apr 22, 2022
3219448
cifar100, resnet32
jysohn1108 Apr 22, 2022
c5ad2fb
Merge branch 'master' of https://github.com/ksreenivasan/pruning_is_e…
jysohn1108 Apr 22, 2022
49aab99
trying ddp with cifar10
ksreenivasan Apr 25, 2022
0104f0e
merging conflicts
ksreenivasan Apr 25, 2022
07ea02a
indentation fix
ksreenivasan Apr 25, 2022
e723ea5
minor indentation fix
ksreenivasan Apr 25, 2022
6dc75f1
changing model to resnet18
ksreenivasan Apr 25, 2022
3d6ce30
tweaking things for ddp cifar10
ksreenivasan Apr 25, 2022
1bf670f
testing if batches are disjoint cifar10 ddp
ksreenivasan Apr 25, 2022
7117486
trying cifar10 ddp with toy fc model
ksreenivasan Apr 25, 2022
abc7a98
indentation fixes
ksreenivasan Apr 25, 2022
747e95a
trying to periodically prune model ddp
ksreenivasan Apr 25, 2022
c2e9e9d
prune at start of epoch and check norm immediately ddp
ksreenivasan Apr 25, 2022
807dea4
i think the pruning poc is complete
ksreenivasan Apr 25, 2022
6334d1f
adding code to make ddp work
ksreenivasan Apr 26, 2022
9e1f0de
trying out how args work in ddp
ksreenivasan Apr 26, 2022
f616ab6
trying out stuff with parser_args in ddp setting
ksreenivasan Apr 26, 2022
e6b93a6
adding ddp_utils
ksreenivasan Apr 26, 2022
f202a42
adding ddp_utils
ksreenivasan Apr 26, 2022
513b8a6
looks like reimporting doesn't hurt the global values
ksreenivasan Apr 26, 2022
02a6627
adding more code to implement ddp
ksreenivasan Apr 26, 2022
7f1e0f6
testing ddp with deepcopy
ksreenivasan Apr 26, 2022
6cc557b
looks like copy.deepcopy causes sync issues
ksreenivasan Apr 26, 2022
dd0ba73
fixing typo in ddp deepcopy
ksreenivasan Apr 26, 2022
1d21c5a
finishing up ddp for sanity checks and finetune
ksreenivasan Apr 26, 2022
691cffa
minor bugfixes for ddp
ksreenivasan Apr 26, 2022
ffca648
removing .cuda() from the codebase
ksreenivasan Apr 26, 2022
e1c9810
trying to catch the rank=0 leak
ksreenivasan Apr 26, 2022
64cbf57
I think ddp works!
ksreenivasan Apr 26, 2022
eb12a2d
skipping checkpoint, trying to get rid of tqdm
ksreenivasan Apr 28, 2022
f4fbff0
trying to eliminate tqdm and progress meters
ksreenivasan Apr 28, 2022
69048e0
trainer doesn't see parser_args
ksreenivasan Apr 28, 2022
3834b3d
still removing leftover calls to tqdm and progresmeters
ksreenivasan Apr 28, 2022
3ba1f93
removing more instances of progressmeter and replacing them with vani…
ksreenivasan Apr 28, 2022
77fbe48
fixing dir creation bug
ksreenivasan Apr 28, 2022
1ffc000
adding config for serial debug
ksreenivasan Apr 28, 2022
53b90c0
stuff works, removing an unnecessary barrier
ksreenivasan Apr 29, 2022
10b1ee4
adding imagenet configs and exec script
ksreenivasan Apr 29, 2022
38550af
setting find_unused_parameters=False and adding config for sp10
ksreenivasan May 3, 2022
50805e3
pushing config for sp15 imagenet
May 4, 2022
fb1eab0
minor tweaks to configs for imagenet
May 4, 2022
5ccc7a3
adding port as param for multiple runs
ksreenivasan May 4, 2022
9c94797
Merge branch 'ffcv_imagenet_serial' into ddp_ffcv
ksreenivasan May 5, 2022
56e32cb
updating port to str not int
ksreenivasan May 6, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 118 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,118 @@
# pruning_is_enough
Pruning is all you need (hopefully)
## Rare Gems: Finding Lottery Tickets at Initialization

### Overview
---
It has been widely observed that large neural networks can be pruned to a small fraction of their original size, with little loss in accuracy, by typically following a time-consuming "train, prune, re-train" approach. Frankle & Carbin (2018) conjecture that we can avoid this by training lottery tickets, i.e., special sparse subnetworks found at initialization, that can be trained to high accuracy. However, a subsequent line of work presents concrete evidence that current algorithms for finding trainable networks at initialization, fail simple baseline comparisons, e.g., against training random sparse subnetworks. Finding lottery tickets that train to better accuracy compared to simple baselines remains an open problem. In this work, we partially resolve this open problem by discovering rare gems: subnetworks at initialization that attain considerable accuracy, even before training. Refining these rare gems - "by means of fine-tuning" - beats current baselines and leads to accuracy competitive or better than magnitude pruning methods.

### Depdendencies (tentative)
---
Tested stable dependencies:
* python 3.6.5 (Anaconda)
* PyTorch 1.1.0
* torchvision 0.2.2
* CUDA 10.0.130
* cuDNN 7.5.1
* tensorboard
* tqdm
* ffcv (If you want to run ffcv imagenet)

### Data Preparation
---
1. For `tinyimagenet`, run `load_tiny_imagenet.sh`
2. For `imagenet`, you will need to download `imagenet` and specify the path in `data/imagenet.py` (Currently in branch. Will be merged soon)

### Running Experients:
---
The main script is `main.py`, to launch the jobs, we provide scripts `./cifar_exec.sh`, `imp_exec.sh`. And we provide a description of the main arguments. For more detailed descriptions, refer to `args_helper.py`.


| Argument | Description |
| ----------------------------- | ---------------------------------------- |
| `algo` | Specify the algorithm to run. `hc|ep|hc_iter|wt`. Note that GM is `hc_iter` in the code. |
| `lr` | Inital learning rate that will be used for the pruning process. |
| `fine_tune_lr` | Inital learning rate that will be used for the finetuning process. |
| `batch-size` | Batch size for the optimizers e.g. SGD or Adam. |
| `optimizer` | `sgd` or `adam`. |
| `dataset` | Dataset to use. |
| `arch` | Model to use. |
| `gamma` | the factor of learning rate decay, i.e. the effective learning rate is `lr*gamma^t`. |
| `iter_period` | Specifically for `hc_iter`, how often to run iterative thresholding. |
| `conv_type` | Will almost always be `SubnetConv` for pruning. |
| `target_sparsity` | Specify the target sparsity for the ticket. |
| `unflag_before_finetune` | Restore weights if the regularizer killed too many. |
| `init` | Weight initialization distribution. |
| `score_init` | Score initialization distribution. |
| `hc_quantized` | Enable for GM since it will round on forward pass. |
| `regularization` | `L2|L1` |
| `lmbda` | Regularization weight. |
| `gpu` | Specify which gpu to run on. |


#### Configs
Note that the workflow is managed by specifying the above arguments using `.yml` files specified in the `configs/` directory. Please refer them to create new configs like `configs/resnet20/resnet20_sparsity_0_59_unflagT.yml`.

#### Sample Config
```
# subfolder: target_sparsity_0_59_unflagT

# Hypercube optimization
algo: 'hc_iter'
iter_period: 5

# Architecture
arch: resnet20

# ===== Dataset ===== #
dataset: CIFAR10
name: resnet20_quantized_iter_hc

# ===== Learning Rate Policy ======== #
optimizer: sgd
lr: 0.1 #0.01
lr_policy: cosine_lr #constant_lr #multistep_lr
fine_tune_lr: 0.01
fine_tune_lr_policy: multistep_lr

# ===== Network training config ===== #
epochs: 150
wd: 0.0
momentum: 0.9
batch_size: 128

# ===== Sparsity =========== #
conv_type: SubnetConv
bn_type: NonAffineBatchNorm
freeze_weights: True
prune_type: BottomK
# enter target sparsity here
target_sparsity: 0.59
# decide if you want to "unflag"
unflag_before_finetune: True
init: signed_constant
score_init: unif #skew #half #bimodal #skew # bern
scale_fan: False #True

# ===== Rounding ===== #
round: naive
noise: True
noise_ratio: 0

# ===== Quantization ===== #
hc_quantized: True
quantize_threshold: 0.5

# ===== Regularization ===== #
regularization: L2
lmbda: 0.0001 # 1e-4

# ===== Hardware setup ===== #
workers: 4
gpu: 0

# ===== Checkpointing ===== #
checkpoint_at_prune: False

# ==== sanity check ==== #
skip_sanity_checks: False

```
55 changes: 40 additions & 15 deletions args_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -876,21 +876,40 @@ def parse_arguments(self, jupyter_mode=False):
default=0,
help="Use mixed precision or not"
)
parser.add_argument('--transformer_emsize', type=int, default=200,
help='size of word embeddings')
parser.add_argument('--transformer_nhid', type=int, default=200,
help='number of hidden units per layer')
parser.add_argument('--transformer_nlayers', type=int, default=2,
help='number of layers')
parser.add_argument('--transformer_clip', type=float, default=0.25,
help='gradient clipping')
parser.add_argument('--transformer_bptt', type=int, default=35,
help='sequence length')
parser.add_argument('--transformer_dropout', type=float, default=0.2,
help='dropout applied to layers (0 = no dropout)')
parser.add_argument('--transformer_nhead', type=int, default=2,
help='the number of heads in the encoder/decoder of the transformer model')

parser.add_argument('--transformer_emsize',
type=int, default=200,
help='size of word embeddings'
)
parser.add_argument('--transformer_nhid',
type=int,
default=200,
help='number of hidden units per layer'
)
parser.add_argument('--transformer_nlayers',
type=int,
default=2,
help='number of layers'
)
parser.add_argument('--transformer_clip',
type=float,
default=0.25,
help='gradient clipping'
)
parser.add_argument('--transformer_bptt',
type=int,
default=35,
help='sequence length'
)
parser.add_argument('--transformer_dropout',
type=float,
default=0.2,
help='dropout applied to layers (0 = no dropout)'
)
parser.add_argument('--transformer_nhead',
type=int,
default=2,
help='the number of heads in the encoder/decoder of the transformer model'
)
parser.add_argument(
"--only-sanity",
action="store_true",
Expand Down Expand Up @@ -928,6 +947,12 @@ def parse_arguments(self, jupyter_mode=False):
default=False,
help="Enable this use full train data and not leave anything for validation"
)
parser.add_argument(
"--port",
default=29500,
type=int,
help="Specify port to use for DDP",
)

if jupyter_mode:
args = parser.parse_args("")
Expand Down
46 changes: 37 additions & 9 deletions cifar_exec.sh
Original file line number Diff line number Diff line change
Expand Up @@ -61,25 +61,53 @@ python main.py \
--config configs/hypercube/wideresnet28/wideresnet28_weight_training.yml > wideresnet_wt_log 2>&1
BLOCK


# Running trials in parallel
#:<<BLOCK
# Using validation to figure out hyperparams
# NOTE: make sure to delete/comment subfolder from the config file or else it may not work
conf_file="configs/conf"
conf_file="configs/hypercube/resnet50/imagenet/resnet50_sparsity_15"
conf_end=".yml"
log_root="resnet20_059_val_debug"
log_root="resnet50_imagenet_sp15_"
log_end="_log"
subfolder_root="resnet20_059_val_debug_"
subfolder_root="resnet50_imagenet_sp15_"

for trial in 4 5 6
for trial in 1
do
python main.py \
--config "$conf_file$trial$conf_end" \
--trial-num $trial \
--config "$conf_file$conf_end" \
--subfolder "$subfolder_root$trial" > "$log_root$trial$log_end" 2>&1 &

#python main.py \
#--config "$conf_file" \
#--config "$conf_file$conf_end" \
#--trial-num $trial \
#--invert-sanity-check \
#--skip-sanity-checks \
#--subfolder "invert_$subfolder_root$trial" > "invert_$log_root$trial$log_end" 2>&1 &
done
#BLOCK

:<<BLOCK
# Final run on full data
# NOTE: make sure to delete/comment subfolder from the config file or else it may not work
conf_file="configs/param_tuning/resnet20_13_34/conf2"
conf_end=".yml"
log_root="resnet20_sp13_34_"
log_end="_log"
subfolder_root="resnet20_sp13_34_"

for trial in 1
do
python main.py \
--config "$conf_file$conf_end" \
--trial-num $trial \
--use-full-data \
--subfolder "$subfolder_root$trial" > "$log_root$trial$log_end" 2>&1 &

python main.py \
--config "$conf_file$conf_end" \
--trial-num $trial \
--invert-sanity-check \
--use-full-data \
--skip-sanity-checks \
--subfolder "invert_$subfolder_root$trial" > "invert_$log_root$trial$log_end" 2>&1 &
done
BLOCK
Loading