diff --git a/python/paddle/tests/test_pretrained_model.py b/python/paddle/tests/test_pretrained_model.py index 913caec733fe9..8a488e8bdd3d3 100644 --- a/python/paddle/tests/test_pretrained_model.py +++ b/python/paddle/tests/test_pretrained_model.py @@ -56,7 +56,7 @@ def test_models(self): 'mobilenet_v1', 'mobilenet_v2', 'resnet18', 'vgg16', 'alexnet', 'resnext50_32x4d', 'inception_v3', 'densenet121', 'squeezenet1_0', 'squeezenet1_1', 'googlenet', 'shufflenet_v2_x0_25', - 'shufflenet_v2_swish' + 'shufflenet_v2_swish', 'wide_resnet50_2', 'wide_resnet101_2' ] for arch in arches: self.infer(arch) diff --git a/python/paddle/tests/test_vision_models.py b/python/paddle/tests/test_vision_models.py index 48ea1b80c9bf8..547c53345995c 100644 --- a/python/paddle/tests/test_vision_models.py +++ b/python/paddle/tests/test_vision_models.py @@ -70,6 +70,12 @@ def test_resnet101(self): def test_resnet152(self): self.models_infer('resnet152') + def test_wide_resnet50_2(self): + self.models_infer('wide_resnet50_2') + + def test_wide_resnet101_2(self): + self.models_infer('wide_resnet101_2') + def test_densenet121(self): self.models_infer('densenet121') diff --git a/python/paddle/vision/__init__.py b/python/paddle/vision/__init__.py index 54f293d7f57d1..37520175a719f 100644 --- a/python/paddle/vision/__init__.py +++ b/python/paddle/vision/__init__.py @@ -34,6 +34,8 @@ from .models import resnet50 # noqa: F401 from .models import resnet101 # noqa: F401 from .models import resnet152 # noqa: F401 +from .models import wide_resnet50_2 # noqa: F401 +from .models import wide_resnet101_2 # noqa: F401 from .models import MobileNetV1 # noqa: F401 from .models import mobilenet_v1 # noqa: F401 from .models import MobileNetV2 # noqa: F401 diff --git a/python/paddle/vision/models/__init__.py b/python/paddle/vision/models/__init__.py index e9a6af32d406b..044be6a42b7c2 100644 --- a/python/paddle/vision/models/__init__.py +++ b/python/paddle/vision/models/__init__.py @@ -18,6 +18,8 @@ from .resnet import resnet50 # noqa: F401 from .resnet import resnet101 # noqa: F401 from .resnet import resnet152 # noqa: F401 +from .resnet import wide_resnet50_2 # noqa: F401 +from .resnet import wide_resnet101_2 # noqa: F401 from .mobilenetv1 import MobileNetV1 # noqa: F401 from .mobilenetv1 import mobilenet_v1 # noqa: F401 from .mobilenetv2 import MobileNetV2 # noqa: F401 @@ -66,6 +68,8 @@ 'resnet50', 'resnet101', 'resnet152', + 'wide_resnet50_2', + 'wide_resnet101_2', 'VGG', 'vgg11', 'vgg13', diff --git a/python/paddle/vision/models/resnet.py b/python/paddle/vision/models/resnet.py index 5be69c93e8b5f..5921ae10eedef 100644 --- a/python/paddle/vision/models/resnet.py +++ b/python/paddle/vision/models/resnet.py @@ -33,6 +33,12 @@ '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'), } @@ -153,23 +159,37 @@ class ResNet(nn.Layer): Args: Block (BasicBlock|BottleneckBlock): block module of model. depth (int): layers of resnet, default: 50. - num_classes (int): output dim of last fc layer. If num_classes <=0, last fc layer + width (int): base width of resnet, default: 64. + num_classes (int): 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. Examples: .. code-block:: python + import paddle from paddle.vision.models import ResNet from paddle.vision.models.resnet import BottleneckBlock, BasicBlock resnet50 = ResNet(BottleneckBlock, 50) + wide_resnet50_2 = ResNet(BottleneckBlock, 50, width=64*2) + resnet18 = ResNet(BasicBlock, 18) + x = paddle.rand([1, 3, 224, 224]) + out = resnet18(x) + + print(out.shape) + """ - def __init__(self, block, depth, num_classes=1000, with_pool=True): + def __init__(self, + block, + depth=50, + width=64, + num_classes=1000, + with_pool=True): super(ResNet, self).__init__() layer_cfg = { 18: [2, 2, 2, 2], @@ -179,6 +199,8 @@ def __init__(self, block, depth, num_classes=1000, with_pool=True): 152: [3, 8, 36, 3] } layers = layer_cfg[depth] + self.groups = 1 + self.base_width = width self.num_classes = num_classes self.with_pool = with_pool self._norm_layer = nn.BatchNorm2D @@ -225,11 +247,17 @@ def _make_layer(self, block, planes, blocks, stride=1, dilate=False): layers = [] layers.append( - block(self.inplanes, planes, stride, downsample, 1, 64, - previous_dilation, norm_layer)) + block(self.inplanes, planes, stride, downsample, self.groups, + self.base_width, previous_dilation, norm_layer)) self.inplanes = planes * block.expansion for _ in range(1, blocks): - layers.append(block(self.inplanes, planes, norm_layer=norm_layer)) + layers.append( + block( + self.inplanes, + planes, + groups=self.groups, + base_width=self.base_width, + norm_layer=norm_layer)) return nn.Sequential(*layers) @@ -268,14 +296,16 @@ def _resnet(arch, Block, depth, pretrained, **kwargs): def resnet18(pretrained=False, **kwargs): - """ResNet 18-layer model - + """ResNet 18-layer model from + `"Deep Residual Learning for Image Recognition" `_ + Args: pretrained (bool): If True, returns a model pre-trained on ImageNet Examples: .. code-block:: python + import paddle from paddle.vision.models import resnet18 # build model @@ -283,19 +313,26 @@ def resnet18(pretrained=False, **kwargs): # build model and load imagenet pretrained weight # model = resnet18(pretrained=True) + + x = paddle.rand([1, 3, 224, 224]) + out = model(x) + + print(out.shape) """ return _resnet('resnet18', BasicBlock, 18, pretrained, **kwargs) def resnet34(pretrained=False, **kwargs): - """ResNet 34-layer model - + """ResNet 34-layer model from + `"Deep Residual Learning for Image Recognition" `_ + Args: pretrained (bool): If True, returns a model pre-trained on ImageNet - + Examples: .. code-block:: python + import paddle from paddle.vision.models import resnet34 # build model @@ -303,19 +340,26 @@ def resnet34(pretrained=False, **kwargs): # build model and load imagenet pretrained weight # model = resnet34(pretrained=True) + + x = paddle.rand([1, 3, 224, 224]) + out = model(x) + + print(out.shape) """ return _resnet('resnet34', BasicBlock, 34, pretrained, **kwargs) def resnet50(pretrained=False, **kwargs): - """ResNet 50-layer model - + """ResNet 50-layer model from + `"Deep Residual Learning for Image Recognition" `_ + Args: pretrained (bool): If True, returns a model pre-trained on ImageNet Examples: .. code-block:: python + import paddle from paddle.vision.models import resnet50 # build model @@ -323,19 +367,26 @@ def resnet50(pretrained=False, **kwargs): # build model and load imagenet pretrained weight # model = resnet50(pretrained=True) + + x = paddle.rand([1, 3, 224, 224]) + out = model(x) + + print(out.shape) """ return _resnet('resnet50', BottleneckBlock, 50, pretrained, **kwargs) def resnet101(pretrained=False, **kwargs): - """ResNet 101-layer model - + """ResNet 101-layer model from + `"Deep Residual Learning for Image Recognition" `_ + Args: pretrained (bool): If True, returns a model pre-trained on ImageNet Examples: .. code-block:: python + import paddle from paddle.vision.models import resnet101 # build model @@ -343,19 +394,26 @@ def resnet101(pretrained=False, **kwargs): # build model and load imagenet pretrained weight # model = resnet101(pretrained=True) + + x = paddle.rand([1, 3, 224, 224]) + out = model(x) + + print(out.shape) """ return _resnet('resnet101', BottleneckBlock, 101, pretrained, **kwargs) def resnet152(pretrained=False, **kwargs): - """ResNet 152-layer model - + """ResNet 152-layer model from + `"Deep Residual Learning for Image Recognition" `_ + Args: pretrained (bool): If True, returns a model pre-trained on ImageNet Examples: .. code-block:: python + import paddle from paddle.vision.models import resnet152 # build model @@ -363,5 +421,67 @@ def resnet152(pretrained=False, **kwargs): # build model and load imagenet pretrained weight # model = resnet152(pretrained=True) + + x = paddle.rand([1, 3, 224, 224]) + out = model(x) + + print(out.shape) """ return _resnet('resnet152', 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 + + Examples: + .. code-block:: python + + import paddle + from paddle.vision.models import wide_resnet50_2 + + # build model + model = wide_resnet50_2() + + # build model and load imagenet pretrained weight + # model = wide_resnet50_2(pretrained=True) + + x = paddle.rand([1, 3, 224, 224]) + out = model(x) + + print(out.shape) + """ + kwargs['width'] = 64 * 2 + return _resnet('wide_resnet50_2', BottleneckBlock, 50, pretrained, **kwargs) + + +def wide_resnet101_2(pretrained=False, **kwargs): + """Wide ResNet-101-2 model from + `"Wide Residual Networks" `_. + + Args: + pretrained (bool): If True, returns a model pre-trained on ImageNet + + Examples: + .. code-block:: python + + import paddle + from paddle.vision.models import wide_resnet101_2 + + # build model + model = wide_resnet101_2() + + # build model and load imagenet pretrained weight + # model = wide_resnet101_2(pretrained=True) + + x = paddle.rand([1, 3, 224, 224]) + out = model(x) + + print(out.shape) + """ + kwargs['width'] = 64 * 2 + return _resnet('wide_resnet101_2', BottleneckBlock, 101, pretrained, + **kwargs)