darknet.py 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. import paddle
  2. from paddle import ParamAttr
  3. import paddle.nn as nn
  4. import paddle.nn.functional as F
  5. from paddle.nn import Conv2D, BatchNorm, Linear, Dropout
  6. from paddle.nn import AdaptiveAvgPool2D, MaxPool2D, AvgPool2D
  7. from paddle.nn.initializer import Uniform
  8. import math
  9. __all__ = ["DarkNet53"]
  10. class ConvBNLayer(nn.Layer):
  11. def __init__(self,
  12. input_channels,
  13. output_channels,
  14. filter_size,
  15. stride,
  16. padding,
  17. name=None):
  18. super(ConvBNLayer, self).__init__()
  19. self._conv = Conv2D(
  20. in_channels=input_channels,
  21. out_channels=output_channels,
  22. kernel_size=filter_size,
  23. stride=stride,
  24. padding=padding,
  25. weight_attr=ParamAttr(name=name + ".conv.weights"),
  26. bias_attr=False)
  27. bn_name = name + ".bn"
  28. self._bn = BatchNorm(
  29. num_channels=output_channels,
  30. act="relu",
  31. param_attr=ParamAttr(name=bn_name + ".scale"),
  32. bias_attr=ParamAttr(name=bn_name + ".offset"),
  33. moving_mean_name=bn_name + ".mean",
  34. moving_variance_name=bn_name + ".var")
  35. def forward(self, inputs):
  36. x = self._conv(inputs)
  37. x = self._bn(x)
  38. return x
  39. class BasicBlock(nn.Layer):
  40. def __init__(self, input_channels, output_channels, name=None):
  41. super(BasicBlock, self).__init__()
  42. self._conv1 = ConvBNLayer(
  43. input_channels, output_channels, 1, 1, 0, name=name + ".0")
  44. self._conv2 = ConvBNLayer(
  45. output_channels, output_channels * 2, 3, 1, 1, name=name + ".1")
  46. def forward(self, inputs):
  47. x = self._conv1(inputs)
  48. x = self._conv2(x)
  49. return paddle.add(x=inputs, y=x)
  50. class DarkNet(nn.Layer):
  51. def __init__(self, class_dim=1000):
  52. super(DarkNet, self).__init__()
  53. self.stages = [1, 2, 8, 8, 4]
  54. self._conv1 = ConvBNLayer(3, 32, 3, 1, 1, name="yolo_input")
  55. self._conv2 = ConvBNLayer(
  56. 32, 64, 3, 2, 1, name="yolo_input.downsample")
  57. self._basic_block_01 = BasicBlock(64, 32, name="stage.0.0")
  58. self._downsample_0 = ConvBNLayer(
  59. 64, 128, 3, 2, 1, name="stage.0.downsample")
  60. self._basic_block_11 = BasicBlock(128, 64, name="stage.1.0")
  61. self._basic_block_12 = BasicBlock(128, 64, name="stage.1.1")
  62. self._downsample_1 = ConvBNLayer(
  63. 128, 256, 3, 2, 1, name="stage.1.downsample")
  64. self._basic_block_21 = BasicBlock(256, 128, name="stage.2.0")
  65. self._basic_block_22 = BasicBlock(256, 128, name="stage.2.1")
  66. self._basic_block_23 = BasicBlock(256, 128, name="stage.2.2")
  67. self._basic_block_24 = BasicBlock(256, 128, name="stage.2.3")
  68. self._basic_block_25 = BasicBlock(256, 128, name="stage.2.4")
  69. self._basic_block_26 = BasicBlock(256, 128, name="stage.2.5")
  70. self._basic_block_27 = BasicBlock(256, 128, name="stage.2.6")
  71. self._basic_block_28 = BasicBlock(256, 128, name="stage.2.7")
  72. self._downsample_2 = ConvBNLayer(
  73. 256, 512, 3, 2, 1, name="stage.2.downsample")
  74. self._basic_block_31 = BasicBlock(512, 256, name="stage.3.0")
  75. self._basic_block_32 = BasicBlock(512, 256, name="stage.3.1")
  76. self._basic_block_33 = BasicBlock(512, 256, name="stage.3.2")
  77. self._basic_block_34 = BasicBlock(512, 256, name="stage.3.3")
  78. self._basic_block_35 = BasicBlock(512, 256, name="stage.3.4")
  79. self._basic_block_36 = BasicBlock(512, 256, name="stage.3.5")
  80. self._basic_block_37 = BasicBlock(512, 256, name="stage.3.6")
  81. self._basic_block_38 = BasicBlock(512, 256, name="stage.3.7")
  82. self._downsample_3 = ConvBNLayer(
  83. 512, 1024, 3, 2, 1, name="stage.3.downsample")
  84. self._basic_block_41 = BasicBlock(1024, 512, name="stage.4.0")
  85. self._basic_block_42 = BasicBlock(1024, 512, name="stage.4.1")
  86. self._basic_block_43 = BasicBlock(1024, 512, name="stage.4.2")
  87. self._basic_block_44 = BasicBlock(1024, 512, name="stage.4.3")
  88. self._pool = AdaptiveAvgPool2D(1)
  89. stdv = 1.0 / math.sqrt(1024.0)
  90. self._out = Linear(
  91. 1024,
  92. class_dim,
  93. weight_attr=ParamAttr(
  94. name="fc_weights", initializer=Uniform(-stdv, stdv)),
  95. bias_attr=ParamAttr(name="fc_offset"))
  96. def forward(self, inputs):
  97. x = self._conv1(inputs)
  98. x = self._conv2(x)
  99. x = self._basic_block_01(x)
  100. x = self._downsample_0(x)
  101. x = self._basic_block_11(x)
  102. x = self._basic_block_12(x)
  103. x = self._downsample_1(x)
  104. x = self._basic_block_21(x)
  105. x = self._basic_block_22(x)
  106. x = self._basic_block_23(x)
  107. x = self._basic_block_24(x)
  108. x = self._basic_block_25(x)
  109. x = self._basic_block_26(x)
  110. x = self._basic_block_27(x)
  111. x = self._basic_block_28(x)
  112. x = self._downsample_2(x)
  113. x = self._basic_block_31(x)
  114. x = self._basic_block_32(x)
  115. x = self._basic_block_33(x)
  116. x = self._basic_block_34(x)
  117. x = self._basic_block_35(x)
  118. x = self._basic_block_36(x)
  119. x = self._basic_block_37(x)
  120. x = self._basic_block_38(x)
  121. x = self._downsample_3(x)
  122. x = self._basic_block_41(x)
  123. x = self._basic_block_42(x)
  124. x = self._basic_block_43(x)
  125. x = self._basic_block_44(x)
  126. x = self._pool(x)
  127. x = paddle.squeeze(x, axis=[2, 3])
  128. x = self._out(x)
  129. return x
  130. def DarkNet53(**args):
  131. model = DarkNet(**args)
  132. return model