YOLOv5新增註意力機制的具體步驟

專注的阿熊發表於2022-09-29

class ChannelAttention(nn.Module):

     def __init__(self, in_planes, ratio=16):

         super(ChannelAttention, self).__init__()

         self.avg_pool = nn.AdaptiveAvgPool2d(1)

         self.max_pool = nn.AdaptiveMaxPool2d(1)

         self.f1 = nn.Conv2d(in_planes, in_planes // ratio, 1, bias=False)

         self.relu = nn.ReLU()

         self.f2 = nn.Conv2d(in_planes // ratio, in_planes, 1, bias=False)

         # 寫法二 , 亦可使用順序容器

         # self.sharedMLP = nn.Sequential(

         # nn.Conv2d(in_planes, in_planes // ratio, 1, bias=False), nn.ReLU(),

         # nn.Conv2d(in_planes // rotio, in_planes, 1, bias=False))

         self.sigmoid = nn.Sigmoid()

     def forward(self, x):

         avg_out = self.f2(self.relu(self.f1(self.avg_pool(x))))

         max_out = self.f2(self.relu(self.f1(self.max_pool(x))))

         out = self.sigmoid(avg_out + max_out)

         return torch.mul(x, out)

class SpatialAttention(nn.Module):

     def __init__(self, kernel_size=7):

         super(SpatialAttention, self).__init__()

         assert kernel_size in (3, 7), 'kernel size must be 3 or 7'

         padding = 3 if kernel_size == 7 else 1

         self.conv = nn.Conv2d(2, 1, kernel_size, padding=padding, bias=False)

         self.sigmoid = nn.Sigmoid()

     def forward(self, x):

         avg_out = torch.mean(x, dim=1, keepdim=True)

         max_out, _ = torch.max(x, dim=1, keepdim=True)

         out = torch.cat([avg_out, max_out], dim=1)

         out = self.sigmoid(self.conv(out))

         return torch.mul(x, out)

class CBAMC3(nn.Module):

     # CSP Bottleneck with 3 convolutions

     def __init__(self, c1, c2, n=1, shortcut=True, g=1, e=0.5):  # ch_in, ch_out, number, shortcut, groups, expansion

         super(CBAMC3, self).__init__()

         c_ = int(c2 * e)  # hidden channels

         self.cv1 = 跟單網gendan5.comConv(c1, c_, 1, 1)

         self.cv2 = Conv(c1, c_, 1, 1)

         self.cv3 = Conv(2 * c_, c2, 1)

         self.m = nn.Sequential(*[Bottleneck(c_, c_, shortcut, g, e=1.0) for _ in range(n)])

         self.channel_attention = ChannelAttention(c2, 16)

         self.spatial_attention = SpatialAttention(7)

         # self.m = nn.Sequential(*[CrossConv(c_, c_, 3, 1, g, 1.0, shortcut) for _ in range(n)])

     def forward(self, x):

      # 將最後的標準卷積模組改為了注意力機制提取特徵

         return self.spatial_attention(

             self.channel_attention(self.cv3(torch.cat((self.m(self.cv1(x)), self.cv2(x)), dim=1))))

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69946337/viewspace-2916723/,如需轉載,請註明出處,否則將追究法律責任。

相關文章