Implementation of SqueezeNet: AlexNet-level accuracy with 50x fewer parameters and <0.5MB model size by Forrest N. Iandola, Song Han, Matthew W. Moskewicz, Khalid Ashraf, William J. Dally, Kurt Keutzer.
To reproduce the article I mainly focused on the hyperparameters in this .prototxt file from paper's authors. In addition i used:
- Weights initialization described in paper;
- There is not much information about image preprocessing in paper, but there are some issues with author's answers about image preprocessing and augmentation (link 1, link2). There is also
.prototxtfile with only mean substraction, even without division by 255. So, i used the author's answers to build augmentation and preprocessing pipeline with albumentation; - I used
torch.optim.lr_scheduler.PolynomialLRand do it's step after each batch. As far as i understand inCaffeit works like this; - I didn't use any gradient accumulation techniques as described in
.prototxtand directly trained usingbatch_size=512; - I also tried to calculate how many epochs i need to train to match
170_000batches as described in.prototxtfile and got~67epochs to train.
| Architecture | Acc@1 | Acc@5 | Skip connections type | W&B run | PyTorch checkpoints |
|---|---|---|---|---|---|
| SqueezeNet 1.0 | 56.0 | 79.0 | None | link | link |
| SqueezeNet 1.0 | 51.3 | 74.8 | simple | link | link |
| SqueezeNet 1.0 | NaN | NaN | complex | link | - |
| SqueezeNet 1.1 | 54.6 | 78.0 | None | link | link |
| SqueezeNet 1.1 | 53.7 | 77.3 | simple | link | link |
| SqueezeNet 1.1 | NaN | NaN | complex | link | - |
It was also interesting for me to play a bit with SqueezeNets. So i decide to add the following things:
- In
ExpandLayeruse only onetorch.nn.ReLUinstead of two. Obviously, it's faster; - Swap first
torch.nn.MaxPoll2dwith firsttorch.nn.ReLU. This will lead to applying ReLU to the tensor with much less data which is much faster; - Substitute
final_convwith singletorch.nn.Linearlayer, so we don't have convolution + ReLU for the final classification layer wich was quite strange decision since ReLU killed all logits that are below zero; - Standard PyTorch initialization for layers;
- Add
BatchNorm2dto the model; - Use standard modern Z-normalization for images (division by 255 and Z-standardization with ImageNet means and stds);
- Use
torch.optim.lr_scheduler.CosineAnnealingLRinstead oftorch.optim.lr_scheduler.PolynomialLR; RandomResizedCrop(227, 227)instead ofCompose(Resized(256, 256), RandomResizedCrop(227, 227));- Add
SE-module.
| Architecture | Acc@1 | Acc@5 | Skip connections type | W&B run | PyTorch checkpoints |
|---|---|---|---|---|---|
| SqueezeNet 1.2 | 61.8 | 84.6 | None | link | link |
I used ImageNet from Kaggle. You can find it here.
I used the following environment configuration:
- Ubuntu 22.04;
- Python 3.11;
- Python 3.11-venv;
- NVidia Driver 530.41.03;
- NVidia CUDA 12.2
Core requirements are listed in requirements.txt file. Development requirements are listed in requirements.dev.txt. I also provide to you optional requirements in requirements.optional.txt. So, to be able to use this repo you need to do the following things:
- Install
python 3.11,python3.11-devandpython3.11-venv:sudo apt-get install -y python3.11 python3.11-dev python3.11-venv - Install
libturbojpeg. You need it to usejpeg4pypackage which greatly reduce the time of reading.jpeg\.jpgimages from disk:sudo apt-get install libturbojpeg - Create
venv, activate it and updatepip:python3.11 -m venv venv source venv/bin/activate pip install --upgrade pip - Install core dependencies:
pip install -r requirements.txt - If you want to use
W&Blogger then installrequirements.optional.txtbypip install -r requirements.optional.txt. And create.envfile and putWANDB_API_KEYinside.env. You can find example in.env-example.
If you want to further develop this repo you need to install development requirements. Development requirements contain ruff package for linting\formatting and pytest packages for tests.
I also provide to you some recipies in Makefile to make your life easier:
make lint- runsrufflinter;make format- runsruffformatter;make run_tests- runs tests withpytest;make pre_push_test- runs linter and tests.
These recipies are mostly for development purposes.
It's quite simple:
- Modify
config.ymlfile according to your desires; - Run
python train.py.
It shoud works okay. I also provide to you some predefined configuration files placed in predefined_configs. These are configuration files that i used to obtain models listed in tables above.
To export the model just do:
python export_to_onnx.py \
--config %path to config.yml% \
--torch_weights %path to PyTorch weights% \
--onnx_path %path tot ONNX file% \
--image_size %Image height and image width separated by single comma%
Example of command to export squeezenet-v1.1:
python export_to_onnx.py \
--config predefined_configs/squeezenetv1.1.yml \
--torch_weights weights/i9a39wo6/state_dict.pth \
--onnx_path ./squeezenetv11.onnx \
--image_size 224,224 \