Repository: pytorch/vision
Pull request: Add shufflenetv2 1.5 and 2.0 weights
Resolve https://github.com/pytorch/vision/issues/3257

We train the model using similar with [the improved recipe](https://pytorch.org/blog/how-to-train-state-of-the-art-models-using-torchvision-latest-primitives/#the-training-recipe). Here are the commands:
```
# Choose the model
MODEL = shufflenet_v2_x1_5
# MODEL = shufflenet_v2_x2_0

# Training command
python \
    -u ~/script/run_with_submitit.py \
    --timeout 3000 --ngpus 8 --nodes 1 --batch-size=128 \
    --partition train --model $MODEL \
    --data-path="/datasets01_ontap/imagenet_full_size/061417" \
    --lr=0.5 --lr-scheduler=cosineannealinglr --lr-warmup-epochs=5 --lr-warmup-method=linear \
    --auto-augment=ta_wide --epochs=600 --random-erase=0.1 --weight-decay=0.00002 \
    --norm-weight-decay=0.0 --label-smoothing=0.1 --mixup-alpha=0.2 --cutmix-alpha=1.0 \
    --train-crop-size=176 --model-ema --val-resize-size=232 --ra-sampler --ra-reps=4
```

Once the training finished, we take the checkpoint of epoch with the highest `Acc@1` accuracy, for shufflenetv2_x2_0 we take epoch 595 and for shufflenetv2_x1_5 we take epoch 594, we take the non-ema models for both. Then, we test again the checkpoints with 1 gpu and batch_size=1, here are the commands and results:

```
# For shufflenetv2_x1_5
python -u ~/script/run_with_submitit.py \
    --timeout 3000 --nodes 1 --ngpus 1 --batch-size=1 \
    --partition train --model shufflenet_v2_x1_5 \
    --data-path="/datasets01_ontap/imagenet_full_size/061417" \
    --weights="ShuffleNet_V2_X1_5_Weights.IMAGENET1K_V1" \
    --test-only
# Test:  Acc@1 Acc@1 72.996 Acc@5 91.086

# For shufflenetv2_x2_0
python -u ~/script/run_with_submitit.py \
    --timeout 3000 --nodes 1 --ngpus 1 --batch-size=1 \
    --partition train --model shufflenet_v2_x1_5 \
    --data-path="/datasets01_ontap/imagenet_full_size/061417" \
    --weights="ShuffleNet_V2_X1_5_Weights.IMAGENET1K_V1" \
    --test-only
# Test:  Acc@1 76.230 Acc@5 93.006
```

We also provide quantized model using post training quantization. Here are the commands to do it:
```
# For shufflenet_v2_x1_5
python train_quantization.py --device='cpu' --post-training-quantize --backend='fbgemm' \
    --model=shufflenet_v2_x1_5 --weights="ShuffleNet_V2_X1_5_Weights.IMAGENET1K_V1" \
    --train-crop-size 176 --val-resize-size 232 --data-path /datasets01_ontap/imagenet_full_size/061417/

# For shufflenet_v2_x2_0
python train_quantization.py --device='cpu' --post-training-quantize --backend='fbgemm' \
    --model=shufflenet_v2_x1_5 --weights="ShuffleNet_V2_X1_5_Weights.IMAGENET1K_V1" \
    --train-crop-size 176 --val-resize-size 232 --data-path /datasets01_ontap/imagenet_full_size/061417/
```

And once we have the quantized model, we do evaluation with 1 gpu and batch_size=1. Here are the commands for evaluation and the corresponding result:

```
python train_quantization.py --device='cpu' --eval-batch-size=1 --test-only --backend='fbgemm' \
    --model='shufflenet_v2_x2_0' \
    --data-path="/datasets01_ontap/imagenet_full_size/061417" \
    --weights="ShuffleNet_V2_X2_0_QuantizedWeights.IMAGENET1K_FBGEMM_V1"
# Acc@1 72.052 Acc@5 90.700

python train_quantization.py --device='cpu' --eval-batch-size=1 --test-only --backend='fbgemm' \
    --model='shufflenet_v2_x1_5' \
    --data-path="/datasets01_ontap/imagenet_full_size/061417" \
    --weights="ShuffleNet_V2_X1_5_QuantizedWeights.IMAGENET1K_FBGEMM_V1"
# Acc@1 75.354 Acc@5 92.488
```


Problem statement:
Pre-trained shufflenetv2_x1.5 and shufflenetv2_x2.0 raise "...not supported as of now".
## 🐛 Bug

Pre-trained models of shufflenetv2_x1.5 and shufflenetv2_x2.0 raise the following `NotImplementedError: pretrained {} is not supported as of now`. Important: pre-trained models of shufflenet_v2_x0_5 and shufflenet_v2_x1_0 are working perfectly.

## To Reproduce

Steps to reproduce the behavior:

1. from torchvision import models
2. model = models.shufflenet_v2_x1_5(pretrained=pretrained)
3. model = models.shufflenet_v2_x2_0(pretrained=pretrained)
4. Raises the following:

<!-- If you have a code sample, error messages, stack traces, please provide it here as well -->

```
  NotImplementedError                       Traceback (most recent call last)
  <ipython-input-15-788c60a16542> in <module>
        1 # Build and train your network
        2 # Transfer Learning
  ----> 3 model = models.shufflenet_v2_x1_5(pretrained=pretrained)
  
  ~/venvs/pytorch_gpu/lib/python3.8/site-packages/torchvision/models/shufflenetv2.py in shufflenet_v2_x1_5(pretrained, progress, **kwargs)
      191         progress (bool): If True, displays a progress bar of the download to stderr
      192     """
  --> 193     return _shufflenetv2('shufflenetv2_x1.5', pretrained, progress,
      194                          [4, 8, 4], [24, 176, 352, 704, 1024], **kwargs)
      195 
  
  ~/venvs/pytorch_gpu/lib/python3.8/site-packages/torchvision/models/shufflenetv2.py in _shufflenetv2(arch, pretrained, progress, *args, **kwargs)
      145         model_url = model_urls[arch]
      146         if model_url is None:
  --> 147             raise NotImplementedError('pretrained {} is not supported as of now'.format(arch))
      148         else:
      149             state_dict = load_state_dict_from_url(model_url, progress=progress)
  
  NotImplementedError: pretrained shufflenetv2_x1.5 is not supported as of now
```

## Expected behavior

<!-- A clear and concise description of what you expected to happen. -->
Get the pre-trained model of Shufflenet_v2_x1_5 and shufflenet_v2_x2.0. 

## Environment

- PyTorch version: 1.5.1
- Is debug build: False
- CUDA used to build PyTorch: 10.2
- ROCM used to build PyTorch: N/A
- 
- OS: Ubuntu 20.04.1 LTS (x86_64)
- GCC version: (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
- Clang version: Could not collect
- CMake version: Could not collect
- 
- Python version: 3.8 (64-bit runtime)
- Is CUDA available: True
- CUDA runtime version: Could not collect
- GPU models and configuration: GPU 0: GeForce GTX 1660 Ti with Max-Q Design
- Nvidia driver version: 450.102.04
- cuDNN version: Could not collect
- HIP runtime version: N/A
- MIOpen runtime version: N/A
- 
- Versions of relevant libraries:
- [pip3] numpy==1.19.1
- [pip3] torch==1.5.1
- [pip3] torchvision==0.6.1
- [conda] Could not collect

## Additional context
Also tried to get the pre-trained model with:
`model = torch.hub.load('pytorch/vision:v0.6.0', 'shufflenet_v2_x2_0', pretrained=True)`
and it raised:
`RuntimeError: Cannot find callable shufflenet_v2_x2_0 in hubconf`

Hints from issue discussion:
I found that models are unavailable. Model URLs are `None` in lines 13-18 of [shufflenetv2.py](https://github.com/pytorch/vision/blob/master/torchvision/models/shufflenetv2.py):

```
model_urls = {
    'shufflenetv2_x0.5': 'https://download.pytorch.org/models/shufflenetv2_x0.5-f707e7126e.pth',
    'shufflenetv2_x1.0': 'https://download.pytorch.org/models/shufflenetv2_x1-5666bf0f80.pth',
    'shufflenetv2_x1.5': None,
    'shufflenetv2_x2.0': None,
}
```
so it raises the following:
```
if model_url is None:
            raise NotImplementedError('pretrained {} is not supported as of now'.format(arch))
```

at lines 169 and 170 of the same file.

I don't know if this is a bug or it's all ok, so I'll leave it open. 
Hi It is not a bug :sweat_smile: PyTorch is yet to provide Pre Trained weights, for these. Marking for #2707 .
Thank you, I was a little bit confused. So I'll close this.

Commit message: Add to docs

Patch to review:
diff --git a/docs/source/models.rst b/docs/source/models.rst
index 51881e505e4..aeb23d57581 100644
--- a/docs/source/models.rst
+++ b/docs/source/models.rst
@@ -176,8 +176,10 @@ Densenet-201                      76.896          93.370
 Densenet-161                      77.138          93.560
 Inception v3                      77.294          93.450
 GoogleNet                         69.778          89.530
-ShuffleNet V2 x1.0                69.362          88.316
 ShuffleNet V2 x0.5                60.552          81.746
+ShuffleNet V2 x1.0                69.362          88.316
+ShuffleNet V2 x1.5                72.784          91.058
+ShuffleNet V2 x2.0                76.200          92.888
 MobileNet V2                      71.878          90.286
 MobileNet V3 Large                74.042          91.340
 MobileNet V3 Small                67.668          87.402
diff --git a/torchvision/models/shufflenetv2.py b/torchvision/models/shufflenetv2.py
index 68243e06e8f..d5cb76dfec5 100644
--- a/torchvision/models/shufflenetv2.py
+++ b/torchvision/models/shufflenetv2.py
@@ -223,11 +223,37 @@ class ShuffleNet_V2_X1_0_Weights(WeightsEnum):
 
 
 class ShuffleNet_V2_X1_5_Weights(WeightsEnum):
-    pass
+    IMAGENET1K_V1 = Weights(
+        url="https://download.pytorch.org/models/shufflenetv2_x1_5-3c479a10.pth",
+        transforms=partial(ImageClassification, crop_size=224),
+        meta={
+            **_COMMON_META,
+            "recipe": "https://github.com/pytorch/vision/pull/5906",
+            "num_params": 3503624,
+            "metrics": {
+                "acc@1": 72.784,
+                "acc@5": 91.058,
+            },
+        },
+    )
+    DEFAULT = IMAGENET1K_V1
 
 
 class ShuffleNet_V2_X2_0_Weights(WeightsEnum):
-    pass
+    IMAGENET1K_V1 = Weights(
+        url="https://download.pytorch.org/models/shufflenetv2_x2_0-8be3c8ee.pth",
+        transforms=partial(ImageClassification, crop_size=224),
+        meta={
+            **_COMMON_META,
+            "recipe": "https://github.com/pytorch/vision/pull/5906",
+            "num_params": 7393996,
+            "metrics": {
+                "acc@1": 76.200,
+                "acc@5": 92.888,
+            },
+        },
+    )
+    DEFAULT = IMAGENET1K_V1
 
 
 @handle_legacy_interface(weights=("pretrained", ShuffleNet_V2_X0_5_Weights.IMAGENET1K_V1))


Code review comments:
diff_hunk: @@ -223,11 +223,37 @@ class ShuffleNet_V2_X1_0_Weights(WeightsEnum):
 
 
 class ShuffleNet_V2_X1_5_Weights(WeightsEnum):
-    pass
+    IMAGENET1K_V1 = Weights(
+        url="https://download.pytorch.org/models/shufflenetv2_x1_5-3c479a10.pth",
+        transforms=partial(ImageClassification, crop_size=224),
path: torchvision/models/shufflenetv2.py
text: @user1:
In the recipe you mentioned that you used `--val-resize-size=232` but that's not included here. Can you please add it and provide execution runs with the pre-trained weights that confirm the batch-size=1/gpu=1 accuracies?

@author:
Thanks for noticing this! I forgot to add this and as a result the accuracy went down a bit for the eval. I have added this and update the resulting eval as well. The test execution run is on the PR description.