darknet.py 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  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 paddle
  15. from paddle import ParamAttr
  16. import paddle.nn as nn
  17. import paddle.nn.functional as F
  18. from paddle.nn import Conv2D, BatchNorm, Linear, Dropout
  19. from paddle.nn import AdaptiveAvgPool2D, MaxPool2D, AvgPool2D
  20. from paddle.nn.initializer import Uniform
  21. import math
  22. from paddlex.ppcls.utils.save_load import load_dygraph_pretrain, load_dygraph_pretrain_from_url
  23. MODEL_URLS = {
  24. "DarkNet53":
  25. "https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/DarkNet53_pretrained.pdparams"
  26. }
  27. __all__ = list(MODEL_URLS.keys())
  28. class ConvBNLayer(nn.Layer):
  29. def __init__(self,
  30. input_channels,
  31. output_channels,
  32. filter_size,
  33. stride,
  34. padding,
  35. name=None):
  36. super(ConvBNLayer, self).__init__()
  37. self._conv = Conv2D(
  38. in_channels=input_channels,
  39. out_channels=output_channels,
  40. kernel_size=filter_size,
  41. stride=stride,
  42. padding=padding,
  43. weight_attr=ParamAttr(name=name + ".conv.weights"),
  44. bias_attr=False)
  45. bn_name = name + ".bn"
  46. self._bn = BatchNorm(
  47. num_channels=output_channels,
  48. act="relu",
  49. param_attr=ParamAttr(name=bn_name + ".scale"),
  50. bias_attr=ParamAttr(name=bn_name + ".offset"),
  51. moving_mean_name=bn_name + ".mean",
  52. moving_variance_name=bn_name + ".var")
  53. def forward(self, inputs):
  54. x = self._conv(inputs)
  55. x = self._bn(x)
  56. return x
  57. class BasicBlock(nn.Layer):
  58. def __init__(self, input_channels, output_channels, name=None):
  59. super(BasicBlock, self).__init__()
  60. self._conv1 = ConvBNLayer(
  61. input_channels, output_channels, 1, 1, 0, name=name + ".0")
  62. self._conv2 = ConvBNLayer(
  63. output_channels, output_channels * 2, 3, 1, 1, name=name + ".1")
  64. def forward(self, inputs):
  65. x = self._conv1(inputs)
  66. x = self._conv2(x)
  67. return paddle.add(x=inputs, y=x)
  68. class DarkNet(nn.Layer):
  69. def __init__(self, class_num=1000):
  70. super(DarkNet, self).__init__()
  71. self.stages = [1, 2, 8, 8, 4]
  72. self._conv1 = ConvBNLayer(3, 32, 3, 1, 1, name="yolo_input")
  73. self._conv2 = ConvBNLayer(
  74. 32, 64, 3, 2, 1, name="yolo_input.downsample")
  75. self._basic_block_01 = BasicBlock(64, 32, name="stage.0.0")
  76. self._downsample_0 = ConvBNLayer(
  77. 64, 128, 3, 2, 1, name="stage.0.downsample")
  78. self._basic_block_11 = BasicBlock(128, 64, name="stage.1.0")
  79. self._basic_block_12 = BasicBlock(128, 64, name="stage.1.1")
  80. self._downsample_1 = ConvBNLayer(
  81. 128, 256, 3, 2, 1, name="stage.1.downsample")
  82. self._basic_block_21 = BasicBlock(256, 128, name="stage.2.0")
  83. self._basic_block_22 = BasicBlock(256, 128, name="stage.2.1")
  84. self._basic_block_23 = BasicBlock(256, 128, name="stage.2.2")
  85. self._basic_block_24 = BasicBlock(256, 128, name="stage.2.3")
  86. self._basic_block_25 = BasicBlock(256, 128, name="stage.2.4")
  87. self._basic_block_26 = BasicBlock(256, 128, name="stage.2.5")
  88. self._basic_block_27 = BasicBlock(256, 128, name="stage.2.6")
  89. self._basic_block_28 = BasicBlock(256, 128, name="stage.2.7")
  90. self._downsample_2 = ConvBNLayer(
  91. 256, 512, 3, 2, 1, name="stage.2.downsample")
  92. self._basic_block_31 = BasicBlock(512, 256, name="stage.3.0")
  93. self._basic_block_32 = BasicBlock(512, 256, name="stage.3.1")
  94. self._basic_block_33 = BasicBlock(512, 256, name="stage.3.2")
  95. self._basic_block_34 = BasicBlock(512, 256, name="stage.3.3")
  96. self._basic_block_35 = BasicBlock(512, 256, name="stage.3.4")
  97. self._basic_block_36 = BasicBlock(512, 256, name="stage.3.5")
  98. self._basic_block_37 = BasicBlock(512, 256, name="stage.3.6")
  99. self._basic_block_38 = BasicBlock(512, 256, name="stage.3.7")
  100. self._downsample_3 = ConvBNLayer(
  101. 512, 1024, 3, 2, 1, name="stage.3.downsample")
  102. self._basic_block_41 = BasicBlock(1024, 512, name="stage.4.0")
  103. self._basic_block_42 = BasicBlock(1024, 512, name="stage.4.1")
  104. self._basic_block_43 = BasicBlock(1024, 512, name="stage.4.2")
  105. self._basic_block_44 = BasicBlock(1024, 512, name="stage.4.3")
  106. self._pool = AdaptiveAvgPool2D(1)
  107. stdv = 1.0 / math.sqrt(1024.0)
  108. self._out = Linear(
  109. 1024,
  110. class_num,
  111. weight_attr=ParamAttr(
  112. name="fc_weights", initializer=Uniform(-stdv, stdv)),
  113. bias_attr=ParamAttr(name="fc_offset"))
  114. def forward(self, inputs):
  115. x = self._conv1(inputs)
  116. x = self._conv2(x)
  117. x = self._basic_block_01(x)
  118. x = self._downsample_0(x)
  119. x = self._basic_block_11(x)
  120. x = self._basic_block_12(x)
  121. x = self._downsample_1(x)
  122. x = self._basic_block_21(x)
  123. x = self._basic_block_22(x)
  124. x = self._basic_block_23(x)
  125. x = self._basic_block_24(x)
  126. x = self._basic_block_25(x)
  127. x = self._basic_block_26(x)
  128. x = self._basic_block_27(x)
  129. x = self._basic_block_28(x)
  130. x = self._downsample_2(x)
  131. x = self._basic_block_31(x)
  132. x = self._basic_block_32(x)
  133. x = self._basic_block_33(x)
  134. x = self._basic_block_34(x)
  135. x = self._basic_block_35(x)
  136. x = self._basic_block_36(x)
  137. x = self._basic_block_37(x)
  138. x = self._basic_block_38(x)
  139. x = self._downsample_3(x)
  140. x = self._basic_block_41(x)
  141. x = self._basic_block_42(x)
  142. x = self._basic_block_43(x)
  143. x = self._basic_block_44(x)
  144. x = self._pool(x)
  145. x = paddle.squeeze(x, axis=[2, 3])
  146. x = self._out(x)
  147. return x
  148. def _load_pretrained(pretrained, model, model_url, use_ssld=False):
  149. if pretrained is False:
  150. pass
  151. elif pretrained is True:
  152. load_dygraph_pretrain_from_url(model, model_url, use_ssld=use_ssld)
  153. elif isinstance(pretrained, str):
  154. load_dygraph_pretrain(model, pretrained)
  155. else:
  156. raise RuntimeError(
  157. "pretrained type is not available. Please use `string` or `boolean` type."
  158. )
  159. def DarkNet53(pretrained=False, use_ssld=False, **kwargs):
  160. model = DarkNet(**kwargs)
  161. _load_pretrained(
  162. pretrained, model, MODEL_URLS["DarkNet53"], use_ssld=use_ssld)
  163. return model