vgg.py 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. # Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved.
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. import paddle
  15. from paddle import nn
  16. from paddle.utils.download import get_weights_path_from_url
  17. __all__ = []
  18. model_urls = {
  19. 'vgg16': (
  20. 'https://paddle-hapi.bj.bcebos.com/models/vgg16.pdparams',
  21. '89bbffc0f87d260be9b8cdc169c991c4',
  22. ),
  23. 'vgg19': (
  24. 'https://paddle-hapi.bj.bcebos.com/models/vgg19.pdparams',
  25. '23b18bb13d8894f60f54e642be79a0dd',
  26. ),
  27. }
  28. class VGG(nn.Layer):
  29. """VGG model from
  30. `"Very Deep Convolutional Networks For Large-Scale Image Recognition" <https://arxiv.org/pdf/1409.1556.pdf>`_.
  31. Args:
  32. features (nn.Layer): Vgg features create by function make_layers.
  33. num_classes (int, optional): Output dim of last fc layer. If num_classes <= 0, last fc layer
  34. will not be defined. Default: 1000.
  35. with_pool (bool, optional): Use pool before the last three fc layer or not. Default: True.
  36. Returns:
  37. :ref:`api_paddle_nn_Layer`. An instance of VGG model.
  38. Examples:
  39. .. code-block:: python
  40. >>> import paddle
  41. >>> from paddle.vision.models import VGG
  42. >>> from paddle.vision.models.vgg import make_layers
  43. >>> vgg11_cfg = [64, 'M', 128, 'M', 256, 256, 'M', 512, 512, 'M', 512, 512, 'M']
  44. >>> features = make_layers(vgg11_cfg)
  45. >>> vgg11 = VGG(features)
  46. >>> x = paddle.rand([1, 3, 224, 224])
  47. >>> out = vgg11(x)
  48. >>> print(out.shape)
  49. [1, 1000]
  50. """
  51. def __init__(self, features, num_classes=1000, with_pool=True):
  52. super().__init__()
  53. self.features = features
  54. self.num_classes = num_classes
  55. self.with_pool = with_pool
  56. if with_pool:
  57. self.avgpool = nn.AdaptiveAvgPool2D((7, 7))
  58. if num_classes > 0:
  59. self.classifier = nn.Sequential(
  60. nn.Linear(512 * 7 * 7, 4096),
  61. nn.ReLU(),
  62. nn.Dropout(),
  63. nn.Linear(4096, 4096),
  64. nn.ReLU(),
  65. nn.Dropout(),
  66. nn.Linear(4096, num_classes),
  67. )
  68. def forward(self, x):
  69. x = self.features(x)
  70. if self.with_pool:
  71. x = self.avgpool(x)
  72. if self.num_classes > 0:
  73. x = paddle.flatten(x, 1)
  74. x = self.classifier(x)
  75. return x
  76. def make_layers(cfg, batch_norm=False):
  77. layers = []
  78. in_channels = 3
  79. for v in cfg:
  80. if v == 'M':
  81. layers += [nn.MaxPool2D(kernel_size=2, stride=2)]
  82. else:
  83. conv2d = nn.Conv2D(in_channels, v, kernel_size=3, padding=1)
  84. if batch_norm:
  85. layers += [conv2d, nn.BatchNorm2D(v), nn.ReLU()]
  86. else:
  87. layers += [conv2d, nn.ReLU()]
  88. in_channels = v
  89. return nn.Sequential(*layers)
  90. cfgs = {
  91. 'A': [64, 'M', 128, 'M', 256, 256, 'M', 512, 512, 'M', 512, 512, 'M'],
  92. 'B': [
  93. 64,
  94. 64,
  95. 'M',
  96. 128,
  97. 128,
  98. 'M',
  99. 256,
  100. 256,
  101. 'M',
  102. 512,
  103. 512,
  104. 'M',
  105. 512,
  106. 512,
  107. 'M',
  108. ],
  109. 'D': [
  110. 64,
  111. 64,
  112. 'M',
  113. 128,
  114. 128,
  115. 'M',
  116. 256,
  117. 256,
  118. 256,
  119. 'M',
  120. 512,
  121. 512,
  122. 512,
  123. 'M',
  124. 512,
  125. 512,
  126. 512,
  127. 'M',
  128. ],
  129. 'E': [
  130. 64,
  131. 64,
  132. 'M',
  133. 128,
  134. 128,
  135. 'M',
  136. 256,
  137. 256,
  138. 256,
  139. 256,
  140. 'M',
  141. 512,
  142. 512,
  143. 512,
  144. 512,
  145. 'M',
  146. 512,
  147. 512,
  148. 512,
  149. 512,
  150. 'M',
  151. ],
  152. }
  153. def _vgg(arch, cfg, batch_norm, pretrained, **kwargs):
  154. model = VGG(make_layers(cfgs[cfg], batch_norm=batch_norm), **kwargs)
  155. if pretrained:
  156. assert (
  157. arch in model_urls
  158. ), f"{arch} model do not have a pretrained model now, you should set pretrained=False"
  159. weight_path = get_weights_path_from_url(
  160. model_urls[arch][0], model_urls[arch][1]
  161. )
  162. param = paddle.load(weight_path)
  163. model.load_dict(param)
  164. return model
  165. def vgg11(pretrained=False, batch_norm=False, **kwargs):
  166. """VGG 11-layer model from
  167. `"Very Deep Convolutional Networks For Large-Scale Image Recognition" <https://arxiv.org/pdf/1409.1556.pdf>`_.
  168. Args:
  169. pretrained (bool, optional): Whether to load pre-trained weights. If True, returns a model pre-trained
  170. on ImageNet. Default: False.
  171. batch_norm (bool, optional): If True, returns a model with batch_norm layer. Default: False.
  172. **kwargs (optional): Additional keyword arguments. For details, please refer to :ref:`VGG <api_paddle_vision_models_VGG>`.
  173. Returns:
  174. :ref:`api_paddle_nn_Layer`. An instance of VGG 11-layer model.
  175. Examples:
  176. .. code-block:: python
  177. >>> import paddle
  178. >>> from paddle.vision.models import vgg11
  179. >>> # build model
  180. >>> model = vgg11()
  181. >>> # build vgg11 model with batch_norm
  182. >>> model = vgg11(batch_norm=True)
  183. >>> x = paddle.rand([1, 3, 224, 224])
  184. >>> out = model(x)
  185. >>> print(out.shape)
  186. [1, 1000]
  187. """
  188. model_name = 'vgg11'
  189. if batch_norm:
  190. model_name += '_bn'
  191. return _vgg(model_name, 'A', batch_norm, pretrained, **kwargs)
  192. def vgg13(pretrained=False, batch_norm=False, **kwargs):
  193. """VGG 13-layer model from
  194. `"Very Deep Convolutional Networks For Large-Scale Image Recognition" <https://arxiv.org/pdf/1409.1556.pdf>`_.
  195. Args:
  196. pretrained (bool, optional): Whether to load pre-trained weights. If True, returns a model pre-trained
  197. on ImageNet. Default: False.
  198. batch_norm (bool): If True, returns a model with batch_norm layer. Default: False.
  199. **kwargs (optional): Additional keyword arguments. For details, please refer to :ref:`VGG <api_paddle_vision_models_VGG>`.
  200. Returns:
  201. :ref:`api_paddle_nn_Layer`. An instance of VGG 13-layer model.
  202. Examples:
  203. .. code-block:: python
  204. >>> import paddle
  205. >>> from paddle.vision.models import vgg13
  206. >>> # build model
  207. >>> model = vgg13()
  208. >>> # build vgg13 model with batch_norm
  209. >>> model = vgg13(batch_norm=True)
  210. >>> x = paddle.rand([1, 3, 224, 224])
  211. >>> out = model(x)
  212. >>> print(out.shape)
  213. [1, 1000]
  214. """
  215. model_name = 'vgg13'
  216. if batch_norm:
  217. model_name += '_bn'
  218. return _vgg(model_name, 'B', batch_norm, pretrained, **kwargs)
  219. def vgg16(pretrained=False, batch_norm=False, **kwargs):
  220. """VGG 16-layer model from
  221. `"Very Deep Convolutional Networks For Large-Scale Image Recognition" <https://arxiv.org/pdf/1409.1556.pdf>`_.
  222. Args:
  223. pretrained (bool, optional): Whether to load pre-trained weights. If True, returns a model pre-trained
  224. on ImageNet. Default: False.
  225. batch_norm (bool, optional): If True, returns a model with batch_norm layer. Default: False.
  226. **kwargs (optional): Additional keyword arguments. For details, please refer to :ref:`VGG <api_paddle_vision_models_VGG>`.
  227. Returns:
  228. :ref:`api_paddle_nn_Layer`. An instance of VGG 16-layer model.
  229. Examples:
  230. .. code-block:: python
  231. >>> import paddle
  232. >>> from paddle.vision.models import vgg16
  233. >>> # build model
  234. >>> model = vgg16()
  235. >>> # build vgg16 model with batch_norm
  236. >>> model = vgg16(batch_norm=True)
  237. >>> x = paddle.rand([1, 3, 224, 224])
  238. >>> out = model(x)
  239. >>> print(out.shape)
  240. [1, 1000]
  241. """
  242. model_name = 'vgg16'
  243. if batch_norm:
  244. model_name += '_bn'
  245. return _vgg(model_name, 'D', batch_norm, pretrained, **kwargs)
  246. def vgg19(pretrained=False, batch_norm=False, **kwargs):
  247. """VGG 19-layer model from
  248. `"Very Deep Convolutional Networks For Large-Scale Image Recognition" <https://arxiv.org/pdf/1409.1556.pdf>`_.
  249. Args:
  250. pretrained (bool, optional): Whether to load pre-trained weights. If True, returns a model pre-trained
  251. on ImageNet. Default: False.
  252. batch_norm (bool, optional): If True, returns a model with batch_norm layer. Default: False.
  253. **kwargs (optional): Additional keyword arguments. For details, please refer to :ref:`VGG <api_paddle_vision_models_VGG>`.
  254. Returns:
  255. :ref:`api_paddle_nn_Layer`. An instance of VGG 19-layer model.
  256. Examples:
  257. .. code-block:: python
  258. >>> import paddle
  259. >>> from paddle.vision.models import vgg19
  260. >>> # build model
  261. >>> model = vgg19()
  262. >>> # build vgg19 model with batch_norm
  263. >>> model = vgg19(batch_norm=True)
  264. >>> x = paddle.rand([1, 3, 224, 224])
  265. >>> out = model(x)
  266. >>> print(out.shape)
  267. [1, 1000]
  268. """
  269. model_name = 'vgg19'
  270. if batch_norm:
  271. model_name += '_bn'
  272. return _vgg(model_name, 'E', batch_norm, pretrained, **kwargs)