yolov6_backbone.py 3.9 KB

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