From 31fadbee7d1a65cd73ae43dfd4ac6e97e7ca7b01 Mon Sep 17 00:00:00 2001 From: Joao Gomes Date: Fri, 29 Oct 2021 10:32:46 +0100 Subject: [PATCH 1/9] Adding multiweight support for shufflenetv2 prototype models --- torchvision/prototype/models/__init__.py | 1 + torchvision/prototype/models/shufflenetv2.py | 121 +++++++++++++++++++ 2 files changed, 122 insertions(+) create mode 100644 torchvision/prototype/models/shufflenetv2.py diff --git a/torchvision/prototype/models/__init__.py b/torchvision/prototype/models/__init__.py index a187af7f090..399280eaff7 100644 --- a/torchvision/prototype/models/__init__.py +++ b/torchvision/prototype/models/__init__.py @@ -5,6 +5,7 @@ from .efficientnet import * from .mobilenetv3 import * from .mnasnet import * +from .shufflenetv2 import * from . import detection from . import quantization from . import segmentation diff --git a/torchvision/prototype/models/shufflenetv2.py b/torchvision/prototype/models/shufflenetv2.py new file mode 100644 index 00000000000..d6d02873051 --- /dev/null +++ b/torchvision/prototype/models/shufflenetv2.py @@ -0,0 +1,121 @@ +import warnings +from functools import partial +from typing import Any, Optional + +from torchvision.transforms.functional import InterpolationMode + +from ...models.shufflenetv2 import ShuffleNetV2 +from ..transforms.presets import ImageNetEval +from ._api import Weights, WeightEntry +from ._meta import _IMAGENET_CATEGORIES + + +__all__ = [ + "ShuffleNetV2", + "ShuffleNetV2_x0_5Weights", + "ShuffleNetV2_x1_0Weights", + "ShuffleNetV2_x1_5Weights", + "ShuffleNetV2_x2_0Weights", + "shufflenet_v2_x0_5", + "shufflenet_v2_x1_0", + "shufflenet_v2_x1_5", + "shufflenet_v2_x2_0", +] + + +def _shufflenetv2( + weights: Optional[Weights], + progress: bool, + *args: Any, + **kwargs: Any, +) -> ShuffleNetV2: + if weights is not None: + kwargs["num_classes"] = len(weights.meta["categories"]) + + model = ShuffleNetV2(*args, **kwargs) + + if weights is not None: + model.load_state_dict(weights.state_dict(progress=progress)) + + return model + + +_common_meta = {"size": (224, 224), "categories": _IMAGENET_CATEGORIES, "interpolation": InterpolationMode.BILINEAR} + + +class ShuffleNetV2_x0_5Weights(Weights): + ImageNet1K_RefV1 = WeightEntry( + url="https://download.pytorch.org/models/shufflenetv2_x0.5-f707e7126e.pth", + transforms=partial(ImageNetEval, crop_size=224), + meta={ + **_common_meta, + "recipe": "", + "acc@1": 69.362, + "acc@5": 88.316, + }, + ) + + +class ShuffleNetV2_x1_0Weights(Weights): + ImageNet1K_RefV1 = WeightEntry( + url="https://download.pytorch.org/models/shufflenetv2_x1-5666bf0f80.pth", + transforms=partial(ImageNetEval, crop_size=224), + meta={ + **_common_meta, + "recipe": "", + "acc@1": 60.552, + "acc@5": 81.746, + }, + ) + + +class ShuffleNetV2_x1_5Weights(Weights): + pass + + +class ShuffleNetV2_x2_0Weights(Weights): + pass + + +def shufflenet_v2_x0_5( + weights: Optional[ShuffleNetV2_x0_5Weights] = None, progress: bool = True, **kwargs: Any +) -> ShuffleNetV2: + if "pretrained" in kwargs: + warnings.warn("The argument pretrained is deprecated, please use weights instead.") + weights = ShuffleNetV2_x0_5Weights.ImageNet1K_RefV1 if kwargs.pop("pretrained") else None + weights = ShuffleNetV2_x0_5Weights.verify(weights) + + return _shufflenetv2(weights, progress, [4, 8, 4], [24, 48, 96, 192, 1024], **kwargs) + + +def shufflenet_v2_x1_0( + weights: Optional[ShuffleNetV2_x1_0Weights] = None, progress: bool = True, **kwargs: Any +) -> ShuffleNetV2: + if "pretrained" in kwargs: + warnings.warn("The argument pretrained is deprecated, please use weights instead.") + weights = ShuffleNetV2_x1_0Weights.ImageNet1K_RefV1 if kwargs.pop("pretrained") else None + weights = ShuffleNetV2_x1_0Weights.verify(weights) + + return _shufflenetv2(weights, progress, [4, 8, 4], [24, 116, 232, 464, 1024], **kwargs) + + +def shufflenet_v2_x1_5( + weights: Optional[ShuffleNetV2_x1_5Weights] = None, progress: bool = True, **kwargs: Any +) -> ShuffleNetV2: + if "pretrained" in kwargs: + warnings.warn("The argument pretrained is deprecated, please use weights instead.") + weights = ShuffleNetV2_x1_5Weights.ImageNet1K_RefV1 if kwargs.pop("pretrained") else None + weights = ShuffleNetV2_x1_5Weights.verify(weights) + + return _shufflenetv2(weights, progress, [4, 8, 4], [24, 176, 352, 704, 1024], **kwargs) + + +def shufflenet_v2_x2_0( + weights: Optional[ShuffleNetV2_x2_0Weights] = None, progress: bool = True, **kwargs: Any +) -> ShuffleNetV2: + if "pretrained" in kwargs: + warnings.warn("The argument pretrained is deprecated, please use weights instead.") + weights = ShuffleNetV2_x2_0Weights.ImageNet1K_RefV1 if kwargs.pop("pretrained") else None + weights = ShuffleNetV2_x2_0Weights.verify(weights) + + return _shufflenetv2(weights, progress, [4, 8, 4], [24, 244, 488, 976, 2048], **kwargs) From 1e578b7fe05ff5a18201df8a36b552a18fabcd08 Mon Sep 17 00:00:00 2001 From: Joao Gomes Date: Fri, 29 Oct 2021 10:42:31 +0100 Subject: [PATCH 2/9] Revert "Adding multiweight support for shufflenetv2 prototype models" This reverts commit 31fadbee7d1a65cd73ae43dfd4ac6e97e7ca7b01. --- torchvision/prototype/models/__init__.py | 1 - torchvision/prototype/models/shufflenetv2.py | 121 ------------------- 2 files changed, 122 deletions(-) delete mode 100644 torchvision/prototype/models/shufflenetv2.py diff --git a/torchvision/prototype/models/__init__.py b/torchvision/prototype/models/__init__.py index 399280eaff7..a187af7f090 100644 --- a/torchvision/prototype/models/__init__.py +++ b/torchvision/prototype/models/__init__.py @@ -5,7 +5,6 @@ from .efficientnet import * from .mobilenetv3 import * from .mnasnet import * -from .shufflenetv2 import * from . import detection from . import quantization from . import segmentation diff --git a/torchvision/prototype/models/shufflenetv2.py b/torchvision/prototype/models/shufflenetv2.py deleted file mode 100644 index d6d02873051..00000000000 --- a/torchvision/prototype/models/shufflenetv2.py +++ /dev/null @@ -1,121 +0,0 @@ -import warnings -from functools import partial -from typing import Any, Optional - -from torchvision.transforms.functional import InterpolationMode - -from ...models.shufflenetv2 import ShuffleNetV2 -from ..transforms.presets import ImageNetEval -from ._api import Weights, WeightEntry -from ._meta import _IMAGENET_CATEGORIES - - -__all__ = [ - "ShuffleNetV2", - "ShuffleNetV2_x0_5Weights", - "ShuffleNetV2_x1_0Weights", - "ShuffleNetV2_x1_5Weights", - "ShuffleNetV2_x2_0Weights", - "shufflenet_v2_x0_5", - "shufflenet_v2_x1_0", - "shufflenet_v2_x1_5", - "shufflenet_v2_x2_0", -] - - -def _shufflenetv2( - weights: Optional[Weights], - progress: bool, - *args: Any, - **kwargs: Any, -) -> ShuffleNetV2: - if weights is not None: - kwargs["num_classes"] = len(weights.meta["categories"]) - - model = ShuffleNetV2(*args, **kwargs) - - if weights is not None: - model.load_state_dict(weights.state_dict(progress=progress)) - - return model - - -_common_meta = {"size": (224, 224), "categories": _IMAGENET_CATEGORIES, "interpolation": InterpolationMode.BILINEAR} - - -class ShuffleNetV2_x0_5Weights(Weights): - ImageNet1K_RefV1 = WeightEntry( - url="https://download.pytorch.org/models/shufflenetv2_x0.5-f707e7126e.pth", - transforms=partial(ImageNetEval, crop_size=224), - meta={ - **_common_meta, - "recipe": "", - "acc@1": 69.362, - "acc@5": 88.316, - }, - ) - - -class ShuffleNetV2_x1_0Weights(Weights): - ImageNet1K_RefV1 = WeightEntry( - url="https://download.pytorch.org/models/shufflenetv2_x1-5666bf0f80.pth", - transforms=partial(ImageNetEval, crop_size=224), - meta={ - **_common_meta, - "recipe": "", - "acc@1": 60.552, - "acc@5": 81.746, - }, - ) - - -class ShuffleNetV2_x1_5Weights(Weights): - pass - - -class ShuffleNetV2_x2_0Weights(Weights): - pass - - -def shufflenet_v2_x0_5( - weights: Optional[ShuffleNetV2_x0_5Weights] = None, progress: bool = True, **kwargs: Any -) -> ShuffleNetV2: - if "pretrained" in kwargs: - warnings.warn("The argument pretrained is deprecated, please use weights instead.") - weights = ShuffleNetV2_x0_5Weights.ImageNet1K_RefV1 if kwargs.pop("pretrained") else None - weights = ShuffleNetV2_x0_5Weights.verify(weights) - - return _shufflenetv2(weights, progress, [4, 8, 4], [24, 48, 96, 192, 1024], **kwargs) - - -def shufflenet_v2_x1_0( - weights: Optional[ShuffleNetV2_x1_0Weights] = None, progress: bool = True, **kwargs: Any -) -> ShuffleNetV2: - if "pretrained" in kwargs: - warnings.warn("The argument pretrained is deprecated, please use weights instead.") - weights = ShuffleNetV2_x1_0Weights.ImageNet1K_RefV1 if kwargs.pop("pretrained") else None - weights = ShuffleNetV2_x1_0Weights.verify(weights) - - return _shufflenetv2(weights, progress, [4, 8, 4], [24, 116, 232, 464, 1024], **kwargs) - - -def shufflenet_v2_x1_5( - weights: Optional[ShuffleNetV2_x1_5Weights] = None, progress: bool = True, **kwargs: Any -) -> ShuffleNetV2: - if "pretrained" in kwargs: - warnings.warn("The argument pretrained is deprecated, please use weights instead.") - weights = ShuffleNetV2_x1_5Weights.ImageNet1K_RefV1 if kwargs.pop("pretrained") else None - weights = ShuffleNetV2_x1_5Weights.verify(weights) - - return _shufflenetv2(weights, progress, [4, 8, 4], [24, 176, 352, 704, 1024], **kwargs) - - -def shufflenet_v2_x2_0( - weights: Optional[ShuffleNetV2_x2_0Weights] = None, progress: bool = True, **kwargs: Any -) -> ShuffleNetV2: - if "pretrained" in kwargs: - warnings.warn("The argument pretrained is deprecated, please use weights instead.") - weights = ShuffleNetV2_x2_0Weights.ImageNet1K_RefV1 if kwargs.pop("pretrained") else None - weights = ShuffleNetV2_x2_0Weights.verify(weights) - - return _shufflenetv2(weights, progress, [4, 8, 4], [24, 244, 488, 976, 2048], **kwargs) From 4e3d900f796c1e3e667312087e77956ca4a4c017 Mon Sep 17 00:00:00 2001 From: Joao Gomes Date: Fri, 29 Oct 2021 10:59:31 +0100 Subject: [PATCH 3/9] Adding multiweight support for shufflenetv2 prototype models --- torchvision/prototype/models/__init__.py | 1 + torchvision/prototype/models/shufflenetv2.py | 121 +++++++++++++++++++ 2 files changed, 122 insertions(+) create mode 100644 torchvision/prototype/models/shufflenetv2.py diff --git a/torchvision/prototype/models/__init__.py b/torchvision/prototype/models/__init__.py index 264d787d40e..69fe4310606 100644 --- a/torchvision/prototype/models/__init__.py +++ b/torchvision/prototype/models/__init__.py @@ -7,6 +7,7 @@ from .mobilenetv2 import * from .mnasnet import * from .regnet import * +from .shufflenetv2 import * from . import detection from . import quantization from . import segmentation diff --git a/torchvision/prototype/models/shufflenetv2.py b/torchvision/prototype/models/shufflenetv2.py new file mode 100644 index 00000000000..d6d02873051 --- /dev/null +++ b/torchvision/prototype/models/shufflenetv2.py @@ -0,0 +1,121 @@ +import warnings +from functools import partial +from typing import Any, Optional + +from torchvision.transforms.functional import InterpolationMode + +from ...models.shufflenetv2 import ShuffleNetV2 +from ..transforms.presets import ImageNetEval +from ._api import Weights, WeightEntry +from ._meta import _IMAGENET_CATEGORIES + + +__all__ = [ + "ShuffleNetV2", + "ShuffleNetV2_x0_5Weights", + "ShuffleNetV2_x1_0Weights", + "ShuffleNetV2_x1_5Weights", + "ShuffleNetV2_x2_0Weights", + "shufflenet_v2_x0_5", + "shufflenet_v2_x1_0", + "shufflenet_v2_x1_5", + "shufflenet_v2_x2_0", +] + + +def _shufflenetv2( + weights: Optional[Weights], + progress: bool, + *args: Any, + **kwargs: Any, +) -> ShuffleNetV2: + if weights is not None: + kwargs["num_classes"] = len(weights.meta["categories"]) + + model = ShuffleNetV2(*args, **kwargs) + + if weights is not None: + model.load_state_dict(weights.state_dict(progress=progress)) + + return model + + +_common_meta = {"size": (224, 224), "categories": _IMAGENET_CATEGORIES, "interpolation": InterpolationMode.BILINEAR} + + +class ShuffleNetV2_x0_5Weights(Weights): + ImageNet1K_RefV1 = WeightEntry( + url="https://download.pytorch.org/models/shufflenetv2_x0.5-f707e7126e.pth", + transforms=partial(ImageNetEval, crop_size=224), + meta={ + **_common_meta, + "recipe": "", + "acc@1": 69.362, + "acc@5": 88.316, + }, + ) + + +class ShuffleNetV2_x1_0Weights(Weights): + ImageNet1K_RefV1 = WeightEntry( + url="https://download.pytorch.org/models/shufflenetv2_x1-5666bf0f80.pth", + transforms=partial(ImageNetEval, crop_size=224), + meta={ + **_common_meta, + "recipe": "", + "acc@1": 60.552, + "acc@5": 81.746, + }, + ) + + +class ShuffleNetV2_x1_5Weights(Weights): + pass + + +class ShuffleNetV2_x2_0Weights(Weights): + pass + + +def shufflenet_v2_x0_5( + weights: Optional[ShuffleNetV2_x0_5Weights] = None, progress: bool = True, **kwargs: Any +) -> ShuffleNetV2: + if "pretrained" in kwargs: + warnings.warn("The argument pretrained is deprecated, please use weights instead.") + weights = ShuffleNetV2_x0_5Weights.ImageNet1K_RefV1 if kwargs.pop("pretrained") else None + weights = ShuffleNetV2_x0_5Weights.verify(weights) + + return _shufflenetv2(weights, progress, [4, 8, 4], [24, 48, 96, 192, 1024], **kwargs) + + +def shufflenet_v2_x1_0( + weights: Optional[ShuffleNetV2_x1_0Weights] = None, progress: bool = True, **kwargs: Any +) -> ShuffleNetV2: + if "pretrained" in kwargs: + warnings.warn("The argument pretrained is deprecated, please use weights instead.") + weights = ShuffleNetV2_x1_0Weights.ImageNet1K_RefV1 if kwargs.pop("pretrained") else None + weights = ShuffleNetV2_x1_0Weights.verify(weights) + + return _shufflenetv2(weights, progress, [4, 8, 4], [24, 116, 232, 464, 1024], **kwargs) + + +def shufflenet_v2_x1_5( + weights: Optional[ShuffleNetV2_x1_5Weights] = None, progress: bool = True, **kwargs: Any +) -> ShuffleNetV2: + if "pretrained" in kwargs: + warnings.warn("The argument pretrained is deprecated, please use weights instead.") + weights = ShuffleNetV2_x1_5Weights.ImageNet1K_RefV1 if kwargs.pop("pretrained") else None + weights = ShuffleNetV2_x1_5Weights.verify(weights) + + return _shufflenetv2(weights, progress, [4, 8, 4], [24, 176, 352, 704, 1024], **kwargs) + + +def shufflenet_v2_x2_0( + weights: Optional[ShuffleNetV2_x2_0Weights] = None, progress: bool = True, **kwargs: Any +) -> ShuffleNetV2: + if "pretrained" in kwargs: + warnings.warn("The argument pretrained is deprecated, please use weights instead.") + weights = ShuffleNetV2_x2_0Weights.ImageNet1K_RefV1 if kwargs.pop("pretrained") else None + weights = ShuffleNetV2_x2_0Weights.verify(weights) + + return _shufflenetv2(weights, progress, [4, 8, 4], [24, 244, 488, 976, 2048], **kwargs) From 615b612933c1dea2da471ac5678bd4ec97e5255f Mon Sep 17 00:00:00 2001 From: Joao Gomes Date: Fri, 29 Oct 2021 11:14:45 +0100 Subject: [PATCH 4/9] Revert "Adding multiweight support for shufflenetv2 prototype models" This reverts commit 4e3d900f796c1e3e667312087e77956ca4a4c017. --- torchvision/prototype/models/__init__.py | 1 - torchvision/prototype/models/shufflenetv2.py | 121 ------------------- 2 files changed, 122 deletions(-) delete mode 100644 torchvision/prototype/models/shufflenetv2.py diff --git a/torchvision/prototype/models/__init__.py b/torchvision/prototype/models/__init__.py index 69fe4310606..264d787d40e 100644 --- a/torchvision/prototype/models/__init__.py +++ b/torchvision/prototype/models/__init__.py @@ -7,7 +7,6 @@ from .mobilenetv2 import * from .mnasnet import * from .regnet import * -from .shufflenetv2 import * from . import detection from . import quantization from . import segmentation diff --git a/torchvision/prototype/models/shufflenetv2.py b/torchvision/prototype/models/shufflenetv2.py deleted file mode 100644 index d6d02873051..00000000000 --- a/torchvision/prototype/models/shufflenetv2.py +++ /dev/null @@ -1,121 +0,0 @@ -import warnings -from functools import partial -from typing import Any, Optional - -from torchvision.transforms.functional import InterpolationMode - -from ...models.shufflenetv2 import ShuffleNetV2 -from ..transforms.presets import ImageNetEval -from ._api import Weights, WeightEntry -from ._meta import _IMAGENET_CATEGORIES - - -__all__ = [ - "ShuffleNetV2", - "ShuffleNetV2_x0_5Weights", - "ShuffleNetV2_x1_0Weights", - "ShuffleNetV2_x1_5Weights", - "ShuffleNetV2_x2_0Weights", - "shufflenet_v2_x0_5", - "shufflenet_v2_x1_0", - "shufflenet_v2_x1_5", - "shufflenet_v2_x2_0", -] - - -def _shufflenetv2( - weights: Optional[Weights], - progress: bool, - *args: Any, - **kwargs: Any, -) -> ShuffleNetV2: - if weights is not None: - kwargs["num_classes"] = len(weights.meta["categories"]) - - model = ShuffleNetV2(*args, **kwargs) - - if weights is not None: - model.load_state_dict(weights.state_dict(progress=progress)) - - return model - - -_common_meta = {"size": (224, 224), "categories": _IMAGENET_CATEGORIES, "interpolation": InterpolationMode.BILINEAR} - - -class ShuffleNetV2_x0_5Weights(Weights): - ImageNet1K_RefV1 = WeightEntry( - url="https://download.pytorch.org/models/shufflenetv2_x0.5-f707e7126e.pth", - transforms=partial(ImageNetEval, crop_size=224), - meta={ - **_common_meta, - "recipe": "", - "acc@1": 69.362, - "acc@5": 88.316, - }, - ) - - -class ShuffleNetV2_x1_0Weights(Weights): - ImageNet1K_RefV1 = WeightEntry( - url="https://download.pytorch.org/models/shufflenetv2_x1-5666bf0f80.pth", - transforms=partial(ImageNetEval, crop_size=224), - meta={ - **_common_meta, - "recipe": "", - "acc@1": 60.552, - "acc@5": 81.746, - }, - ) - - -class ShuffleNetV2_x1_5Weights(Weights): - pass - - -class ShuffleNetV2_x2_0Weights(Weights): - pass - - -def shufflenet_v2_x0_5( - weights: Optional[ShuffleNetV2_x0_5Weights] = None, progress: bool = True, **kwargs: Any -) -> ShuffleNetV2: - if "pretrained" in kwargs: - warnings.warn("The argument pretrained is deprecated, please use weights instead.") - weights = ShuffleNetV2_x0_5Weights.ImageNet1K_RefV1 if kwargs.pop("pretrained") else None - weights = ShuffleNetV2_x0_5Weights.verify(weights) - - return _shufflenetv2(weights, progress, [4, 8, 4], [24, 48, 96, 192, 1024], **kwargs) - - -def shufflenet_v2_x1_0( - weights: Optional[ShuffleNetV2_x1_0Weights] = None, progress: bool = True, **kwargs: Any -) -> ShuffleNetV2: - if "pretrained" in kwargs: - warnings.warn("The argument pretrained is deprecated, please use weights instead.") - weights = ShuffleNetV2_x1_0Weights.ImageNet1K_RefV1 if kwargs.pop("pretrained") else None - weights = ShuffleNetV2_x1_0Weights.verify(weights) - - return _shufflenetv2(weights, progress, [4, 8, 4], [24, 116, 232, 464, 1024], **kwargs) - - -def shufflenet_v2_x1_5( - weights: Optional[ShuffleNetV2_x1_5Weights] = None, progress: bool = True, **kwargs: Any -) -> ShuffleNetV2: - if "pretrained" in kwargs: - warnings.warn("The argument pretrained is deprecated, please use weights instead.") - weights = ShuffleNetV2_x1_5Weights.ImageNet1K_RefV1 if kwargs.pop("pretrained") else None - weights = ShuffleNetV2_x1_5Weights.verify(weights) - - return _shufflenetv2(weights, progress, [4, 8, 4], [24, 176, 352, 704, 1024], **kwargs) - - -def shufflenet_v2_x2_0( - weights: Optional[ShuffleNetV2_x2_0Weights] = None, progress: bool = True, **kwargs: Any -) -> ShuffleNetV2: - if "pretrained" in kwargs: - warnings.warn("The argument pretrained is deprecated, please use weights instead.") - weights = ShuffleNetV2_x2_0Weights.ImageNet1K_RefV1 if kwargs.pop("pretrained") else None - weights = ShuffleNetV2_x2_0Weights.verify(weights) - - return _shufflenetv2(weights, progress, [4, 8, 4], [24, 244, 488, 976, 2048], **kwargs) From c9d24bea31b2ba238ee2a654cdda58e5c7b5848a Mon Sep 17 00:00:00 2001 From: Joao Gomes Date: Mon, 1 Nov 2021 12:19:00 +0000 Subject: [PATCH 5/9] Expose misc ops at package level --- torchvision/ops/__init__.py | 4 ++++ torchvision/ops/misc.py | 10 ---------- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/torchvision/ops/__init__.py b/torchvision/ops/__init__.py index 0acd5fe990f..d5cdf39d20f 100644 --- a/torchvision/ops/__init__.py +++ b/torchvision/ops/__init__.py @@ -13,6 +13,7 @@ from .deform_conv import deform_conv2d, DeformConv2d from .feature_pyramid_network import FeaturePyramidNetwork from .focal_loss import sigmoid_focal_loss +from .misc import FrozenBatchNorm2d, ConvNormActivation, SqueezeExcitation from .poolers import MultiScaleRoIAlign from .ps_roi_align import ps_roi_align, PSRoIAlign from .ps_roi_pool import ps_roi_pool, PSRoIPool @@ -48,4 +49,7 @@ "sigmoid_focal_loss", "stochastic_depth", "StochasticDepth", + "FrozenBatchNorm2d", + "ConvNormActivation", + "SqueezeExcitation", ] diff --git a/torchvision/ops/misc.py b/torchvision/ops/misc.py index 3c344a8c5ce..c90b491e12f 100644 --- a/torchvision/ops/misc.py +++ b/torchvision/ops/misc.py @@ -1,13 +1,3 @@ -""" -helper class that supports empty tensors on some nn functions. - -Ideally, add support directly in PyTorch to empty tensors in -those functions. - -This can be removed once https://github.com/pytorch/pytorch/issues/12013 -is implemented -""" - import warnings from typing import Callable, List, Optional From 2b567491e8c483a3c2bc39fc1438db031fbfe8ce Mon Sep 17 00:00:00 2001 From: Joao Gomes Date: Mon, 1 Nov 2021 17:33:22 +0000 Subject: [PATCH 6/9] Adding documentation to the ops exposed --- docs/source/ops.rst | 3 +++ torchvision/ops/misc.py | 37 ++++++++++++++++++++++++++++++++++--- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/docs/source/ops.rst b/docs/source/ops.rst index 6b215572900..9dbcd525861 100644 --- a/docs/source/ops.rst +++ b/docs/source/ops.rst @@ -43,3 +43,6 @@ Operators MultiScaleRoIAlign FeaturePyramidNetwork StochasticDepth + FrozenBatchNorm2d + ConvNormActivation + SqueezeExcitation \ No newline at end of file diff --git a/torchvision/ops/misc.py b/torchvision/ops/misc.py index c90b491e12f..0bf92f2aaa6 100644 --- a/torchvision/ops/misc.py +++ b/torchvision/ops/misc.py @@ -43,8 +43,11 @@ def __init__(self, *args, **kwargs): # This is not in nn class FrozenBatchNorm2d(torch.nn.Module): """ - BatchNorm2d where the batch statistics and the affine parameters - are fixed + BatchNorm2d where the batch statistics and the affine parameters are fixed + + Args: + num_features (int): Number of features ``C`` from an expected input of size ``(N, C, H, W)`` + eps (float): a value added to the denominator for numerical stability. Default: 1e-5 """ def __init__( @@ -99,12 +102,29 @@ def __repr__(self) -> str: class ConvNormActivation(torch.nn.Sequential): + """ + Configurable block used for Convolution-Normalzation-Activation blocks. + + Args: + in_channels (int): Number of channels in the input image + out_channels (int): Number of channels produced by the Convolution-Normalzation-Activation block + kernel_size: (int, optional): Size of the convolving kernel. Default: 3 + stride (int or tuple, optional): Stride of the convolution. Default: 1 + padding (int, tuple or str, optional): Padding added to all four sides of the input. Default: None, in wich case it will calculated as ``padding = (kernel_size - 1) // 2 * dilation`` + groups (int, optional): Number of blocked connections from input channels to output channels. Default: 1 + norm_layer (Callable[..., torch.nn.Module], optional): Norm layer that will be stacked on top of the convolutiuon layer. If ``None`` this layer wont be used. Default: ``torch.nn.BatchNorm2d`` + activation_layer (Callable[..., torch.nn.Module], optinal): Activation function which will be stacked on top of the normalization layer (if not None), otherwise on top of the conv layer. If ``None`` this layer wont be used. Default: ``torch.nn.ReLU`` + dilation (int): Spacing between kernel elements. Default: 1 + inplace (bool): Parameter for the activation layer, which can optionally do the operation in-place. Default ``True`` + + """ + def __init__( self, in_channels: int, out_channels: int, kernel_size: int = 3, - stride: int = 1, + stride: _size_2_t = 1, padding: Optional[int] = None, groups: int = 1, norm_layer: Optional[Callable[..., torch.nn.Module]] = torch.nn.BatchNorm2d, @@ -136,6 +156,17 @@ def __init__( class SqueezeExcitation(torch.nn.Module): + """ + This block implements the Squeeze-and-Excitation block from https://arxiv.org/abs/1709.01507 (see Fig. 1). + Parameters ``activation``, and `scale_activation`` correspond to ``delta`` and ``sigma`` in in eq. 3. + + Args: + input_channels (int): Number of channels in the input image + squeeze_channels (int): Number of squeeze channels + activation (Callable[..., torch.nn.Module], optional): ``delta`` activation. Default: ``torch.nn.ReLU`` + scale_activation (Callable[..., torch.nn.Module]): ``sigma`` activation. Default: ``torch.nn.Sigmoid`` + """ + def __init__( self, input_channels: int, From 91b1e9a34532e81e72b75941bc3123c2811e1418 Mon Sep 17 00:00:00 2001 From: Joao Gomes Date: Mon, 1 Nov 2021 17:46:40 +0000 Subject: [PATCH 7/9] Adding missing import --- torchvision/ops/misc.py | 1 + 1 file changed, 1 insertion(+) diff --git a/torchvision/ops/misc.py b/torchvision/ops/misc.py index 0bf92f2aaa6..f9fb16061e9 100644 --- a/torchvision/ops/misc.py +++ b/torchvision/ops/misc.py @@ -3,6 +3,7 @@ import torch from torch import Tensor +from torch.nn.common_types import _size_2_t from ..utils import _log_api_usage_once From cb90dbf32c4ceab870fee2259bc5f2095841762d Mon Sep 17 00:00:00 2001 From: Joao Gomes Date: Tue, 2 Nov 2021 09:25:52 +0000 Subject: [PATCH 8/9] Addressing PR comments --- torchvision/ops/misc.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/torchvision/ops/misc.py b/torchvision/ops/misc.py index f9fb16061e9..e7bf77e9970 100644 --- a/torchvision/ops/misc.py +++ b/torchvision/ops/misc.py @@ -3,7 +3,6 @@ import torch from torch import Tensor -from torch.nn.common_types import _size_2_t from ..utils import _log_api_usage_once @@ -110,7 +109,7 @@ class ConvNormActivation(torch.nn.Sequential): in_channels (int): Number of channels in the input image out_channels (int): Number of channels produced by the Convolution-Normalzation-Activation block kernel_size: (int, optional): Size of the convolving kernel. Default: 3 - stride (int or tuple, optional): Stride of the convolution. Default: 1 + stride (int, optional): Stride of the convolution. Default: 1 padding (int, tuple or str, optional): Padding added to all four sides of the input. Default: None, in wich case it will calculated as ``padding = (kernel_size - 1) // 2 * dilation`` groups (int, optional): Number of blocked connections from input channels to output channels. Default: 1 norm_layer (Callable[..., torch.nn.Module], optional): Norm layer that will be stacked on top of the convolutiuon layer. If ``None`` this layer wont be used. Default: ``torch.nn.BatchNorm2d`` @@ -125,7 +124,7 @@ def __init__( in_channels: int, out_channels: int, kernel_size: int = 3, - stride: _size_2_t = 1, + stride: int = 1, padding: Optional[int] = None, groups: int = 1, norm_layer: Optional[Callable[..., torch.nn.Module]] = torch.nn.BatchNorm2d, From 5173291d0b7cd0766e50030d3c3e47907c8b00b3 Mon Sep 17 00:00:00 2001 From: Joao Gomes Date: Tue, 2 Nov 2021 09:25:52 +0000 Subject: [PATCH 9/9] Adding missing newline in ops.rst --- docs/source/ops.rst | 2 +- torchvision/ops/misc.py | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/docs/source/ops.rst b/docs/source/ops.rst index 9dbcd525861..f8485607168 100644 --- a/docs/source/ops.rst +++ b/docs/source/ops.rst @@ -45,4 +45,4 @@ Operators StochasticDepth FrozenBatchNorm2d ConvNormActivation - SqueezeExcitation \ No newline at end of file + SqueezeExcitation diff --git a/torchvision/ops/misc.py b/torchvision/ops/misc.py index f9fb16061e9..e7bf77e9970 100644 --- a/torchvision/ops/misc.py +++ b/torchvision/ops/misc.py @@ -3,7 +3,6 @@ import torch from torch import Tensor -from torch.nn.common_types import _size_2_t from ..utils import _log_api_usage_once @@ -110,7 +109,7 @@ class ConvNormActivation(torch.nn.Sequential): in_channels (int): Number of channels in the input image out_channels (int): Number of channels produced by the Convolution-Normalzation-Activation block kernel_size: (int, optional): Size of the convolving kernel. Default: 3 - stride (int or tuple, optional): Stride of the convolution. Default: 1 + stride (int, optional): Stride of the convolution. Default: 1 padding (int, tuple or str, optional): Padding added to all four sides of the input. Default: None, in wich case it will calculated as ``padding = (kernel_size - 1) // 2 * dilation`` groups (int, optional): Number of blocked connections from input channels to output channels. Default: 1 norm_layer (Callable[..., torch.nn.Module], optional): Norm layer that will be stacked on top of the convolutiuon layer. If ``None`` this layer wont be used. Default: ``torch.nn.BatchNorm2d`` @@ -125,7 +124,7 @@ def __init__( in_channels: int, out_channels: int, kernel_size: int = 3, - stride: _size_2_t = 1, + stride: int = 1, padding: Optional[int] = None, groups: int = 1, norm_layer: Optional[Callable[..., torch.nn.Module]] = torch.nn.BatchNorm2d,