From ba4e7c7effc5ca274e9d5dc03232a3441c47ab18 Mon Sep 17 00:00:00 2001 From: Nyakku Shigure Date: Mon, 25 Apr 2022 22:15:25 +0800 Subject: [PATCH] reimplement ResNeXt based on ResNet (#40588) * refactor resnext --- python/paddle/vision/__init__.py | 13 +- python/paddle/vision/models/__init__.py | 26 +- python/paddle/vision/models/resnet.py | 258 +++++++++++++++-- python/paddle/vision/models/resnext.py | 364 ------------------------ 4 files changed, 256 insertions(+), 405 deletions(-) delete mode 100644 python/paddle/vision/models/resnext.py diff --git a/python/paddle/vision/__init__.py b/python/paddle/vision/__init__.py index 3749e0f64fc..2f0052537e2 100644 --- a/python/paddle/vision/__init__.py +++ b/python/paddle/vision/__init__.py @@ -34,6 +34,12 @@ from .models import resnet34 # noqa: F401 from .models import resnet50 # noqa: F401 from .models import resnet101 # noqa: F401 from .models import resnet152 # noqa: F401 +from .models import resnext50_32x4d # noqa: F401 +from .models import resnext50_64x4d # noqa: F401 +from .models import resnext101_32x4d # noqa: F401 +from .models import resnext101_64x4d # noqa: F401 +from .models import resnext152_32x4d # noqa: F401 +from .models import resnext152_64x4d # noqa: F401 from .models import wide_resnet50_2 # noqa: F401 from .models import wide_resnet101_2 # noqa: F401 from .models import MobileNetV1 # noqa: F401 @@ -61,13 +67,6 @@ from .models import densenet201 # noqa: F401 from .models import densenet264 # noqa: F401 from .models import AlexNet # noqa: F401 from .models import alexnet # noqa: F401 -from .models import ResNeXt # noqa: F401 -from .models import resnext50_32x4d # noqa: F401 -from .models import resnext50_64x4d # noqa: F401 -from .models import resnext101_32x4d # noqa: F401 -from .models import resnext101_64x4d # noqa: F401 -from .models import resnext152_32x4d # noqa: F401 -from .models import resnext152_64x4d # noqa: F401 from .models import InceptionV3 # noqa: F401 from .models import inception_v3 # noqa: F401 from .models import GoogLeNet # noqa: F401 diff --git a/python/paddle/vision/models/__init__.py b/python/paddle/vision/models/__init__.py index 5ff3562e56e..85ff5f85dff 100644 --- a/python/paddle/vision/models/__init__.py +++ b/python/paddle/vision/models/__init__.py @@ -18,6 +18,12 @@ from .resnet import resnet34 # noqa: F401 from .resnet import resnet50 # noqa: F401 from .resnet import resnet101 # noqa: F401 from .resnet import resnet152 # noqa: F401 +from .resnet import resnext50_32x4d # noqa: F401 +from .resnet import resnext50_64x4d # noqa: F401 +from .resnet import resnext101_32x4d # noqa: F401 +from .resnet import resnext101_64x4d # noqa: F401 +from .resnet import resnext152_32x4d # noqa: F401 +from .resnet import resnext152_64x4d # noqa: F401 from .resnet import wide_resnet50_2 # noqa: F401 from .resnet import wide_resnet101_2 # noqa: F401 from .mobilenetv1 import MobileNetV1 # noqa: F401 @@ -42,13 +48,6 @@ from .densenet import densenet201 # noqa: F401 from .densenet import densenet264 # noqa: F401 from .alexnet import AlexNet # noqa: F401 from .alexnet import alexnet # noqa: F401 -from .resnext import ResNeXt # noqa: F401 -from .resnext import resnext50_32x4d # noqa: F401 -from .resnext import resnext50_64x4d # noqa: F401 -from .resnext import resnext101_32x4d # noqa: F401 -from .resnext import resnext101_64x4d # noqa: F401 -from .resnext import resnext152_32x4d # noqa: F401 -from .resnext import resnext152_64x4d # noqa: F401 from .inceptionv3 import InceptionV3 # noqa: F401 from .inceptionv3 import inception_v3 # noqa: F401 from .squeezenet import SqueezeNet # noqa: F401 @@ -72,6 +71,12 @@ __all__ = [ #noqa 'resnet50', 'resnet101', 'resnet152', + 'resnext50_32x4d', + 'resnext50_64x4d', + 'resnext101_32x4d', + 'resnext101_64x4d', + 'resnext152_32x4d', + 'resnext152_64x4d', 'wide_resnet50_2', 'wide_resnet101_2', 'VGG', @@ -96,13 +101,6 @@ __all__ = [ #noqa 'densenet264', 'AlexNet', 'alexnet', - 'ResNeXt', - 'resnext50_32x4d', - 'resnext50_64x4d', - 'resnext101_32x4d', - 'resnext101_64x4d', - 'resnext152_32x4d', - 'resnext152_64x4d', 'InceptionV3', 'inception_v3', 'SqueezeNet', diff --git a/python/paddle/vision/models/resnet.py b/python/paddle/vision/models/resnet.py index 5921ae10eed..27536b6a9c6 100644 --- a/python/paddle/vision/models/resnet.py +++ b/python/paddle/vision/models/resnet.py @@ -33,12 +33,30 @@ model_urls = { '02f35f034ca3858e1e54d4036443c92d'), 'resnet152': ('https://paddle-hapi.bj.bcebos.com/models/resnet152.pdparams', '7ad16a2f1e7333859ff986138630fd7a'), - 'wide_resnet50_2': - ('https://paddle-hapi.bj.bcebos.com/models/wide_resnet50_2.pdparams', - '0282f804d73debdab289bd9fea3fa6dc'), - 'wide_resnet101_2': - ('https://paddle-hapi.bj.bcebos.com/models/wide_resnet101_2.pdparams', - 'd4360a2d23657f059216f5d5a1a9ac93'), + 'resnext50_32x4d': + ('https://paddle-hapi.bj.bcebos.com/models/resnext50_32x4d.pdparams', + 'dc47483169be7d6f018fcbb7baf8775d'), + "resnext50_64x4d": + ('https://paddle-hapi.bj.bcebos.com/models/resnext50_64x4d.pdparams', + '063d4b483e12b06388529450ad7576db'), + 'resnext101_32x4d': ( + 'https://paddle-hapi.bj.bcebos.com/models/resnext101_32x4d.pdparams', + '967b090039f9de2c8d06fe994fb9095f'), + 'resnext101_64x4d': ( + 'https://paddle-hapi.bj.bcebos.com/models/resnext101_64x4d.pdparams', + '98e04e7ca616a066699230d769d03008'), + 'resnext152_32x4d': ( + 'https://paddle-hapi.bj.bcebos.com/models/resnext152_32x4d.pdparams', + '18ff0beee21f2efc99c4b31786107121'), + 'resnext152_64x4d': ( + 'https://paddle-hapi.bj.bcebos.com/models/resnext152_64x4d.pdparams', + '77c4af00ca42c405fa7f841841959379'), + 'wide_resnet50_2': ( + 'https://paddle-hapi.bj.bcebos.com/models/wide_resnet50_2.pdparams', + '0282f804d73debdab289bd9fea3fa6dc'), + 'wide_resnet101_2': ( + 'https://paddle-hapi.bj.bcebos.com/models/wide_resnet101_2.pdparams', + 'd4360a2d23657f059216f5d5a1a9ac93'), } @@ -158,11 +176,12 @@ class ResNet(nn.Layer): Args: Block (BasicBlock|BottleneckBlock): block module of model. - depth (int): layers of resnet, default: 50. - width (int): base width of resnet, default: 64. - num_classes (int): output dim of last fc layer. If num_classes <=0, last fc layer + depth (int, optional): layers of resnet, Default: 50. + width (int, optional): base width per convolution group for each convolution block, Default: 64. + num_classes (int, optional): output dim of last fc layer. If num_classes <=0, last fc layer will not be defined. Default: 1000. - with_pool (bool): use pool before the last fc layer or not. Default: True. + with_pool (bool, optional): use pool before the last fc layer or not. Default: True. + groups (int, optional): number of groups for each convolution block, Default: 1. Examples: .. code-block:: python @@ -171,16 +190,23 @@ class ResNet(nn.Layer): from paddle.vision.models import ResNet from paddle.vision.models.resnet import BottleneckBlock, BasicBlock + # build ResNet with 18 layers + resnet18 = ResNet(BasicBlock, 18) + + # build ResNet with 50 layers resnet50 = ResNet(BottleneckBlock, 50) + # build Wide ResNet model wide_resnet50_2 = ResNet(BottleneckBlock, 50, width=64*2) - resnet18 = ResNet(BasicBlock, 18) + # build ResNeXt model + resnext50_32x4d = ResNet(BottleneckBlock, 50, width=4, groups=32) x = paddle.rand([1, 3, 224, 224]) out = resnet18(x) print(out.shape) + # [1, 1000] """ @@ -189,7 +215,8 @@ class ResNet(nn.Layer): depth=50, width=64, num_classes=1000, - with_pool=True): + with_pool=True, + groups=1): super(ResNet, self).__init__() layer_cfg = { 18: [2, 2, 2, 2], @@ -199,7 +226,7 @@ class ResNet(nn.Layer): 152: [3, 8, 36, 3] } layers = layer_cfg[depth] - self.groups = 1 + self.groups = groups self.base_width = width self.num_classes = num_classes self.with_pool = with_pool @@ -300,7 +327,7 @@ def resnet18(pretrained=False, **kwargs): `"Deep Residual Learning for Image Recognition" `_ Args: - pretrained (bool): If True, returns a model pre-trained on ImageNet + pretrained (bool, optional): If True, returns a model pre-trained on ImageNet. Default: False. Examples: .. code-block:: python @@ -318,6 +345,7 @@ def resnet18(pretrained=False, **kwargs): out = model(x) print(out.shape) + # [1, 1000] """ return _resnet('resnet18', BasicBlock, 18, pretrained, **kwargs) @@ -327,7 +355,7 @@ def resnet34(pretrained=False, **kwargs): `"Deep Residual Learning for Image Recognition" `_ Args: - pretrained (bool): If True, returns a model pre-trained on ImageNet + pretrained (bool, optional): If True, returns a model pre-trained on ImageNet. Default: False. Examples: .. code-block:: python @@ -345,6 +373,7 @@ def resnet34(pretrained=False, **kwargs): out = model(x) print(out.shape) + # [1, 1000] """ return _resnet('resnet34', BasicBlock, 34, pretrained, **kwargs) @@ -354,7 +383,7 @@ def resnet50(pretrained=False, **kwargs): `"Deep Residual Learning for Image Recognition" `_ Args: - pretrained (bool): If True, returns a model pre-trained on ImageNet + pretrained (bool, optional): If True, returns a model pre-trained on ImageNet. Default: False. Examples: .. code-block:: python @@ -372,6 +401,7 @@ def resnet50(pretrained=False, **kwargs): out = model(x) print(out.shape) + # [1, 1000] """ return _resnet('resnet50', BottleneckBlock, 50, pretrained, **kwargs) @@ -381,7 +411,7 @@ def resnet101(pretrained=False, **kwargs): `"Deep Residual Learning for Image Recognition" `_ Args: - pretrained (bool): If True, returns a model pre-trained on ImageNet + pretrained (bool, optional): If True, returns a model pre-trained on ImageNet. Default: False. Examples: .. code-block:: python @@ -399,6 +429,7 @@ def resnet101(pretrained=False, **kwargs): out = model(x) print(out.shape) + # [1, 1000] """ return _resnet('resnet101', BottleneckBlock, 101, pretrained, **kwargs) @@ -408,7 +439,7 @@ def resnet152(pretrained=False, **kwargs): `"Deep Residual Learning for Image Recognition" `_ Args: - pretrained (bool): If True, returns a model pre-trained on ImageNet + pretrained (bool, optional): If True, returns a model pre-trained on ImageNet. Default: False. Examples: .. code-block:: python @@ -426,16 +457,201 @@ def resnet152(pretrained=False, **kwargs): out = model(x) print(out.shape) + # [1, 1000] """ return _resnet('resnet152', BottleneckBlock, 152, pretrained, **kwargs) +def resnext50_32x4d(pretrained=False, **kwargs): + """ResNeXt-50 32x4d model from + `"Aggregated Residual Transformations for Deep Neural Networks" `_ + + Args: + pretrained (bool, optional): If True, returns a model pre-trained on ImageNet. Default: False. + + Examples: + .. code-block:: python + + import paddle + from paddle.vision.models import resnext50_32x4d + + # build model + model = resnext50_32x4d() + + # build model and load imagenet pretrained weight + # model = resnext50_32x4d(pretrained=True) + + x = paddle.rand([1, 3, 224, 224]) + out = model(x) + + print(out.shape) + # [1, 1000] + """ + kwargs['groups'] = 32 + kwargs['width'] = 4 + return _resnet('resnext50_32x4d', BottleneckBlock, 50, pretrained, **kwargs) + + +def resnext50_64x4d(pretrained=False, **kwargs): + """ResNeXt-50 64x4d model from + `"Aggregated Residual Transformations for Deep Neural Networks" `_ + + Args: + pretrained (bool, optional): If True, returns a model pre-trained on ImageNet. Default: False. + + Examples: + .. code-block:: python + + import paddle + from paddle.vision.models import resnext50_64x4d + + # build model + model = resnext50_64x4d() + + # build model and load imagenet pretrained weight + # model = resnext50_64x4d(pretrained=True) + + x = paddle.rand([1, 3, 224, 224]) + out = model(x) + + print(out.shape) + # [1, 1000] + """ + kwargs['groups'] = 64 + kwargs['width'] = 4 + return _resnet('resnext50_64x4d', BottleneckBlock, 50, pretrained, **kwargs) + + +def resnext101_32x4d(pretrained=False, **kwargs): + """ResNeXt-101 32x4d model from + `"Aggregated Residual Transformations for Deep Neural Networks" `_ + + Args: + pretrained (bool, optional): If True, returns a model pre-trained on ImageNet. Default: False. + + Examples: + .. code-block:: python + + import paddle + from paddle.vision.models import resnext101_32x4d + + # build model + model = resnext101_32x4d() + + # build model and load imagenet pretrained weight + # model = resnext101_32x4d(pretrained=True) + + x = paddle.rand([1, 3, 224, 224]) + out = model(x) + + print(out.shape) + # [1, 1000] + """ + kwargs['groups'] = 32 + kwargs['width'] = 4 + return _resnet('resnext101_32x4d', BottleneckBlock, 101, pretrained, + **kwargs) + + +def resnext101_64x4d(pretrained=False, **kwargs): + """ResNeXt-101 64x4d model from + `"Aggregated Residual Transformations for Deep Neural Networks" `_ + + Args: + pretrained (bool, optional): If True, returns a model pre-trained on ImageNet. Default: False. + + Examples: + .. code-block:: python + + import paddle + from paddle.vision.models import resnext101_64x4d + + # build model + model = resnext101_64x4d() + + # build model and load imagenet pretrained weight + # model = resnext101_64x4d(pretrained=True) + + x = paddle.rand([1, 3, 224, 224]) + out = model(x) + + print(out.shape) + # [1, 1000] + """ + kwargs['groups'] = 64 + kwargs['width'] = 4 + return _resnet('resnext101_64x4d', BottleneckBlock, 101, pretrained, + **kwargs) + + +def resnext152_32x4d(pretrained=False, **kwargs): + """ResNeXt-152 32x4d model from + `"Aggregated Residual Transformations for Deep Neural Networks" `_ + + Args: + pretrained (bool, optional): If True, returns a model pre-trained on ImageNet. Default: False. + + Examples: + .. code-block:: python + + import paddle + from paddle.vision.models import resnext152_32x4d + + # build model + model = resnext152_32x4d() + + # build model and load imagenet pretrained weight + # model = resnext152_32x4d(pretrained=True) + + x = paddle.rand([1, 3, 224, 224]) + out = model(x) + + print(out.shape) + # [1, 1000] + """ + kwargs['groups'] = 32 + kwargs['width'] = 4 + return _resnet('resnext152_32x4d', BottleneckBlock, 152, pretrained, + **kwargs) + + +def resnext152_64x4d(pretrained=False, **kwargs): + """ResNeXt-152 64x4d model from + `"Aggregated Residual Transformations for Deep Neural Networks" `_ + + Args: + pretrained (bool, optional): If True, returns a model pre-trained on ImageNet. Default: False. + + Examples: + .. code-block:: python + + import paddle + from paddle.vision.models import resnext152_64x4d + + # build model + model = resnext152_64x4d() + + # build model and load imagenet pretrained weight + # model = resnext152_64x4d(pretrained=True) + + x = paddle.rand([1, 3, 224, 224]) + out = model(x) + + print(out.shape) + # [1, 1000] + """ + kwargs['groups'] = 64 + kwargs['width'] = 4 + return _resnet('resnext152_64x4d', BottleneckBlock, 152, pretrained, + **kwargs) + + def wide_resnet50_2(pretrained=False, **kwargs): """Wide ResNet-50-2 model from `"Wide Residual Networks" `_. Args: - pretrained (bool): If True, returns a model pre-trained on ImageNet + pretrained (bool, optional): If True, returns a model pre-trained on ImageNet. Default: False. Examples: .. code-block:: python @@ -453,6 +669,7 @@ def wide_resnet50_2(pretrained=False, **kwargs): out = model(x) print(out.shape) + # [1, 1000] """ kwargs['width'] = 64 * 2 return _resnet('wide_resnet50_2', BottleneckBlock, 50, pretrained, **kwargs) @@ -463,7 +680,7 @@ def wide_resnet101_2(pretrained=False, **kwargs): `"Wide Residual Networks" `_. Args: - pretrained (bool): If True, returns a model pre-trained on ImageNet + pretrained (bool, optional): If True, returns a model pre-trained on ImageNet. Default: False. Examples: .. code-block:: python @@ -481,6 +698,7 @@ def wide_resnet101_2(pretrained=False, **kwargs): out = model(x) print(out.shape) + # [1, 1000] """ kwargs['width'] = 64 * 2 return _resnet('wide_resnet101_2', BottleneckBlock, 101, pretrained, diff --git a/python/paddle/vision/models/resnext.py b/python/paddle/vision/models/resnext.py deleted file mode 100644 index 2e1073c8ac5..00000000000 --- a/python/paddle/vision/models/resnext.py +++ /dev/null @@ -1,364 +0,0 @@ -# copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - -import math - -import paddle -import paddle.nn as nn -import paddle.nn.functional as F -from paddle.fluid.param_attr import ParamAttr -from paddle.nn import AdaptiveAvgPool2D, BatchNorm, Conv2D, Linear, MaxPool2D -from paddle.nn.initializer import Uniform -from paddle.utils.download import get_weights_path_from_url - -__all__ = [] - -model_urls = { - 'resnext50_32x4d': - ('https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/ResNeXt50_32x4d_pretrained.pdparams', - 'bf04add2f7fd22efcbe91511bcd1eebe'), - "resnext50_64x4d": - ('https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/ResNeXt50_64x4d_pretrained.pdparams', - '46307df0e2d6d41d3b1c1d22b00abc69'), - 'resnext101_32x4d': - ('https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/ResNeXt101_32x4d_pretrained.pdparams', - '078ca145b3bea964ba0544303a43c36d'), - 'resnext101_64x4d': - ('https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/ResNeXt101_64x4d_pretrained.pdparams', - '4edc0eb32d3cc5d80eff7cab32cd5c64'), - 'resnext152_32x4d': - ('https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/ResNeXt152_32x4d_pretrained.pdparams', - '7971cc994d459af167c502366f866378'), - 'resnext152_64x4d': - ('https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/ResNeXt152_64x4d_pretrained.pdparams', - '836943f03709efec364d486c57d132de'), -} - - -class ConvBNLayer(nn.Layer): - def __init__(self, - num_channels, - num_filters, - filter_size, - stride=1, - groups=1, - act=None): - super(ConvBNLayer, self).__init__() - self._conv = Conv2D( - in_channels=num_channels, - out_channels=num_filters, - kernel_size=filter_size, - stride=stride, - padding=(filter_size - 1) // 2, - groups=groups, - bias_attr=False) - self._batch_norm = BatchNorm(num_filters, act=act) - - def forward(self, inputs): - x = self._conv(inputs) - x = self._batch_norm(x) - return x - - -class BottleneckBlock(nn.Layer): - def __init__(self, - num_channels, - num_filters, - stride, - cardinality, - shortcut=True): - super(BottleneckBlock, self).__init__() - self.conv0 = ConvBNLayer( - num_channels=num_channels, - num_filters=num_filters, - filter_size=1, - act='relu') - self.conv1 = ConvBNLayer( - num_channels=num_filters, - num_filters=num_filters, - filter_size=3, - groups=cardinality, - stride=stride, - act='relu') - self.conv2 = ConvBNLayer( - num_channels=num_filters, - num_filters=num_filters * 2 if cardinality == 32 else num_filters, - filter_size=1, - act=None) - - if not shortcut: - self.short = ConvBNLayer( - num_channels=num_channels, - num_filters=num_filters * 2 - if cardinality == 32 else num_filters, - filter_size=1, - stride=stride) - - self.shortcut = shortcut - - def forward(self, inputs): - x = self.conv0(inputs) - conv1 = self.conv1(x) - conv2 = self.conv2(conv1) - - if self.shortcut: - short = inputs - else: - short = self.short(inputs) - - x = paddle.add(x=short, y=conv2) - x = F.relu(x) - return x - - -class ResNeXt(nn.Layer): - """ResNeXt model from - `"Aggregated Residual Transformations for Deep Neural Networks" `_ - - Args: - depth (int, optional): depth of resnext. Default: 50. - cardinality (int, optional): cardinality of resnext. Default: 32. - num_classes (int, optional): output dim of last fc layer. If num_classes <=0, last fc layer - will not be defined. Default: 1000. - with_pool (bool, optional): use pool before the last fc layer or not. Default: True. - - Examples: - .. code-block:: python - - import paddle - from paddle.vision.models import ResNeXt - - resnext50_32x4d = ResNeXt(depth=50, cardinality=32) - - """ - - def __init__(self, - depth=50, - cardinality=32, - num_classes=1000, - with_pool=True): - super(ResNeXt, self).__init__() - - self.depth = depth - self.cardinality = cardinality - self.num_classes = num_classes - self.with_pool = with_pool - - supported_depth = [50, 101, 152] - assert depth in supported_depth, \ - "supported layers are {} but input layer is {}".format( - supported_depth, depth) - supported_cardinality = [32, 64] - assert cardinality in supported_cardinality, \ - "supported cardinality is {} but input cardinality is {}" \ - .format(supported_cardinality, cardinality) - layer_cfg = {50: [3, 4, 6, 3], 101: [3, 4, 23, 3], 152: [3, 8, 36, 3]} - layers = layer_cfg[depth] - num_channels = [64, 256, 512, 1024] - num_filters = [128, 256, 512, - 1024] if cardinality == 32 else [256, 512, 1024, 2048] - - self.conv = ConvBNLayer( - num_channels=3, num_filters=64, filter_size=7, stride=2, act='relu') - self.pool2d_max = MaxPool2D(kernel_size=3, stride=2, padding=1) - - self.block_list = [] - for block in range(len(layers)): - shortcut = False - for i in range(layers[block]): - bottleneck_block = self.add_sublayer( - 'bb_%d_%d' % (block, i), - BottleneckBlock( - num_channels=num_channels[block] if i == 0 else - num_filters[block] * int(64 // self.cardinality), - num_filters=num_filters[block], - stride=2 if i == 0 and block != 0 else 1, - cardinality=self.cardinality, - shortcut=shortcut)) - self.block_list.append(bottleneck_block) - shortcut = True - - if with_pool: - self.pool2d_avg = AdaptiveAvgPool2D(1) - - if num_classes > 0: - self.pool2d_avg_channels = num_channels[-1] * 2 - stdv = 1.0 / math.sqrt(self.pool2d_avg_channels * 1.0) - self.out = Linear( - self.pool2d_avg_channels, - num_classes, - weight_attr=ParamAttr(initializer=Uniform(-stdv, stdv))) - - def forward(self, inputs): - with paddle.static.amp.fp16_guard(): - x = self.conv(inputs) - x = self.pool2d_max(x) - for block in self.block_list: - x = block(x) - if self.with_pool: - x = self.pool2d_avg(x) - if self.num_classes > 0: - x = paddle.reshape(x, shape=[-1, self.pool2d_avg_channels]) - x = self.out(x) - return x - - -def _resnext(arch, depth, cardinality, pretrained, **kwargs): - model = ResNeXt(depth=depth, cardinality=cardinality, **kwargs) - if pretrained: - assert arch in model_urls, "{} model do not have a pretrained model now, you should set pretrained=False".format( - arch) - weight_path = get_weights_path_from_url(model_urls[arch][0], - model_urls[arch][1]) - - param = paddle.load(weight_path) - model.set_dict(param) - - return model - - -def resnext50_32x4d(pretrained=False, **kwargs): - """ResNeXt-50 32x4d model from - `"Aggregated Residual Transformations for Deep Neural Networks" `_ - - Args: - pretrained (bool): If True, returns a model pre-trained on ImageNet - - Examples: - .. code-block:: python - - import paddle - from paddle.vision.models import resnext50_32x4d - - # build model - model = resnext50_32x4d() - - # build model and load imagenet pretrained weight - # model = resnext50_32x4d(pretrained=True) - """ - return _resnext('resnext50_32x4d', 50, 32, pretrained, **kwargs) - - -def resnext50_64x4d(pretrained=False, **kwargs): - """ResNeXt-50 64x4d model from - `"Aggregated Residual Transformations for Deep Neural Networks" `_ - - Args: - pretrained (bool): If True, returns a model pre-trained on ImageNet - - Examples: - .. code-block:: python - - import paddle - from paddle.vision.models import resnext50_64x4d - - # build model - model = resnext50_64x4d() - - # build model and load imagenet pretrained weight - # model = resnext50_64x4d(pretrained=True) - """ - return _resnext('resnext50_64x4d', 50, 64, pretrained, **kwargs) - - -def resnext101_32x4d(pretrained=False, **kwargs): - """ResNeXt-101 32x4d model from - `"Aggregated Residual Transformations for Deep Neural Networks" `_ - - Args: - pretrained (bool): If True, returns a model pre-trained on ImageNet - - Examples: - .. code-block:: python - - import paddle - from paddle.vision.models import resnext101_32x4d - - # build model - model = resnext101_32x4d() - - # build model and load imagenet pretrained weight - # model = resnext101_32x4d(pretrained=True) - """ - return _resnext('resnext101_32x4d', 101, 32, pretrained, **kwargs) - - -def resnext101_64x4d(pretrained=False, **kwargs): - """ResNeXt-101 64x4d model from - `"Aggregated Residual Transformations for Deep Neural Networks" `_ - - Args: - pretrained (bool): If True, returns a model pre-trained on ImageNet - - Examples: - .. code-block:: python - - import paddle - from paddle.vision.models import resnext101_64x4d - - # build model - model = resnext101_64x4d() - - # build model and load imagenet pretrained weight - # model = resnext101_64x4d(pretrained=True) - """ - return _resnext('resnext101_64x4d', 101, 64, pretrained, **kwargs) - - -def resnext152_32x4d(pretrained=False, **kwargs): - """ResNeXt-152 32x4d model from - `"Aggregated Residual Transformations for Deep Neural Networks" `_ - - Args: - pretrained (bool): If True, returns a model pre-trained on ImageNet - - Examples: - .. code-block:: python - - import paddle - from paddle.vision.models import resnext152_32x4d - - # build model - model = resnext152_32x4d() - - # build model and load imagenet pretrained weight - # model = resnext152_32x4d(pretrained=True) - """ - return _resnext('resnext152_32x4d', 152, 32, pretrained, **kwargs) - - -def resnext152_64x4d(pretrained=False, **kwargs): - """ResNeXt-152 64x4d model from - `"Aggregated Residual Transformations for Deep Neural Networks" `_ - - Args: - pretrained (bool): If True, returns a model pre-trained on ImageNet - - Examples: - .. code-block:: python - - import paddle - from paddle.vision.models import resnext152_64x4d - - # build model - model = resnext152_64x4d() - - # build model and load imagenet pretrained weight - # model = resnext152_64x4d(pretrained=True) - """ - return _resnext('resnext152_64x4d', 152, 64, pretrained, **kwargs) -- GitLab