voxel51 / fiftyone

The open-source tool for building high-quality datasets and computer vision models
https://fiftyone.ai
Apache License 2.0
8.1k stars 540 forks source link

[FR] torchvision: use weights instead of depcrecated pretrained parameter #1977

Open brimoor opened 2 years ago

brimoor commented 2 years ago

When loading most Torch models from the FiftyOne Model Zoo with torchvision==0.13.0 installed:

import fiftyone.zoo as foz

model = foz.load_zoo_model("mobilenet-v2-imagenet-torch")

I see the following error:

/path/to/python3.9/site-packages/torchvision/models/_utils.py:208: UserWarning:
The parameter 'pretrained' is deprecated since 0.13 and will be removed in 0.15, please use 'weights' instead.

/path/to/python3.9/site-packages/torchvision/models/_utils.py:223: UserWarning:
Arguments other than a weight enum or `None` for 'weights' are deprecated since 0.13 and will be removed in 0.15. The current behavior is equivalent to passing `weights=MobileNet_V2_Weights.IMAGENET1K_V1`. You can also use `weights=MobileNet_V2_Weights.DEFAULT` to get the most up-to-date weights.

So it looks like, when torchvision==0.15.0 is released (as of this writing, the latest version is 0.13.0 so this isn't a problem yet...), we'll need to follow the above advice and use weights='ResNet50_Weights.DEFAULT' instead of pretrained=True.

Here's where the pretrained=True is currently coming from: https://github.com/voxel51/fiftyone/blob/79fe485ae8da86a7aef156fdf466f6f7d81a7045/fiftyone/zoo/models/manifest-torch.json#L700-L710

Note that, if we're going to update the syntax, we either need to require a sufficiently new torchvision version (unsure if weights was available prior to torchvision==0.13.0, for example), or we need to bake some logic into the code to selectively use the appropriate parameter based on the installed torchvision version...

n3ry7 commented 1 year ago

I would like to solve this issue as my first contribution. I tried to replicate the issue but I got another error instead.

Traceback (most recent call last): File "/home/nery/test.py", line 4, in model = foz.load_zoo_model("mobilenet-v2-imagenet-torch") File "/home/nery/fiftyone/fiftyone/zoo/models/init.py", line 188, in load_zoo_model error_level = fo.config.requirement_error_level AttributeError: module 'fiftyone' has no attribute 'config'

brimoor commented 1 year ago

Glad you're interested in contributing to the project! πŸ™Œ

I believe this issue contains the fix for your dev environment: https://github.com/voxel51/fiftyone/issues/2154

brimoor commented 1 year ago

Related conversation: https://fiftyone-users.slack.com/archives/C0189A476EQ/p1673357874994249

ai2ys commented 1 year ago

When loading most Torch models from the FiftyOne Model Zoo with torchvision==0.13.0 installed:

import fiftyone.zoo as foz

model = foz.load_zoo_model("mobilenet-v2-imagenet-torch")

I see the following error:

/path/to/python3.9/site-packages/torchvision/models/_utils.py:208: UserWarning:
The parameter 'pretrained' is deprecated since 0.13 and will be removed in 0.15, please use 'weights' instead.

/path/to/python3.9/site-packages/torchvision/models/_utils.py:223: UserWarning:
Arguments other than a weight enum or `None` for 'weights' are deprecated since 0.13 and will be removed in 0.15. The current behavior is equivalent to passing `weights=MobileNet_V2_Weights.IMAGENET1K_V1`. You can also use `weights=MobileNet_V2_Weights.DEFAULT` to get the most up-to-date weights.

So it looks like, when torchvision==0.15.0 is released (as of this writing, the latest version is 0.13.0 so this isn't a problem yet...), we'll need to follow the above advice and use weights='ResNet50_Weights.DEFAULT' instead of pretrained=True.

Here's where the pretrained=True is currently coming from:

https://github.com/voxel51/fiftyone/blob/79fe485ae8da86a7aef156fdf466f6f7d81a7045/fiftyone/zoo/models/manifest-torch.json#L700-L710

Note that, if we're going to update the syntax, we either need to require a sufficiently new torchvision version (unsure if weights was available prior to torchvision==0.13.0, for example), or we need to bake some logic into the code to selectively use the appropriate parameter based on the installed torchvision version...

Just checked on availability of parameter weights for torchvision version 0.12.0. There only the parameter pretrained is available. https://github.com/pytorch/vision/blob/v0.12.0/torchvision/models/mobilenetv2.py

helioshe4 commented 1 year ago

Hi, is this still an ongoing issue? I'd be willing to look into it and try and fix it.

brimoor commented 1 year ago

@helioshe4 a contribution would be welcome, thanks! The problem here is that we need to support these two syntaxes:

# torchvision < 0.13
model = torchvision.models.mobilenet.mobilenet_v2(pretrained=True)

# torchvision >= 0.13
model = torchvision.models.mobilenet.mobilenet_v2(weights=ResNet50_Weights.DEFAULT)

I suppose we could just update the manifest JSON to use weights instead of pretrained everywhere, and then add a torchvision>=0.13 requirement.

For bonus points, perhaps you could add a check in this function that would replace weights=XXX with pretrained=True only when torchvision<0.13 is installed. So that we would not have to strictly require torchvision>=0.13 πŸ˜„

helioshe4 commented 1 year ago

Hello @brimoor , just wanted to check in. An example warning when I use pretrained=True prints

The current behavior is equivalent to passing `weights=DeepLabV3_ResNet101_Weights.COCO_WITH_VOC_LABELS_V1`. 
You can also use `weights=DeepLabV3_ResNet101_Weights.DEFAULT` to get the most up-to-date weights.

Should I replace the pretrained:true in the manifest-torch json file using the "equivalent" (in this case, DeepLabV3_ResNet101_Weights.COCO_WITH_VOC_LABELS_V1') weights, or the .DEFAULT weights?

PyTorch docs says the two are the same, but I guess that would change if the weights ever get updated. https://pytorch.org/vision/main/models/generated/torchvision.models.segmentation.deeplabv3_resnet101.html

This is what I've done as of now thats running with no warnings:

"base_name": "alexnet-imagenet-torch",
            "base_filename": "alexnet-owt-4df8aa71.pth",
            "version": null,
            "description": "AlexNet model architecture from `One weird trick for parallelizing convolutional neural networks <https://arxiv.org/abs/1404.5997>`_ trained on ImageNet",
            "source": "https://pytorch.org/vision/main/models.html",
            "size_bytes": 244418560,
            "manager": {
                "type": "fiftyone.core.models.ModelManager",
                "config": {
                    "url": "https://download.pytorch.org/models/alexnet-owt-4df8aa71.pth"
                }
            },
            "default_deployment_config_dict": {
                "type": "fiftyone.zoo.models.torch.TorchvisionImageModel",
                "config": {
                    "entrypoint_fcn": "torchvision.models.alexnet.alexnet",
                     // ********** WEIGHT CHANGE HERE **********
                    "entrypoint_args": { "weights": "AlexNet_Weights.IMAGENET1K_V1" }, 
                    "output_processor_cls": "fiftyone.utils.torch.ClassifierOutputProcessor",
                    "labels_path": "{{eta-resources}}/imagenet-labels-no-background.txt",
                    "image_min_dim": 224,
                    "image_max_dim": 2048,
                    "image_mean": [0.485, 0.456, 0.406],
                    "image_std": [0.229, 0.224, 0.225],
                    "embeddings_layer": "<classifier.6"
                }
            }

I hope that made sense. Thanks

brimoor commented 1 year ago

I think using .DEFAULT is a good idea because it will make the code more future-proof. If torchvision authors decide to update the the default weights, FiftyOne users will likely want the same update.

helioshe4 commented 1 year ago

Hello @brimoor , I've submitted a pr here #3348

Ibnathism commented 10 months ago

@helioshe4 a contribution would be welcome, thanks! The problem here is that we need to support these two syntaxes:

# torchvision < 0.13
model = torchvision.models.mobilenet.mobilenet_v2(pretrained=True)

# torchvision >= 0.13
model = torchvision.models.mobilenet.mobilenet_v2(weights=ResNet50_Weights.DEFAULT)

I suppose we could just update the manifest JSON to use weights instead of pretrained everywhere, and then add a torchvision>=0.13 requirement.

For bonus points, perhaps you could add a check in this function that would replace weights=XXX with pretrained=True only when torchvision<0.13 is installed. So that we would not have to strictly require torchvision>=0.13 πŸ˜„

Hey, I need to make pretrained = False. What should I do in that case?

brimoor commented 10 months ago

@Ibnathism here's a couple helpful resources depending on what you're waning to achieve: