AlanLi1997 / slim-neck-by-gsconv

Pytorch implementation of the 'Slim-neck by GSConv: a lightweight-design for real-time detector architectures'
https://link.springer.com/article/10.1007/s11554-024-01436-6
GNU General Public License v3.0
195 stars 12 forks source link

RunningError #35

Open lqh964165950 opened 1 week ago

lqh964165950 commented 1 week ago

Traceback (most recent call last): File "yolo.py", line 498, in model = Model(opt.cfg).to(device) File "yolo.py", line 258, in init m.stride = torch.tensor([s / x.shape[-2] for x in _forward(torch.zeros(1, ch, s, s))]) # forward File "yolo.py", line 254, in _forward return self.forward(x)[0] if isinstance(m, Segment) else self.forward(x) File "yolo.py", line 273, in forward return self._forward_once(x, profile, visualize) # single-scale inference, train File "yolo.py", line 172, in _forward_once x = m(x) # run File "/home/gxu4090x2/.conda/envs/yolo/lib/python3.8/site-packages/torch/nn/modules/module.py", line 1501, in _call_impl return forward_call(*args, **kwargs) File "/home/gxu4090x2/桌面/lqh/program/yolov5-master/models/slimneck.py", line 56, in forward x2 = torch.cat((x1, self.cv2(x1)), 1) RuntimeError: Sizes of tensors must match except in dimension 1. Expected size 10 but got size 8 for tensor number 1 in the list. 运行时出现这个错误,如何解决呢?

AlanLi1997 commented 1 week ago

Traceback (most recent call last): File "yolo.py", line 498, in model = Model(opt.cfg).to(device) File "yolo.py", line 258, in init m.stride = torch.tensor([s / x.shape[-2] for x in _forward(torch.zeros(1, ch, s, s))]) # forward File "yolo.py", line 254, in _forward return self.forward(x)[0] if isinstance(m, Segment) else self.forward(x) File "yolo.py", line 273, in forward return self._forward_once(x, profile, visualize) # single-scale inference, train File "yolo.py", line 172, in _forward_once x = m(x) # run File "/home/gxu4090x2/.conda/envs/yolo/lib/python3.8/site-packages/torch/nn/modules/module.py", line 1501, in _call_impl return forward_call(*args, **kwargs) File "/home/gxu4090x2/桌面/lqh/program/yolov5-master/models/slimneck.py", line 56, in forward x2 = torch.cat((x1, self.cv2(x1)), 1) RuntimeError: Sizes of tensors must match except in dimension 1. Expected size 10 but got size 8 for tensor number 1 in the list. 运行时出现这个错误,如何解决呢?

根据已有的信息我只能判断出:第一次使用GSConv时维度不匹配。请检查GSConv模块确保tensor维度匹配。

