yolo11_neck.py 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. import torch
  2. import torch.nn as nn
  3. try:
  4. from .modules import ConvModule, PSABlock
  5. except:
  6. from modules import ConvModule, PSABlock
  7. class SPPF(nn.Module):
  8. def __init__(self, in_dim, out_dim, spp_pooling_size: int = 5, neck_expand_ratio:float = 0.5):
  9. super().__init__()
  10. ## ----------- Basic Parameters -----------
  11. inter_dim = round(in_dim * neck_expand_ratio)
  12. self.out_dim = out_dim
  13. ## ----------- Network Parameters -----------
  14. self.cv1 = ConvModule(in_dim, inter_dim, kernel_size=1, stride=1)
  15. self.cv2 = ConvModule(inter_dim * 4, out_dim, kernel_size=1, stride=1)
  16. self.m = nn.MaxPool2d(kernel_size=spp_pooling_size, stride=1, padding=spp_pooling_size // 2)
  17. def forward(self, x):
  18. x = self.cv1(x)
  19. y1 = self.m(x)
  20. y2 = self.m(y1)
  21. return self.cv2(torch.cat((x, y1, y2, self.m(y2)), 1))
  22. class C2PSA(nn.Module):
  23. def __init__(self, in_dim, out_dim, num_blocks=1, expansion=0.5):
  24. super().__init__()
  25. assert in_dim == out_dim
  26. inter_dim = int(in_dim * expansion)
  27. self.cv1 = ConvModule(in_dim, 2 * inter_dim, kernel_size=1)
  28. self.cv2 = ConvModule(2 * inter_dim, in_dim, kernel_size=1)
  29. self.m = nn.Sequential(*[
  30. PSABlock(in_dim = inter_dim,
  31. attn_ratio = 0.5,
  32. num_heads = inter_dim // 64
  33. ) for _ in range(num_blocks)])
  34. def forward(self, x):
  35. x1, x2 = torch.chunk(self.cv1(x), chunks=2, dim=1)
  36. x2 = self.m(x2)
  37. return self.cv2(torch.cat([x1, x2], dim=1))