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