class GSConv(nn.Module):
    # GSConv https://github.com/AlanLi1997/slim-neck-by-gsconv
    def __init__(self, c1, c2, k=1, s=1, g=1, act=True):
        super().__init__()
        c_ = c2 // 2
        self.cv1 = Conv(c1, c_, k, s, None, g, act)
        self.cv2 = Conv(c_, c_, 5, 1, None, c_, act)

    def forward(self, x):
        x1 = self.cv1(x)
        x2 = torch.cat((x1, self.cv2(x1)), 1)
        # shuffle
        y = x2.reshape(x2.shape[0], 2, x2.shape[1] // 2, x2.shape[2], x2.shape[3])
        y = y.permute(0, 2, 1, 3, 4)
        return y.reshape(y.shape[0], -1, y.shape[3], y.shape[4])

如果你能报告更多相关信息,比如模型的yaml文件,或许可以让我更简单地帮助你。

lqh964165950 commented 1 week ago

YOLOv5 🚀 by Ultralytics, GPL-3.0 license

Slim-neck by GSConv: A better design paradigm of detector architectures for autonomous vehicle

Parameters

nc: 80 # number of classes depth_multiple: 0.33 # model depth multiple width_multiple: 0.50 # layer channel multiple anchors:

YOLOv5 v6.0 backbone

backbone:

[from, number, module, args]

[[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2 [-1, 1, Conv, [128, 3, 2]], # 1-P2/4 [-1, 3, C3, [128]], [-1, 1, Conv, [256, 3, 2]], # 3-P3/8 [-1, 6, C3, [256]], [-1, 1, Conv, [512, 3, 2]], # 5-P4/16 [-1, 9, C3, [512]], [-1, 1, Conv, [1024, 3, 2]], # 7-P5/32 [-1, 3, C3, [1024]], [-1, 1, SPPF, [1024, 5]], # 9 ]

YOLOv5 v6.0 head

head: [[-1, 1, GSConv, [512, 1, 1]], [-1, 1, nn.Upsample, [None, 2, 'nearest']], [[-1, 6], 1, Concat, [1]], # cat backbone P4 [-1, 3, C3, [512, False]], # 13

[-1, 1, GSConv, [256, 1, 1]], [-1, 1, nn.Upsample, [None, 2, 'nearest']], [[-1, 4], 1, Concat, [1]], # cat backbone P3 [-1, 3, C3, [256, False]], # 17 (P3/8-small)

[-1, 1, GSConv, [256, 3, 2]], [[-1, 14], 1, Concat, [1]], # cat head P4 [-1, 3, C3, [512, False]], # 20 (P4/16-medium)

[-1, 1, GSConv, [512, 3, 2]], [[-1, 10], 1, Concat, [1]], # cat head P5 [-1, 3, C3, [1024, False]], # 23 (P5/32-large)

[[17, 20, 23], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5) ] slimneck.py import torch import torch.nn as nn import math

def autopad(k, p=None, d=1): """ Pads kernel to 'same' output shape, adjusting for optional dilation; returns padding size. k: kernel, p: padding, d: dilation. """ if d > 1: k = d (k - 1) + 1 if isinstance(k, int) else [d (x - 1) + 1 for x in k] # actual kernel-size if p is None: p = k // 2 if isinstance(k, int) else [x // 2 for x in k] # auto-pad return p

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):
    """Initializes a standard convolution layer with optional batch normalization and activation."""
    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):
    """Applies a convolution followed by batch normalization and an activation function to the input tensor `x`."""
    return self.act(self.bn(self.conv(x)))

def forward_fuse(self, x):
    """Applies a fused convolution and activation function to the input tensor `x`."""
    return self.act(self.conv(x))

class DWConv(Conv): """Depth-wise convolution."""

def __init__(self, c1, c2, k=1, s=1, d=1, act=True):  # ch_in, ch_out, kernel, stride, dilation, activation
    """Initialize Depth-wise convolution with given parameters."""
    super().__init__(c1, c2, k, s, g=math.gcd(c1, c2), d=d, act=act)

class GSConv(nn.Module):

GSConv https://github.com/AlanLi1997/slim-neck-by-gsconv

def __init__(self, c1, c2, k=1, s=1, g=1, act=True):
    super().__init__()
    c_ = c2 // 2
    self.cv1 = Conv(c1, c_, k, s, None, g, act)
    self.cv2 = Conv(c_, c_, 5, 1, None, c_, act)

def forward(self, x):
    x1 = self.cv1(x)
    x2 = torch.cat((x1, self.cv2(x1)), 1)
    # shuffle
    y = x2.reshape(x2.shape[0], 2, x2.shape[1] // 2, x2.shape[2], x2.shape[3])
    y = y.permute(0, 2, 1, 3, 4)
    return y.reshape(y.shape[0], -1, y.shape[3], y.shape[4])

class GSConvns(GSConv):

GSConv with a normative-shuffle https://github.com/AlanLi1997/slim-neck-by-gsconv

def __init__(self, c1, c2, k=1, s=1, p=None, g=1, act=True):
    super().__init__(c1, c2, k, s, p, g, act=True)
    c_ = c2 // 2
    self.shuf = nn.Conv2d(c_ * 2, c2, 1, 1, 0, bias=False)

def forward(self, x):
    x1 = self.cv1(x)
    x2 = torch.cat((x1, self.cv2(x1)), 1)
    # normative-shuffle, TRT supported
    return nn.ReLU()(self.shuf(x2))

class GSBottleneck(nn.Module):

GS Bottleneck https://github.com/AlanLi1997/slim-neck-by-gsconv

def __init__(self, c1, c2, k=3, s=1, e=0.5):
    super().__init__()
    c_ = int(c2*e)
    # for lighting
    self.conv_lighting = nn.Sequential(
        GSConv(c1, c_, 1, 1),
        GSConv(c_, c2, 3, 1, act=False))
    self.shortcut = Conv(c1, c2, 1, 1, act=False)

def forward(self, x):
    return self.conv_lighting(x) + self.shortcut(x)

class GSBottleneckns(GSBottleneck):

GS Bottleneck https://github.com/AlanLi1997/slim-neck-by-gsconv

def __init__(self, c1, c2, k=3, s=1, e=0.5):
    super().__init__(c1, c2, k, s, e)
    c_ = int(c2*e)
    # for lighting
    self.conv_lighting = nn.Sequential(
        GSConvns(c1, c_, 1, 1),
        GSConvns(c_, c2, 3, 1, act=False))

class GSBottleneckC(GSBottleneck):

cheap GS Bottleneck https://github.com/AlanLi1997/slim-neck-by-gsconv

def __init__(self, c1, c2, k=3, s=1):
    super().__init__(c1, c2, k, s)
    self.shortcut = DWConv(c1, c2, k, s, act=False)

class VoVGSCSP(nn.Module):

VoVGSCSP module with GSBottleneck

def __init__(self, c1, c2, n=1, shortcut=True, g=1, e=0.5):
    super().__init__()
    c_ = int(c2 * e)  # hidden channels
    self.cv1 = Conv(c1, c_, 1, 1)
    self.cv2 = Conv(c1, c_, 1, 1)
    self.gsb = nn.Sequential(*(GSBottleneck(c_, c_, e=1.0) for _ in range(n)))
    self.res = Conv(c_, c_, 3, 1, act=False)
    self.cv3 = Conv(2 * c_, c2, 1)

def forward(self, x):
    x1 = self.gsb(self.cv1(x))
    y = self.cv2(x)
    return self.cv3(torch.cat((y, x1), dim=1))

class VoVGSCSPns(VoVGSCSP): def init(self, c1, c2, n=1, shortcut=True, g=1, e=0.5): super().init(c1, c2, n, shortcut, g, e) c = int(c2 e) # hidden channels self.gsb = nn.Sequential((GSBottleneckns(c, c, e=1.0) for in range(n)))

class VoVGSCSPC(VoVGSCSP):

cheap VoVGSCSP module with GSBottleneck

def __init__(self, c1, c2, n=1, shortcut=True, g=1, e=0.5):
    super().__init__(c1, c2)
    c_ = int(c2 * 0.5)  # hidden channels
    self.gsb = GSBottleneckC(c_, c_, 1, 1)
   换了你给出的GSConv模块后,又出现了不一样的错误:

Traceback (most recent call last): File "yolo.py", line 501, in model = Model(opt.cfg).to(device) File "yolo.py", line 258, in init m.stride = torch.tensor([s / x.shape[-2] for x in _forward(torch.zeros(1, ch, s, s))]) # forward File "yolo.py", line 254, in _forward return self.forward(x)[0] if isinstance(m, Segment) else self.forward(x) File "yolo.py", line 273, in forward return self._forward_once(x, profile, visualize) # single-scale inference, train File "yolo.py", line 172, in _forward_once x = m(x) # run File "/home/gxu4090x2/.conda/envs/yolo/lib/python3.8/site-packages/torch/nn/modules/module.py", line 1501, in _call_impl return forward_call(*args, kwargs) File "/home/gxu4090x2/桌面/lqh/program/yolov5-master/models/slimneck.py", line 55, in forward x1 = self.cv1(x) File "/home/gxu4090x2/.conda/envs/yolo/lib/python3.8/site-packages/torch/nn/modules/module.py", line 1501, in _call_impl return forward_call(*args, *kwargs) File "/home/gxu4090x2/桌面/lqh/program/yolov5-master/models/slimneck.py", line 31, in forward return self.act(self.bn(self.conv(x))) File "/home/gxu4090x2/.conda/envs/yolo/lib/python3.8/site-packages/torch/nn/modules/module.py", line 1501, in _call_impl return forward_call(args, kwargs) File "/home/gxu4090x2/.conda/envs/yolo/lib/python3.8/site-packages/torch/nn/modules/conv.py", line 463, in forward return self._conv_forward(input, self.weight, self.bias) File "/home/gxu4090x2/.conda/envs/yolo/lib/python3.8/site-packages/torch/nn/modules/conv.py", line 459, in _conv_forward return F.conv2d(input, weight, bias, self.stride, TypeError: conv2d() received an invalid combination of arguments - got (Tensor, Parameter, NoneType, tuple, tuple, tuple, int), but expected one of:

AlanLi1997 commented 1 week ago

@lqh964165950 尝试使用下面的GSConv代码:

class GSConv(nn.Module):
    # GSConv https://github.com/AlanLi1997/slim-neck-by-gsconv
    def __init__(self, c1, c2, k=1, s=1, g=1, d=1, act=True):
        super().__init__()
        c_ = c2 // 2
        self.cv1 = Conv(c1, c_, k, s, None, g, d, act)
        self.cv2 = Conv(c_, c_, 5, 1, None, c_, d, act)

    def forward(self, x):
        x1 = self.cv1(x)
        x2 = torch.cat((x1, self.cv2(x1)), 1)
        # shuffle
        y = x2.reshape(x2.shape[0], 2, x2.shape[1] // 2, x2.shape[2], x2.shape[3])
        y = y.permute(0, 2, 1, 3, 4)
        return y.reshape(y.shape[0], -1, y.shape[3], y.shape[4])
lqh964165950 commented 1 week ago

尝试使用上述的GSConv代码后,又出现如下报错: Traceback (most recent call last): File "yolo.py", line 501, in model = Model(opt.cfg).to(device) File "yolo.py", line 258, in init m.stride = torch.tensor([s / x.shape[-2] for x in _forward(torch.zeros(1, ch, s, s))]) # forward File "yolo.py", line 254, in _forward return self.forward(x)[0] if isinstance(m, Segment) else self.forward(x) File "yolo.py", line 273, in forward return self._forward_once(x, profile, visualize) # single-scale inference, train File "yolo.py", line 172, in _forward_once x = m(x) # run File "/home/gxu4090x2/.conda/envs/yolo/lib/python3.8/site-packages/torch/nn/modules/module.py", line 1501, in _call_impl return forward_call(*args, **kwargs) File "/home/gxu4090x2/桌面/lqh/program/yolov5-master/models/common.py", line 456, in forward return torch.cat(x, self.d) RuntimeError: Sizes of tensors must match except in dimension 1. Expected size 11 but got size 16 for tensor number 1 in the list.

AlanLi1997 commented 6 days ago

@lqh964165950 看起来tensor size 仍然不匹配,或许是padding的错误。尝试用这个:

class GSConv(nn.Module):
    # GSConv https://github.com/AlanLi1997/slim-neck-by-gsconv
    def __init__(self, c1, c2, k=1, s=1, g=1, d=1, act=True):
        super().__init__()
        c_ = c2 // 2
        self.cv1 = Conv(c1, c_, k, s, k//2, g, d, act)
        self.cv2 = Conv(c_, c_, 5, 1, k//2, c_, d, act)

    def forward(self, x):
        x1 = self.cv1(x)
        x2 = torch.cat((x1, self.cv2(x1)), 1)
        # shuffle
        y = x2.reshape(x2.shape[0], 2, x2.shape[1] // 2, x2.shape[2], x2.shape[3])
        y = y.permute(0, 2, 1, 3, 4)
        return y.reshape(y.shape[0], -1, y.shape[3], y.shape[4])

如果错误仍存在,尝试更改yaml文件的head部分为:

head:
[[-1, 1, Conv, [512, 1, 1]],
[-1, 1, nn.Upsample, [None, 2, 'nearest']],
[[-1, 6], 1, Concat, [1]], # cat backbone P4
[-1, 3, C3, [512, False]], # 13

[-1, 1, Conv, [256, 1, 1]],
[-1, 1, nn.Upsample, [None, 2, 'nearest']],
[[-1, 4], 1, Concat, [1]], # cat backbone P3
[-1, 3, C3, [256, False]], # 17 (P3/8-small)

[-1, 1, GSConv, [256, 3, 2]],
[[-1, 14], 1, Concat, [1]], # cat head P4
[-1, 3, C3, [512, False]], # 20 (P4/16-medium)

[-1, 1, GSConv, [512, 3, 2]],
[[-1, 10], 1, Concat, [1]], # cat head P5
[-1, 3, C3, [1024, False]], # 23 (P5/32-large)

[[17, 20, 23], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5)
]

如果错误继续存在,那么我认为必须检查对GSConv的输入参数的初始化代码,例如确保args = [c_in, c_out, k, s],和Conv一样。