Convolutional Block Attention Module(CBAM):CBAM是一种组合模型,将通道注意力和空间注意力相结合,以提高模型的表现力。
CBAM 模块包括两个注意力子模块:通道注意力模块和空间注意力模块。通道注意力模块用于计算每个通道的重要性,以便更好地区分不同通道之间的特征。空间注意力模块则用于计算每个像素在空间上的重要性,以便更好地捕捉图像中的空间结构。
通道注意力模块通过对输入特征图在通道维度上进行最大池化和平均池化,然后将这两个池化结果输入到一个全连接层中,最后输出一个通道注意力权重向量。这个向量用于加权输入特征图中的每个通道,从而更好地区分不同通道的特征。
空间注意力模块通过对输入特征图在通道维度上进行平均池化和最大池化,然后将这两个池化结果输入到一个全连接层中,最后输出一个空间注意力权重张量。这个张量用于对每个像素在空间上进行加权,从而更好地捕捉图像中的空间结构。
CBAM 模块的整体结构如下图所示:
在图中,绿色框表示通道注意力模块,橙色框表示空间注意力模块。通过将这两个模块串联起来,可以得到一个完整的 CBAM 模块,用于插入到卷积神经网络中以提升模型性能。
用pytorch实现CBAM:
import torch
import torch.nn as nn
import torch.nn.functional as F
class ChannelAttention(nn.Module):
def __init__(self, in_channels, reduction_ratio=16):
super(ChannelAttention, self).__init__()
self.avg_pool = nn.AdaptiveAvgPool2d(1)
self.max_pool = nn.AdaptiveMaxPool2d(1)
self.fc1 = nn.Conv2d(in_channels, in_channels // reduction_ratio, 1, bias=False)
self.relu = nn.ReLU()
self.fc2 = nn.Conv2d(in_channels // reduction_ratio, in_channels, 1, bias=False)
self.sigmoid = nn.Sigmoid()
def forward(self, x):
avg_out = self.fc2(self.relu(self.fc1(self.avg_pool(x))))
max_out = self.fc2(self.relu(self.fc1(self.max_pool(x))))
out = avg_out + max_out
return self.sigmoid(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)
x = torch.cat([avg_out, max_out], dim=1)
x = self.conv(x)
return self.sigmoid(x)
class CBAM(nn.Module):
def __init__(self, in_channels, reduction_ratio=16, kernel_size=7):
super(CBAM, self).__init__()
self.channel_att = ChannelAttention(in_channels, reduction_ratio)
self.spatial_att = SpatialAttention(kernel_size)
def forward(self, x):
out = self.channel_att(x) * x
out = self.spatial_att(out) * out
return out
以上代码中实现了 CBAM 模块的两个子模块:通道注意力模块(ChannelAttention)和空间注意力模块(SpatialAttention),以及整个 CBAM 模块(CBAM)。
其中通道注意力模块通过对输入特征图在通道维度上进行最大池化和平均池化,然后将这两个池化结果输入到一个全连接层中,最后输出一个通道注意力权重向量。空间注意力模块则通过对输入特征图在通道维度上进行平均池化和最大池化,然后将这两个池化结果输入到一个全连接层中,最后输出一个空间注意力权重张量。CBAM 模块则将这两个子模块串联起来,用于插入到卷积神经网络中以提升模型性能。
在模型中使用CBAM模块:
class MyModel(nn.Module):
def __init__(self):
super(MyModel, self).__init__()
self.conv1 = nn.Conv2d(3, 64, kernel_size=3, padding=1)
self.cbam1 = CBAM(64)
self.conv2 = nn.Conv2d(64, 128, kernel_size=3, padding=1)
self.cbam2 = CBAM(128)
self.conv3 = nn.Conv2d(128, 256, kernel_size=3, padding=1)
self.cbam3 = CBAM(256)
self.fc = nn.Linear(256 * 8 * 8, 10)
def forward(self, x):
x = F.relu(self.conv1(x))
x = self.cbam1(x)
x = F.max_pool2d(x, kernel_size=2, stride=2)
x = F.relu(self.conv2(x))
x = self.cbam2(x)
x = F.max_pool2d(x, kernel_size=2, stride=2)
x = F.relu(self.conv3(x))
x = self.cbam3(x)
x = F.max_pool2d(x, kernel_size=2, stride=2)
x = x.view(x.size(0), -1)
x = self.fc(x)
return x
这是一个简单的卷积神经网络,其中包含三个卷积层和三个CBAM模块,最终使用一个全连接层将特征映射转换为预测标签。在前向传递过程中,输入特征图通过卷积层和CBAM模块进行特征提取和特征增强,然后通过最大池化层将特征图的空间尺寸降低,最终通过全连接层输出预测标签。
版权归原作者 木子十口儿几丶 所有, 如有侵权,请联系我们删除。