densenet.py 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514
  1. # copyright (c) 2021 PaddlePaddle Authors. All Rights Reserve.
  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 math
  15. import paddle
  16. from paddle import nn
  17. from paddle.base.param_attr import ParamAttr
  18. from paddle.nn import (
  19. AdaptiveAvgPool2D,
  20. AvgPool2D,
  21. BatchNorm,
  22. Conv2D,
  23. Dropout,
  24. Linear,
  25. MaxPool2D,
  26. )
  27. from paddle.nn.initializer import Uniform
  28. from paddle.utils.download import get_weights_path_from_url
  29. __all__ = []
  30. model_urls = {
  31. 'densenet121': (
  32. 'https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/DenseNet121_pretrained.pdparams',
  33. 'db1b239ed80a905290fd8b01d3af08e4',
  34. ),
  35. 'densenet161': (
  36. 'https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/DenseNet161_pretrained.pdparams',
  37. '62158869cb315098bd25ddbfd308a853',
  38. ),
  39. 'densenet169': (
  40. 'https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/DenseNet169_pretrained.pdparams',
  41. '82cc7c635c3f19098c748850efb2d796',
  42. ),
  43. 'densenet201': (
  44. 'https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/DenseNet201_pretrained.pdparams',
  45. '16ca29565a7712329cf9e36e02caaf58',
  46. ),
  47. 'densenet264': (
  48. 'https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/DenseNet264_pretrained.pdparams',
  49. '3270ce516b85370bba88cfdd9f60bff4',
  50. ),
  51. }
  52. class BNACConvLayer(nn.Layer):
  53. def __init__(
  54. self,
  55. num_channels,
  56. num_filters,
  57. filter_size,
  58. stride=1,
  59. pad=0,
  60. groups=1,
  61. act="relu",
  62. ):
  63. super().__init__()
  64. self._batch_norm = BatchNorm(num_channels, act=act)
  65. self._conv = Conv2D(
  66. in_channels=num_channels,
  67. out_channels=num_filters,
  68. kernel_size=filter_size,
  69. stride=stride,
  70. padding=pad,
  71. groups=groups,
  72. weight_attr=ParamAttr(),
  73. bias_attr=False,
  74. )
  75. def forward(self, input):
  76. y = self._batch_norm(input)
  77. y = self._conv(y)
  78. return y
  79. class DenseLayer(nn.Layer):
  80. def __init__(self, num_channels, growth_rate, bn_size, dropout):
  81. super().__init__()
  82. self.dropout = dropout
  83. self.bn_ac_func1 = BNACConvLayer(
  84. num_channels=num_channels,
  85. num_filters=bn_size * growth_rate,
  86. filter_size=1,
  87. pad=0,
  88. stride=1,
  89. )
  90. self.bn_ac_func2 = BNACConvLayer(
  91. num_channels=bn_size * growth_rate,
  92. num_filters=growth_rate,
  93. filter_size=3,
  94. pad=1,
  95. stride=1,
  96. )
  97. if dropout:
  98. self.dropout_func = Dropout(p=dropout, mode="downscale_in_infer")
  99. def forward(self, input):
  100. conv = self.bn_ac_func1(input)
  101. conv = self.bn_ac_func2(conv)
  102. if self.dropout:
  103. conv = self.dropout_func(conv)
  104. conv = paddle.concat([input, conv], axis=1)
  105. return conv
  106. class DenseBlock(nn.Layer):
  107. def __init__(
  108. self, num_channels, num_layers, bn_size, growth_rate, dropout, name=None
  109. ):
  110. super().__init__()
  111. self.dropout = dropout
  112. self.dense_layer_func = []
  113. pre_channel = num_channels
  114. for layer in range(num_layers):
  115. self.dense_layer_func.append(
  116. self.add_sublayer(
  117. f"{name}_{layer + 1}",
  118. DenseLayer(
  119. num_channels=pre_channel,
  120. growth_rate=growth_rate,
  121. bn_size=bn_size,
  122. dropout=dropout,
  123. ),
  124. )
  125. )
  126. pre_channel = pre_channel + growth_rate
  127. def forward(self, input):
  128. conv = input
  129. for func in self.dense_layer_func:
  130. conv = func(conv)
  131. return conv
  132. class TransitionLayer(nn.Layer):
  133. def __init__(self, num_channels, num_output_features):
  134. super().__init__()
  135. self.conv_ac_func = BNACConvLayer(
  136. num_channels=num_channels,
  137. num_filters=num_output_features,
  138. filter_size=1,
  139. pad=0,
  140. stride=1,
  141. )
  142. self.pool2d_avg = AvgPool2D(kernel_size=2, stride=2, padding=0)
  143. def forward(self, input):
  144. y = self.conv_ac_func(input)
  145. y = self.pool2d_avg(y)
  146. return y
  147. class ConvBNLayer(nn.Layer):
  148. def __init__(
  149. self,
  150. num_channels,
  151. num_filters,
  152. filter_size,
  153. stride=1,
  154. pad=0,
  155. groups=1,
  156. act="relu",
  157. ):
  158. super().__init__()
  159. self._conv = Conv2D(
  160. in_channels=num_channels,
  161. out_channels=num_filters,
  162. kernel_size=filter_size,
  163. stride=stride,
  164. padding=pad,
  165. groups=groups,
  166. weight_attr=ParamAttr(),
  167. bias_attr=False,
  168. )
  169. self._batch_norm = BatchNorm(num_filters, act=act)
  170. def forward(self, input):
  171. y = self._conv(input)
  172. y = self._batch_norm(y)
  173. return y
  174. class DenseNet(nn.Layer):
  175. """DenseNet model from
  176. `"Densely Connected Convolutional Networks" <https://arxiv.org/pdf/1608.06993.pdf>`_.
  177. Args:
  178. layers (int, optional): Layers of DenseNet. Default: 121.
  179. bn_size (int, optional): Expansion of growth rate in the middle layer. Default: 4.
  180. dropout (float, optional): Dropout rate. Default: :math:`0.0`.
  181. num_classes (int, optional): Output dim of last fc layer. If num_classes <= 0, last fc layer
  182. will not be defined. Default: 1000.
  183. with_pool (bool, optional): Use pool before the last fc layer or not. Default: True.
  184. Returns:
  185. :ref:`api_paddle_nn_Layer`. An instance of DenseNet model.
  186. Examples:
  187. .. code-block:: python
  188. >>> import paddle
  189. >>> from paddle.vision.models import DenseNet
  190. >>> # Build model
  191. >>> densenet = DenseNet()
  192. >>> x = paddle.rand([1, 3, 224, 224])
  193. >>> out = densenet(x)
  194. >>> print(out.shape)
  195. [1, 1000]
  196. """
  197. def __init__(
  198. self,
  199. layers=121,
  200. bn_size=4,
  201. dropout=0.0,
  202. num_classes=1000,
  203. with_pool=True,
  204. ):
  205. super().__init__()
  206. self.num_classes = num_classes
  207. self.with_pool = with_pool
  208. supported_layers = [121, 161, 169, 201, 264]
  209. assert (
  210. layers in supported_layers
  211. ), f"supported layers are {supported_layers} but input layer is {layers}"
  212. densenet_spec = {
  213. 121: (64, 32, [6, 12, 24, 16]),
  214. 161: (96, 48, [6, 12, 36, 24]),
  215. 169: (64, 32, [6, 12, 32, 32]),
  216. 201: (64, 32, [6, 12, 48, 32]),
  217. 264: (64, 32, [6, 12, 64, 48]),
  218. }
  219. num_init_features, growth_rate, block_config = densenet_spec[layers]
  220. self.conv1_func = ConvBNLayer(
  221. num_channels=3,
  222. num_filters=num_init_features,
  223. filter_size=7,
  224. stride=2,
  225. pad=3,
  226. act='relu',
  227. )
  228. self.pool2d_max = MaxPool2D(kernel_size=3, stride=2, padding=1)
  229. self.block_config = block_config
  230. self.dense_block_func_list = []
  231. self.transition_func_list = []
  232. pre_num_channels = num_init_features
  233. num_features = num_init_features
  234. for i, num_layers in enumerate(block_config):
  235. self.dense_block_func_list.append(
  236. self.add_sublayer(
  237. f"db_conv_{i + 2}",
  238. DenseBlock(
  239. num_channels=pre_num_channels,
  240. num_layers=num_layers,
  241. bn_size=bn_size,
  242. growth_rate=growth_rate,
  243. dropout=dropout,
  244. name='conv' + str(i + 2),
  245. ),
  246. )
  247. )
  248. num_features = num_features + num_layers * growth_rate
  249. pre_num_channels = num_features
  250. if i != len(block_config) - 1:
  251. self.transition_func_list.append(
  252. self.add_sublayer(
  253. f"tr_conv{i + 2}_blk",
  254. TransitionLayer(
  255. num_channels=pre_num_channels,
  256. num_output_features=num_features // 2,
  257. ),
  258. )
  259. )
  260. pre_num_channels = num_features // 2
  261. num_features = num_features // 2
  262. self.batch_norm = BatchNorm(num_features, act="relu")
  263. if self.with_pool:
  264. self.pool2d_avg = AdaptiveAvgPool2D(1)
  265. if self.num_classes > 0:
  266. stdv = 1.0 / math.sqrt(num_features * 1.0)
  267. self.out = Linear(
  268. num_features,
  269. num_classes,
  270. weight_attr=ParamAttr(initializer=Uniform(-stdv, stdv)),
  271. bias_attr=ParamAttr(),
  272. )
  273. def forward(self, input):
  274. conv = self.conv1_func(input)
  275. conv = self.pool2d_max(conv)
  276. for i, num_layers in enumerate(self.block_config):
  277. conv = self.dense_block_func_list[i](conv)
  278. if i != len(self.block_config) - 1:
  279. conv = self.transition_func_list[i](conv)
  280. conv = self.batch_norm(conv)
  281. if self.with_pool:
  282. y = self.pool2d_avg(conv)
  283. if self.num_classes > 0:
  284. y = paddle.flatten(y, start_axis=1, stop_axis=-1)
  285. y = self.out(y)
  286. return y
  287. def _densenet(arch, layers, pretrained, **kwargs):
  288. model = DenseNet(layers=layers, **kwargs)
  289. if pretrained:
  290. assert (
  291. arch in model_urls
  292. ), f"{arch} model do not have a pretrained model now, you should set pretrained=False"
  293. weight_path = get_weights_path_from_url(
  294. model_urls[arch][0], model_urls[arch][1]
  295. )
  296. param = paddle.load(weight_path)
  297. model.set_dict(param)
  298. return model
  299. def densenet121(pretrained=False, **kwargs):
  300. """DenseNet 121-layer model from
  301. `"Densely Connected Convolutional Networks" <https://arxiv.org/pdf/1608.06993.pdf>`_.
  302. Args:
  303. pretrained (bool, optional): Whether to load pre-trained weights. If True, returns a model pre-trained
  304. on ImageNet. Default: False.
  305. **kwargs (optional): Additional keyword arguments. For details, please refer to :ref:`DenseNet <api_paddle_vision_models_DenseNet>`.
  306. Returns:
  307. :ref:`api_paddle_nn_Layer`. An instance of DenseNet 121-layer model.
  308. Examples:
  309. .. code-block:: python
  310. >>> import paddle
  311. >>> from paddle.vision.models import densenet121
  312. >>> # Build model
  313. >>> model = densenet121()
  314. >>> # Build model and load imagenet pretrained weight
  315. >>> # model = densenet121(pretrained=True)
  316. >>> x = paddle.rand([1, 3, 224, 224])
  317. >>> out = model(x)
  318. >>> print(out.shape)
  319. [1, 1000]
  320. """
  321. return _densenet('densenet121', 121, pretrained, **kwargs)
  322. def densenet161(pretrained=False, **kwargs):
  323. """DenseNet 161-layer model from
  324. `"Densely Connected Convolutional Networks" <https://arxiv.org/pdf/1608.06993.pdf>`_.
  325. Args:
  326. pretrained (bool, optional): Whether to load pre-trained weights. If True, returns a model pre-trained
  327. on ImageNet. Default: False.
  328. **kwargs (optional): Additional keyword arguments. For details, please refer to :ref:`DenseNet <api_paddle_vision_models_DenseNet>`.
  329. Returns:
  330. :ref:`api_paddle_nn_Layer`. An instance of DenseNet 161-layer model.
  331. Examples:
  332. .. code-block:: python
  333. >>> import paddle
  334. >>> from paddle.vision.models import densenet161
  335. >>> # Build model
  336. >>> model = densenet161()
  337. >>> # Build model and load imagenet pretrained weight
  338. >>> # model = densenet161(pretrained=True)
  339. >>> x = paddle.rand([1, 3, 224, 224])
  340. >>> out = model(x)
  341. >>> print(out.shape)
  342. [1, 1000]
  343. """
  344. return _densenet('densenet161', 161, pretrained, **kwargs)
  345. def densenet169(pretrained=False, **kwargs):
  346. """DenseNet 169-layer model from
  347. `"Densely Connected Convolutional Networks" <https://arxiv.org/pdf/1608.06993.pdf>`_.
  348. Args:
  349. pretrained (bool, optional): Whether to load pre-trained weights. If True, returns a model pre-trained
  350. on ImageNet. Default: False.
  351. **kwargs (optional): Additional keyword arguments. For details, please refer to :ref:`DenseNet <api_paddle_vision_models_DenseNet>`.
  352. Returns:
  353. :ref:`api_paddle_nn_Layer`. An instance of DenseNet 169-layer model.
  354. Examples:
  355. .. code-block:: python
  356. >>> import paddle
  357. >>> from paddle.vision.models import densenet169
  358. >>> # Build model
  359. >>> model = densenet169()
  360. >>> # Build model and load imagenet pretrained weight
  361. >>> # model = densenet169(pretrained=True)
  362. >>> x = paddle.rand([1, 3, 224, 224])
  363. >>> out = model(x)
  364. >>> print(out.shape)
  365. [1, 1000]
  366. """
  367. return _densenet('densenet169', 169, pretrained, **kwargs)
  368. def densenet201(pretrained=False, **kwargs):
  369. """DenseNet 201-layer model from
  370. `"Densely Connected Convolutional Networks" <https://arxiv.org/pdf/1608.06993.pdf>`_.
  371. Args:
  372. pretrained (bool, optional): Whether to load pre-trained weights. If True, returns a model pre-trained
  373. on ImageNet. Default: False.
  374. **kwargs (optional): Additional keyword arguments. For details, please refer to :ref:`DenseNet <api_paddle_vision_models_DenseNet>`.
  375. Returns:
  376. :ref:`api_paddle_nn_Layer`. An instance of DenseNet 201-layer model.
  377. Examples:
  378. .. code-block:: python
  379. >>> import paddle
  380. >>> from paddle.vision.models import densenet201
  381. >>> # Build model
  382. >>> model = densenet201()
  383. >>> # Build model and load imagenet pretrained weight
  384. >>> # model = densenet201(pretrained=True)
  385. >>> x = paddle.rand([1, 3, 224, 224])
  386. >>> out = model(x)
  387. >>> print(out.shape)
  388. [1, 1000]
  389. """
  390. return _densenet('densenet201', 201, pretrained, **kwargs)
  391. def densenet264(pretrained=False, **kwargs):
  392. """DenseNet 264-layer model from
  393. `"Densely Connected Convolutional Networks" <https://arxiv.org/pdf/1608.06993.pdf>`_.
  394. Args:
  395. pretrained (bool, optional): Whether to load pre-trained weights. If True, returns a model pre-trained
  396. on ImageNet. Default: False.
  397. **kwargs (optional): Additional keyword arguments. For details, please refer to :ref:`DenseNet <api_paddle_vision_models_DenseNet>`.
  398. Returns:
  399. :ref:`api_paddle_nn_Layer`. An instance of DenseNet 264-layer model.
  400. Examples:
  401. .. code-block:: python
  402. >>> import paddle
  403. >>> from paddle.vision.models import densenet264
  404. >>> # Build model
  405. >>> model = densenet264()
  406. >>> # Build model and load imagenet pretrained weight
  407. >>> # model = densenet264(pretrained=True)
  408. >>> x = paddle.rand([1, 3, 224, 224])
  409. >>> out = model(x)
  410. >>> print(out.shape)
  411. [1, 1000]
  412. """
  413. return _densenet('densenet264', 264, pretrained, **kwargs)