yolov6_backbone.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. import torch
  2. import torch.nn as nn
  3. try:
  4. from .yolov6_basic import RepBlock, RepVGGBlock, RepCSPBlock
  5. except:
  6. from yolov6_basic import RepBlock, RepVGGBlock, RepCSPBlock
  7. # --------------------- Yolov3's Backbone -----------------------
  8. ## Modified DarkNet
  9. class Yolov6Backbone(nn.Module):
  10. def __init__(self, cfg):
  11. super(Yolov6Backbone, self).__init__()
  12. # ------------------ Basic setting ------------------
  13. self.cfg = cfg
  14. self.model_scale = cfg.scale
  15. self.feat_dims = [round(64 * cfg.width),
  16. round(128 * cfg.width),
  17. round(256 * cfg.width),
  18. round(512 * cfg.width),
  19. round(1024 * cfg.width)]
  20. # ------------------ Network setting ------------------
  21. ## P1/2
  22. self.layer_1 = RepVGGBlock(3, self.feat_dims[0],
  23. kernel_size=3, padding=1, stride=2)
  24. # P2/4
  25. self.layer_2 = self.make_block(self.feat_dims[0], self.feat_dims[1], round(6*cfg.depth))
  26. # P3/8
  27. self.layer_3 = self.make_block(self.feat_dims[1], self.feat_dims[2], round(12*cfg.depth))
  28. # P4/16
  29. self.layer_4 = self.make_block(self.feat_dims[2], self.feat_dims[3], round(18*cfg.depth))
  30. # P5/32
  31. self.layer_5 = self.make_block(self.feat_dims[3], self.feat_dims[4], round(6*cfg.depth))
  32. # Initialize all layers
  33. self.init_weights()
  34. def make_block(self, in_dim, out_dim, num_blocks=1):
  35. if self.model_scale in ["s", "t", "n"]:
  36. block = nn.Sequential(
  37. RepVGGBlock(in_dim, out_dim,
  38. kernel_size=3, padding=1, stride=2),
  39. RepBlock(in_channels = out_dim,
  40. out_channels = out_dim,
  41. num_blocks = num_blocks,
  42. block = RepVGGBlock)
  43. )
  44. elif self.model_scale in ["m", "l"]:
  45. block = nn.Sequential(
  46. RepVGGBlock(in_dim, out_dim,
  47. kernel_size=3, padding=1, stride=2),
  48. RepCSPBlock(in_channels = out_dim,
  49. out_channels = out_dim,
  50. num_blocks = num_blocks,
  51. expansion = self.cfg.bk_csp_expansion)
  52. )
  53. else:
  54. raise NotImplementedError("Unknown model scale: {}".format(self.model_scale))
  55. return block
  56. def init_weights(self):
  57. """Initialize the parameters."""
  58. for m in self.modules():
  59. if isinstance(m, torch.nn.Conv2d):
  60. # In order to be consistent with the source code,
  61. # reset the Conv2d initialization parameters
  62. m.reset_parameters()
  63. def forward(self, x):
  64. c1 = self.layer_1(x)
  65. c2 = self.layer_2(c1)
  66. c3 = self.layer_3(c2)
  67. c4 = self.layer_4(c3)
  68. c5 = self.layer_5(c4)
  69. outputs = [c3, c4, c5]
  70. return outputs
  71. if __name__ == '__main__':
  72. import time
  73. from thop import profile
  74. class BaseConfig(object):
  75. def __init__(self) -> None:
  76. self.bk_depthwise = False
  77. self.width = 0.50
  78. self.depth = 0.34
  79. self.scale = "s"
  80. self.use_pretrained = True
  81. cfg = BaseConfig()
  82. model = Yolov6Backbone(cfg)
  83. x = torch.randn(1, 3, 640, 640)
  84. t0 = time.time()
  85. outputs = model(x)
  86. t1 = time.time()
  87. print('Time: ', t1 - t0)
  88. for out in outputs:
  89. print(out.shape)
  90. for m in model.modules():
  91. if hasattr(m, "switch_to_deploy"):
  92. m.switch_to_deploy()
  93. x = torch.randn(1, 3, 640, 640)
  94. print('==============================')
  95. flops, params = profile(model, inputs=(x, ), verbose=False)
  96. print('==============================')
  97. print('GFLOPs : {:.2f}'.format(flops / 1e9 * 2))
  98. print('Params : {:.2f} M'.format(params / 1e6))