1、问题描述
问题源自之前写的一篇博客:【魔改YOLOv5-6.x(中)】:加入ACON激活函数、CBAM和CA注意力机制、加权双向特征金字塔BiFPN,尝试在YOLOv5的backbone中加入Coordinate Attention,虽然加入后mAP有提升,但是重要的GFLOPs信息却无法显示!!
2、问题解决
于是我就开始了疯狂debug,在各个位置加断点,加断点,终于锁定源头:CABlock类函数的定义
这是CABlock原始类函数,在__init__
中定义了两个自适应平均池化nn.AdaptiveAvgPool2d()
,正是这两个自适应平均池化,导致加入CA后GFLOPs信息无法显示,具体原因目前还不清楚,欢迎各位大佬前来交流~
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
于是,我改成了下面这样,问题就得到解决了
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