[YOLOv5-6.x] Resuelva el problema de que agregar el mecanismo de atención de CA no muestra FLOP

1. Descripción del problema

El problema proviene de un blog escrito antes: [Cambio mágico YOLOv5-6.x (medio)]: agregue la función de activación ACON, el mecanismo de atención CBAM y CA, la pirámide de funciones bidireccional ponderada BiFPN , intente agregar Coordinate Attention a la columna vertebral de YOLOv5, aunque mAP ha mejorado después de unirse, ¡pero no se puede mostrar información importante de GFLOP! !

2. Resolución de problemas

Así que comencé una depuración loca, agregué puntos de interrupción en varias ubicaciones, agregué puntos de interrupción y finalmente bloqueé la fuente: definición de la función de clase CABlock

Esta es la función de clase original de CABlock, en __init__la que se definen dos agrupaciones promedio adaptables nn.AdaptiveAvgPool2d(). Son estas dos agrupaciones promedio adaptables las que hacen que la información de GFLOP no se muestre después de agregar CA. El motivo específico aún no está claro. Bienvenidos todos. Vengan a comunicar ~

class CABlock(nn.Module):
    def __init__(self, inp, oup, reduction=32):
        super(CABlock, self).__init__()
        # ============================
        # height方向上的均值池化
        self.pool_h = nn.AdaptiveAvgPool2d((None, 1))
        # width方向上的均值池化
        self.pool_w = nn.AdaptiveAvgPool2d((1, None))

        mip = max(8, inp // reduction)

        self.conv1 = nn.Conv2d(inp, mip, kernel_size=1, stride=1, padding=0)
        self.bn1 = nn.BatchNorm2d(mip)
        self.act = h_swish()

        self.conv_h = nn.Conv2d(mip, oup, kernel_size=1, stride=1, padding=0)
        self.conv_w = nn.Conv2d(mip, oup, kernel_size=1, stride=1, padding=0)

    def forward(self, x):
        identity = x

        n, c, h, w = x.size()
        x_h = self.pool_h(x)
        x_w = self.pool_w(x).permute(0, 1, 3, 2)

        y = torch.cat([x_h, x_w], dim=2)
        y = self.conv1(y)
        y = self.bn1(y)
        y = self.act(y)

        x_h, x_w = torch.split(y, [h, w], dim=2)
        x_w = x_w.permute(0, 1, 3, 2)

        a_h = self.conv_h(x_h).sigmoid()
        a_w = self.conv_w(x_w).sigmoid()

        out = identity * a_w * a_h

        return out

Entonces, lo cambié a lo siguiente, y el problema se resolvió.

class CABlock(nn.Module):
    def __init__(self, inp, oup, reduction=32):
        super(CABlock, self).__init__()
        mip = max(8, inp // reduction)

        self.conv1 = nn.Conv2d(inp, mip, 1, 1, bias=False)
        self.bn1 = nn.BatchNorm2d(mip)
        self.act = h_swish()

        self.conv_h = nn.Conv2d(mip, oup, 1, 1, bias=False)
        self.conv_w = nn.Conv2d(mip, oup, 1, 1, bias=False)

    def forward(self, x):
        identity = x
        _, _, h, w = x.size()
        pool_h = nn.AdaptiveAvgPool2d((h, 1))
        x_h = pool_h(x)
        pool_w = nn.AdaptiveAvgPool2d((1, w))
        x_w = pool_w(x).permute(0, 1, 3, 2)

        y = torch.cat([x_h, x_w], dim=2)
        y = self.conv1(y)
        y = self.bn1(y)
        y = self.act(y)

        y_h, y_w = torch.split(y, [h, w], dim=2)
        y_w = y_w.permute(0, 1, 3, 2)

        a_h = self.conv_h(y_h).sigmoid()
        a_w = self.conv_w(y_w).sigmoid()

        return identity * a_w * a_h

Supongo que te gusta

Origin blog.csdn.net/weixin_43799388/article/details/124086801
Recomendado
Clasificación