1.引言
金字塔池化模块是yolo系列十分重要的一个改进点,因此,这个地方如果选择多种改进,当然,这里也可以做多种消融实验说明自己的改进有效。
下面以SimSPPF为例,写出如何修改SPPF。
2.改进
2.1 ultralytics/nn/modules/block.py
在文件下方添加SimSPPF
SimSPPF代码
class SimConv(nn.Module):
'''Normal Conv with ReLU activation'''
def __init__(self, in_channels, out_channels, kernel_size, stride, groups=1, bias=False):
super().__init__()
padding = kernel_size // 2
self.conv = nn.Conv2d(
in_channels,
out_channels,
kernel_size=kernel_size,
stride=stride,
padding=padding,
groups=groups,
bias=bias,
)
self.bn = nn.BatchNorm2d(out_channels)
self.act = nn.ReLU()
def forward(self, x):
return self.act(self.bn(self.conv(x)))
def forward_fuse(self, x):
return self.act(self.conv(x))
class SimSPPF(nn.Module):
'''Simplified SPPF with ReLU activation'''
def __init__(self, in_channels, out_channels, kernel_size=5):
super().__init__()
c_ = in_channels // 2 # hidden channels
self.cv1 = SimConv(in_channels, c_, 1, 1)
self.cv2 = SimConv(c_ * 4, out_channels, 1, 1)
self.m = nn.MaxPool2d(kernel_size=kernel_size, stride=1, padding=kernel_size // 2)
def forward(self, x):
x = self.cv1(x)
with warnings.catch_warnings():
warnings.simplefilter('ignore')
y1 = self.m(x)
y2 = self.m(y1)
return self.cv2(torch.cat([x, y1, y2, self.m(y2)], 1))
在block.py开头__all__中添加与上面类相同的名字,即此处为SimSPPF
2.2 ultralytics/nn/modules/init.py
如下图,我们是在block.py中添加的SimSPPF,因此,下面也在.block中添加,__all__中也一样添加
2.3 ultralytics/nn/tasks.py
依然如下图,由于上述我们在 ultralytics/nn/modules中添加的,此处我们添加到ultralytics.nn.modules下,
在代码中,找到def parse_model(d, ch, verbose=True): # model_dict, input_channels(3)方法,找到和SPP在一个括号里的if m in ,添加到后面。
if m in (Classify, Conv, ConvTranspose, GhostConv, Bottleneck, GhostBottleneck, SPP, SPPF, DWConv, Focus,
BottleneckCSP, C1, C2, C2f, C3, C3TR, C3Ghost, nn.ConvTranspose2d, DWConvTranspose2d, C3x, RepC3,
SimSPPF):
2.4 yaml文件修改(ultralytics/cfg/models/v8/yolov8n.yaml)
只需要把yaml的SPPF改为SimSPPF即可,这里推荐复制一份yaml文件,yolov8n-SimSPPF即可,记得训练的时候使用改了的这个网络结构。
3.其他常见金字塔结构代码
修改方式基本相同,下面帖子是常见特征金字塔的代码实现
点击此帖