(已解决)TypeError: isinstance() arg 2 must be a type or tuple of types

错误如下:

 File "D:\project\boxmot-3.0\boxmot-3.0\./yolov5\models\yolo.py", line 340, in fuse
    if isinstance(m, (Conv, DWConv)) and hasattr(m, "bn"):
TypeError: isinstance() arg 2 must be a type or tuple of types

错误位置文件对应如下定义:

def fuse(self):
        """Fuses Conv2d() and BatchNorm2d() layers in the model to improve inference speed."""
        LOGGER.info("Fusing layers... ")
        for m in self.model.modules():
            if isinstance(m, (Conv, DWConv)) and hasattr(m, "bn"):
                m.conv = fuse_conv_and_bn(m.conv, m.bn)  # update conv
                delattr(m, "bn")  # remove batchnorm
                m.forward = m.forward_fuse  # update forward
        self.info()
        return self

common文件中Conv和 DWConv的定义如下:

def DWConv(c1, c2, k=1, s=1, act=True):
    # Depthwise convolution
    return Conv(c1, c2, k, s, g=math.gcd(c1, c2), act=act)


class Conv(nn.Module):
    # Standard convolution
    def __init__(self, c1, c2, k=1, s=1, p=None, g=1, act=True):  # ch_in, ch_out, kernel, stride, padding, groups
        super(Conv, self).__init__()
        self.conv = nn.Conv2d(c1, c2, k, s, autopad(k, p), groups=g, bias=False)
        self.bn = nn.BatchNorm2d(c2)
        self.act = nn.SiLU() 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 fuseforward(self, x):
        return self.act(self.conv(x))

DWConv 函数实际上并没有返回一个新的类实例,而是调用了 Conv 类并返回了一个 Conv 实例。这意味着 DWConv 并不是一个类类型,而是一个函数,它返回的是 Conv 类的实例。因此,在 fuse 方法中使用 isinstance(m, (Conv, DWConv)) 是不正确的,因为 DWConv 不是一个类型,而是一个函数。

为了解决这个问题,需要在 fuse 方法中检查模块是否是 Conv 类的实例,并且如果它是通过 DWConv 函数创建的(即具有特定的属性或结构),则需要额外处理。但是,由于 DWConv 只是调用了 Conv 并没有引入新的类,因此实际上只需要检查 m 是否是 Conv 的实例。

不过,为了保持代码的清晰和可维护性,可以考虑在 Conv 类中添加一个额外的属性来标记它是否是通过 DWConv 函数创建的。但是,在这个特定的情况下,由于 DWConv 仅仅设置了 groups 参数,并且这个参数在 Conv 类的构造函数中已经处理,其实不需要做这种区分。

因此,可以简单地修改 fuse 方法,只检查 m 是否是 Conv 的实例:

def fuse(self):  
    """Fuses Conv2d() and BatchNorm2d() layers in the model to improve inference speed."""  
    LOGGER.info("Fusing layers... ")  
    for m in self.model.modules():  
        if isinstance(m, Conv) and hasattr(m, "bn"):  
            m.conv = fuse_conv_and_bn(m.conv, m.bn)  # update conv  
            delattr(m, "bn")  # remove batchnorm  
            m.forward = m.forward_fuse  # update forward  
    self.info()  
    return self

一般情况下将上面代码替换原来的就可以解决错误了。

注意,这里假设 fuse_conv_and_bn 函数已经正确定义,并且 forward_fuse 方法也在 Conv 类中定义好了。

另外,如果 Conv 类中的 forward_fuse 方法还没有定义,你需要添加它,以便在融合卷积层和批归一化层后使用。这个方法应该类似于原始的 forward 方法,但是不需要调用 bn 层。

class Conv(nn.Module):  
    # ...(其他代码保持不变)  
  
    def forward_fuse(self, x):  
        return self.act(self.conv(x))

最后,请确保 LOGGER 已经被正确定义,否则代码将在尝试记录信息时抛出另一个错误。如果 LOGGER 没有定义,可以使用 Python 的标准日志库来创建一个:

import logging  
LOGGER = logging.getLogger(__name__)  
LOGGER.setLevel(logging.INFO)  
# 如果需要,可以添加日志处理器来将日志输出到控制台或文件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值