YOLOv5 backbone replacement from Darknet to Resnet-50 shape issues

492 Views Asked by At

i am a researcher and want to change the current backbon of YOLOv5 from darknet to resnet for that I added the these 2 classes in commons.py. i am getting this shape error after adding Maxpooling2D and Resblock class names in Yolo.py model summary is printed on screen succesfully after that this error occurs.

class Conv(nn.Module):
    # Standard convolution with args(ch_in, ch_out, kernel, stride, padding, groups, dilation, activation)
    default_act = nn.SiLU()  # default activation

    def __init__(self, c1, c2, k=1, s=1, p=None, g=1, d=1, act=True):
        super().__init__()
        self.conv = nn.Conv2d(c1, c2, k, s, autopad(k, p, d), groups=g, dilation=d, bias=False)
        self.bn = nn.BatchNorm2d(c2)
        self.act = self.default_act if act is True else act if isinstance(act, nn.Module) else nn.Identity()

    def forward(self, x):
        return self.act(self.bn(self.conv(x)))

    def forward_fuse(self, x):
        return self.act(self.conv(x))
class MaxPooling2D(nn.Module):
    # MaxPooling2D layer with args(kernel, stride, padding)
    def __init__(self, k=2, s=2, p=0):
        super().__init__()
        self.maxpool = nn.MaxPool2d(k, s, p)

    def forward(self, x):
        return self.maxpool(x)

class ResBlock(nn.Module):
    def __init__(self, c1, num_repeats):
        super().__init__()
        self.blocks = nn.Sequential(*[
            nn.Identity() if i == 0 else Conv(c1, c1, k=3, s=1, act=True) for i in range(num_repeats)
        ])

    def forward(self, x):
        return torch.cat(x, self.blocks(x))

#Backbone
backbone: [
    [-1, 1, "Conv", [64, 6, 2, 2]],  # 0 - Conv1
    [-1, 1, "MaxPooling2D", [3, 2]],   # 1 - MaxPool
    [-1, 3, "ResBlock", [64]],         # 2 - Res2a, Res2b, Res2c
    [-1, 1, "Conv", [128, 3, 2]], # 3 - Conv3
    [-1, 4, "ResBlock", [128]],        # 4 - Res3a, Res3b, Res3c, Res3d
    [-1, 1, "Conv", [256, 3, 2]], # 5 - Conv4
    [-1, 6, "ResBlock", [256]],        # 6 - Res4a, Res4b, Res4c, Res4d, Res4e, Res4f
    [-1, 1, "Conv", [512, 3, 2]], # 7 - Conv5
    [-1, 3, "ResBlock", [512]],        # 8 - Res5a, Res5b, Res5c
    [-1, 1, "SPPF", [1024, 5]]         # 9 - SPPF
    ]
Traceback (most recent call last):
  File "train.py", line 647, in <module>
    main(opt)
  File "train.py", line 536, in main
    train(opt.hyp, opt, device, callbacks)
  File "train.py", line 130, in train
    model = Model(cfg or ckpt['model'].yaml, ch=3, nc=nc, anchors=hyp.get('anchors')).to(device)  # create
  File "/home/dev/Documents/yolov5/models/yolo.py", line 195, in __init__
    m.stride = torch.tensor([s / x.shape[-2] for x in forward(torch.zeros(1, ch, s, s))])  # forward
  File "/home/dev/Documents/yolov5/models/yolo.py", line 194, in <lambda>
    forward = lambda x: self.forward(x)[0] if isinstance(m, Segment) else self.forward(x)
  File "/home/dev/Documents/yolov5/models/yolo.py", line 209, in forward
    return self._forward_once(x, profile, visualize)  # single-scale inference, train
  File "/home/dev/Documents/yolov5/models/yolo.py", line 121, in _forward_once
    x = m(x)  # run
  File  "/home/dev/Documents/yolov5/models/common.py", line 90, in forward
    return torch.cat(x, self.blocks(x))
  File "/home/dev/Documents/yolov5/models/common.py", line 68, in forward
    return self.act(self.bn(self.conv(x)))
  File "/home/dev/.cache/pypoetry/virtualenvs/yolov5-FT1Hnn5N-py3.8/lib/python3.8/site-packages/torch/nn/modules/module.py", line 1501, in _call_impl
    return forward_call(*args, **kwargs)
  File "/home/dev/.cache/pypoetry/virtualenvs/yolov5-FT1Hnn5N-py3.8/lib/python3.8/site-packages/torch/nn/modules/conv.py", line 463, in forward
    return self._conv_forward(input, self.weight, self.bias)
 RuntimeError: Given groups=1, weight of size [8, 8, 3, 3], expected input[1, 32, 13, 13] to have 8 channels, but got 32 channels instead```
2

There are 2 best solutions below

5
OverLoading On

maybe try set stride of MaxPooling2D to 1.

class MaxPooling2D(nn.Module):

def init(self, k=2, s=1, p=0):

6
Sauron On
  • check the config of your ResBlock class and ensure that the number of input channels matches the expected number of channels for the convolutional layer.
  • ResBlock class is expecting 64 input channels, but the convolutional layer within the ResBlock is expecting 8 input channels.
class ResBlock(nn.Module):
    def __init__(self, c1, num_repeats):
        super().__init__()
        self.blocks = nn.Sequential(*[
            nn.Identity() if i == 0 else Conv(c1, c1, k=3, s=1, act=True) for i in range(num_repeats)
        ])
        self.conv = Conv(c1, c1, k=3, s=1, act=True)  # Add this line

    def forward(self, x):
        return torch.cat(x, self.blocks(self.conv(x)))  # Modify this line

  • Add convolutional layer, and in forward mmethod pass the input tensor x through the self.conv layer before passing it to self.blocks. ensuring that the input tensor has the correct number of channels expected by the subsequent ResBlock layers.