yolov8_backbone.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. import torch
  2. import torch.nn as nn
  3. try:
  4. from .yolov8_basic import Conv, ELAN_CSP_Block
  5. except:
  6. from yolov8_basic import Conv, ELAN_CSP_Block
  7. # ---------------------------- Backbones ----------------------------
  8. ## ELAN-CSPNet
  9. class ELAN_CSPNet(nn.Module):
  10. def __init__(self, width=1.0, depth=1.0, ratio=1.0, act_type='silu', norm_type='BN', depthwise=False):
  11. super(ELAN_CSPNet, self).__init__()
  12. self.feat_dims = [int(256 * width), int(512 * width), int(512 * width * ratio)]
  13. # stride = 2
  14. self.layer_1 = Conv(3, int(64*width), k=3, p=1, s=2, act_type=act_type, norm_type=norm_type)
  15. # stride = 4
  16. self.layer_2 = nn.Sequential(
  17. Conv(int(64*width), int(128*width), k=3, p=1, s=2, act_type=act_type, norm_type=norm_type),
  18. ELAN_CSP_Block(int(128*width), int(128*width), nblocks=int(3*depth), shortcut=True,
  19. act_type=act_type, norm_type=norm_type, depthwise=depthwise)
  20. )
  21. # stride = 8
  22. self.layer_3 = nn.Sequential(
  23. Conv(int(128*width), int(256*width), k=3, p=1, s=2, act_type=act_type, norm_type=norm_type),
  24. ELAN_CSP_Block(int(256*width), int(256*width), nblocks=int(6*depth), shortcut=True,
  25. act_type=act_type, norm_type=norm_type, depthwise=depthwise)
  26. )
  27. # stride = 16
  28. self.layer_4 = nn.Sequential(
  29. Conv(int(256*width), int(512*width), k=3, p=1, s=2, act_type=act_type, norm_type=norm_type),
  30. ELAN_CSP_Block(int(512*width), int(512*width), nblocks=int(6*depth), shortcut=True,
  31. act_type=act_type, norm_type=norm_type, depthwise=depthwise)
  32. )
  33. # stride = 32
  34. self.layer_5 = nn.Sequential(
  35. Conv(int(512*width), int(512*width*ratio), k=3, p=1, s=2, act_type=act_type, norm_type=norm_type),
  36. ELAN_CSP_Block(int(512*width*ratio), int(512*width*ratio), nblocks=int(3*depth), shortcut=True,
  37. act_type=act_type, norm_type=norm_type, depthwise=depthwise)
  38. )
  39. def forward(self, x):
  40. c1 = self.layer_1(x)
  41. c2 = self.layer_2(c1)
  42. c3 = self.layer_3(c2)
  43. c4 = self.layer_4(c3)
  44. c5 = self.layer_5(c4)
  45. outputs = [c3, c4, c5]
  46. return outputs
  47. # ---------------------------- Functions ----------------------------
  48. ## build ELAN-Net
  49. def build_backbone(cfg):
  50. # model
  51. backbone = ELAN_CSPNet(
  52. width=cfg['width'],
  53. depth=cfg['depth'],
  54. ratio=cfg['ratio'],
  55. act_type=cfg['bk_act'],
  56. norm_type=cfg['bk_norm'],
  57. depthwise=cfg['bk_dpw']
  58. )
  59. feat_dims = backbone.feat_dims
  60. return backbone, feat_dims
  61. if __name__ == '__main__':
  62. import time
  63. from thop import profile
  64. cfg = {
  65. 'pretrained': True,
  66. 'bk_act': 'silu',
  67. 'bk_norm': 'BN',
  68. 'bk_dpw': False,
  69. 'width': 1.0,
  70. 'depth': 1.0,
  71. 'ratio': 1.0,
  72. }
  73. model, feats = build_backbone(cfg)
  74. x = torch.randn(1, 3, 640, 640)
  75. t0 = time.time()
  76. outputs = model(x)
  77. t1 = time.time()
  78. print('Time: ', t1 - t0)
  79. for out in outputs:
  80. print(out.shape)
  81. x = torch.randn(1, 3, 640, 640)
  82. print('==============================')
  83. flops, params = profile(model, inputs=(x, ), verbose=False)
  84. print('==============================')
  85. print('GFLOPs : {:.2f}'.format(flops / 1e9 * 2))
  86. print('Params : {:.2f} M'.format(params / 1e6))