henry000 commited on
Commit
4f5ca28
·
1 Parent(s): 6e3c0d5

🔨 [Add] Some Basic Module into models

Browse files

Adding some Basic module, e.g. Conv, Pool. Other module are waiting for refactor.
TODO 1: write a pytest and write RepNCSPELAN4.
TODO 2: check if we need fuse forward or not. Also, the weight initalize should be apply

Files changed (1) hide show
  1. yolo/model/module.py +97 -8
yolo/model/module.py CHANGED
@@ -1,5 +1,96 @@
 
 
1
  import torch
2
- import torch.nn as nn
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
 
4
 
5
  # basic
@@ -247,20 +338,18 @@ class RepDark(nn.Module):
247
  # CSPNet
248
  class CSP(nn.Module):
249
  # CSPNet
250
- def __init__(self, in_channels, out_channels, repeat=1, cb_repeat=2, act=nn.ReLU(), ratio=1.0):
251
-
252
  super().__init__()
253
-
254
  h_channels = in_channels // 2
255
  self.cv1 = Conv(in_channels, in_channels, 1, 1, act=act)
256
  self.cb = nn.Sequential(*(ResConvBlock(h_channels, act=act, repeat=cb_repeat) for _ in range(repeat)))
257
  self.cv2 = Conv(2 * h_channels, out_channels, 1, 1, act=act)
258
 
259
  def forward(self, x):
260
-
261
- y = list(self.cv1(x).chunk(2, 1))
262
-
263
- return self.cv2(torch.cat((self.cb(y[0]), y[1]), 1))
264
 
265
 
266
  class CSPDark(nn.Module):
 
1
+ from typing import Optional
2
+
3
  import torch
4
+ from torch import Tensor, nn
5
+ from torch.nn.common_types import _size_2_t
6
+
7
+ from yolo.tools.module_helper import auto_pad, get_activation
8
+
9
+
10
+ class Conv(nn.Module):
11
+ """A basic convolutional block that includes convolution, batch normalization, and activation."""
12
+
13
+ def __init__(
14
+ self, in_channels: int, out_channels: int, kernel_size: _size_2_t, activation: Optional[str] = "SiLU", **kwargs
15
+ ):
16
+ super().__init__()
17
+ kwargs.setdefault("padding", auto_pad(kernel_size, **kwargs))
18
+ self.conv = nn.Conv2d(in_channels, out_channels, kernel_size, **kwargs)
19
+ self.bn = nn.BatchNorm2d(out_channels)
20
+ self.act = get_activation(activation)
21
+
22
+ def forward(self, x: Tensor) -> Tensor:
23
+ return self.act(self.bn(self.conv(x)))
24
+
25
+
26
+ class Pool(nn.Module):
27
+ """A generic pooling block supporting 'max' and 'avg' pooling methods."""
28
+
29
+ def __init__(self, method: str = "max", kernel_size: _size_2_t = 1, **kwargs):
30
+ super().__init__()
31
+ kwargs.setdefault("padding", auto_pad(kernel_size, **kwargs))
32
+ pool_classes = {"max": nn.MaxPool2d, "avg": nn.AvgPool2d}
33
+ self.pool = pool_classes[method.lower()](kernel_size=kernel_size, **kwargs)
34
+
35
+ def forward(self, x: Tensor) -> Tensor:
36
+ return self.pool(x)
37
+
38
+
39
+ class ADown(nn.Module):
40
+ """Downsampling module combining average and max pooling with convolution for feature reduction."""
41
+
42
+ def __init__(self, in_channels: int, out_channels: int):
43
+ super().__init__()
44
+ half_in_channels = in_channels // 2
45
+ half_out_channels = out_channels // 2
46
+ mid_layer = {"kernel_size": 3, "stride": 2}
47
+ self.avg_pool = Pool("avg", kernel_size=2, stride=1)
48
+ self.conv1 = Conv(half_in_channels, half_out_channels, **mid_layer)
49
+ self.max_pool = Pool("max", **mid_layer)
50
+ self.conv2 = Conv(half_in_channels, half_out_channels, kernel_size=1)
51
+
52
+ def forward(self, x: Tensor) -> Tensor:
53
+ x = self.avg_pool(x)
54
+ x1, x2 = x.chunk(2, dim=1)
55
+ x1 = self.conv1(x1)
56
+ x2 = self.max_pool(x2)
57
+ x2 = self.conv2(x2)
58
+ return torch.cat((x1, x2), dim=1)
59
+
60
+
61
+ class CBLinear(nn.Module):
62
+ """Convolutional block that outputs multiple feature maps split along the channel dimension."""
63
+
64
+ def __init__(self, in_channels: int, out_channels: int, kernel_size: int = 1, **kwargs):
65
+ super(CBLinear, self).__init__()
66
+ kwargs.setdefault("padding", auto_pad(kernel_size, **kwargs))
67
+ self.conv = nn.Conv2d(in_channels, sum(out_channels), kernel_size, **kwargs)
68
+ self.out_channels = out_channels
69
+
70
+ def forward(self, x: Tensor) -> tuple[Tensor]:
71
+ x = self.conv(x)
72
+ return x.split(self.out_channels, dim=1)
73
+
74
+
75
+ class SPPELAN(nn.Module):
76
+ """SPPELAN module comprising multiple pooling and convolution layers."""
77
+
78
+ def __init__(self, in_channels, out_channels, neck_channels=Optional[int]):
79
+ super(SPPELAN, self).__init__()
80
+ neck_channels = neck_channels or out_channels // 2
81
+
82
+ self.conv1 = Conv(in_channels, neck_channels, kernel_size=1)
83
+ self.pools = nn.ModuleList([Pool("max", 5, padding=0) for _ in range(3)])
84
+ self.conv5 = Conv(4 * neck_channels, out_channels, kernel_size=1)
85
+
86
+ def forward(self, x: Tensor) -> Tensor:
87
+ features = [self.conv1(x)]
88
+ for pool in self.pools:
89
+ features.append(pool(features[-1]))
90
+ return self.conv5(torch.cat(features, dim=1))
91
+
92
+
93
+ #### -- ####
94
 
95
 
96
  # basic
 
338
  # CSPNet
339
  class CSP(nn.Module):
340
  # CSPNet
341
+ def __init__(self, in_channels, out_channels, repeat=1, cb_repeat=2, act=nn.ReLU()):
 
342
  super().__init__()
 
343
  h_channels = in_channels // 2
344
  self.cv1 = Conv(in_channels, in_channels, 1, 1, act=act)
345
  self.cb = nn.Sequential(*(ResConvBlock(h_channels, act=act, repeat=cb_repeat) for _ in range(repeat)))
346
  self.cv2 = Conv(2 * h_channels, out_channels, 1, 1, act=act)
347
 
348
  def forward(self, x):
349
+ x = list(self.cv1(x).chunk(2, 1))
350
+ x = torch.cat((self.cb(x[0]), x[1]), 1)
351
+ x = self.cv2(x)
352
+ return x
353
 
354
 
355
  class CSPDark(nn.Module):