CBAM:一个深度学习模型中的重要改进

一、CBAM代码解析

CBAM是一个基于注意力机制的深度学习模型改进方法,其全称为“Convolutional Block Attention Module”(卷积块注意力模块)。CBAM在卷积神经网络(CNN)中引入了两个注意力机制,分别是通道注意力和空间注意力。关于CBAM代码的解析,我们可以看一下其代码实现:

import torch.nn as nn
import torch.nn.functional as F

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.fc1 = nn.Conv2d(in_planes, in_planes // ratio, 1, bias=False)
        self.relu1 = nn.ReLU()
        self.fc2 = nn.Conv2d(in_planes // ratio, in_planes, 1, bias=False)

        self.sigmoid = nn.Sigmoid()

    def forward(self, x):
        avg_out = self.fc2(self.relu1(self.fc1(self.avg_pool(x))))
        max_out = self.fc2(self.relu1(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.conv1 = 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.conv1(x)
        return self.sigmoid(x)

上述代码中,ChannelAttention是用于通道注意力机制的类,SpatialAttention是用于空间注意力机制的类。在ChannelAttention类中,我们首先使用两个自适应池化层avg_pool和max_pool来对输入x进行平均值和最大值的计算。我们使用1×1的卷积层fc1和fc2对结果进行特征提取和映射,并使用ReLU激活函数对映射后的结果进行非线性处理。最后,我们使用Sigmoid函数将特征图映射到0到1的区间中,从而生成通道注意力图。

在对空间注意力机制进行处理时,我们使用一个卷积层对空间特征进行处理,然后使用Sigmoid激活函数将特征图映射到0到1的范围内。最终,我们将两个注意力机制的输出进行相乘,然后将结果与原始输入进行加和操作。这个加和操作中的权重由两个注意力机制的相乘结果确定。这样就完成了CBAM在深度学习模型中的引入。

二、CBAM代码实现

下面是一个使用CBAM的PyTorch代码实现,该模型可以用于进行图像分类:

import torch.nn as nn
from cbam import ChannelAttention, SpatialAttention

class CBAMBlock(nn.Module):
    def __init__(self, in_channels, ratio=16, kernel_size=7):
        super(CBAMBlock, self).__init__()
        self.ca = ChannelAttention(in_channels, ratio)
        self.sa = SpatialAttention(kernel_size)

    def forward(self, x):
        out = x * self.ca(x)
        out = out * self.sa(out)
        return out

class CBAMModel(nn.Module):
    def __init__(self, num_classes=10):
        super(CBAMModel, self).__init__()

        self.conv1 = nn.Conv2d(3, 64, kernel_size=3, stride=2, padding=1, bias=False)
        self.bn1 = nn.BatchNorm2d(64)
        self.cbam1 = CBAMBlock(64)
        self.conv2 = nn.Conv2d(64, 128, kernel_size=3, stride=2, padding=1, bias=False)
        self.bn2 = nn.BatchNorm2d(128)
        self.cbam2 = CBAMBlock(128)
        self.conv3 = nn.Conv2d(128, 256, kernel_size=3, stride=2, padding=1, bias=False)
        self.bn3 = nn.BatchNorm2d(256)
        self.cbam3 = CBAMBlock(256)
        self.avgpool = nn.AdaptiveAvgPool2d((1, 1))
        self.fc = nn.Linear(256, num_classes)

    def forward(self, x):
        out = F.relu(self.bn1(self.conv1(x)))
        out = self.cbam1(out)
        out = F.relu(self.bn2(self.conv2(out)))
        out = self.cbam2(out)
        out = F.relu(self.bn3(self.conv3(out)))
        out = self.cbam3(out)
        out = self.avgpool(out)
        out = out.view(out.size(0), -1)
        out = self.fc(out)
        return out

上述代码中,我们可以看到CBAM的实现方式与传统的卷积神经网络十分相似。我们首先使用三个卷积层和三个批量归一化层来进行特征提取和映射。然后,我们将每个卷积层的输出连接到一个对应的CBAMBlock中进行注意力机制处理。最后,我们使用一个自适应池化层和全连接层对最终特征提取结果进行分类。

三、CBAM代码选取

我们选取几个与CBAM代码相关的示例,以帮助更好地理解CBAM的实现。首先,我们来看一下CBAM模块中通道注意力机制的相关代码:

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.fc1 = nn.Conv2d(in_planes, in_planes // ratio, 1, bias=False)
        self.relu1 = nn.ReLU()
        self.fc2 = nn.Conv2d(in_planes // ratio, in_planes, 1, bias=False)

        self.sigmoid = nn.Sigmoid()

    def forward(self, x):
        avg_out = self.fc2(self.relu1(self.fc1(self.avg_pool(x))))
        max_out = self.fc2(self.relu1(self.fc1(self.max_pool(x))))
        out = avg_out + max_out
        return self.sigmoid(out)

上述代码中,我们在通道注意力机制中使用一个自适应池化层avg_pool和max_pool来对输入x进行平均值和最大值的计算。我们使用1×1的卷积层fc1和fc2对结果进行特征提取和映射,并使用ReLU激活函数对映射后的结果进行非线性处理。最后,我们使用Sigmoid函数将特征图映射到0到1的区间中,从而生成通道注意力图。

接着,我们来看一下CBAM模块中空间注意力机制的相关代码:

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.conv1 = 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.conv1(x)
        return self.sigmoid(x)

上述代码中,我们使用一个卷积层对空间特征进行处理,然后使用Sigmoid激活函数将特征图映射到0到1的范围内。最终,我们将两个注意力机制的输出进行相乘,然后将结果与原始输入进行加和操作。这个加和操作中的权重由两个注意力机制的相乘结果确定。这样就完成了CBAM在深度学习模型中的引入。

最后,我们来看一下使用CBAM模块的PyTorch代码示例:

class CBAMBlock(nn.Module):
    def __init__(self, in_channels, ratio=16, kernel_size=7):
        super(CBAMBlock, self).__init__()
        self.ca = ChannelAttention(in_channels, ratio)
        self.sa = SpatialAttention(kernel_size)

    def forward(self, x):
        out = x * self.ca(x)
        out = out * self.sa(out)
        return out

上述代码中,我们可以看到CBAM的具体使用方式,即将CBAMBlock插入到卷积神经网络的特征提取部分中,用于引入通道注意力和空间注意力机制。在CBAMBlock中,我们使用ChannelAttention和SpatialAttention分别进行通道注意力和空间注意力的计算,并将其相乘后再与原始输入相加,生成输出。

结语

本文详细地阐述了CBAM在深度学习模型中的重要改进,分别对CBAM的代码解析、代码实现和代码选取进行了详细的介绍。相信通过对CBAM深入了解,可以对深度学习模型的构建和优化有更深刻的认识和理解。

原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/235690.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
小蓝小蓝
上一篇 2024-12-12 11:58
下一篇 2024-12-12 11:58

相关推荐

  • TensorFlow Serving Java:实现开发全功能的模型服务

    TensorFlow Serving Java是作为TensorFlow Serving的Java API,可以轻松地将基于TensorFlow模型的服务集成到Java应用程序中。…

    编程 2025-04-29
  • Python训练模型后如何投入应用

    Python已成为机器学习和深度学习领域中热门的编程语言之一,在训练完模型后如何将其投入应用中,是一个重要问题。本文将从多个方面为大家详细阐述。 一、模型持久化 在应用中使用训练好…

    编程 2025-04-29
  • ARIMA模型Python应用用法介绍

    ARIMA(自回归移动平均模型)是一种时序分析常用的模型,广泛应用于股票、经济等领域。本文将从多个方面详细阐述ARIMA模型的Python实现方式。 一、ARIMA模型是什么? A…

    编程 2025-04-29
  • Python实现一元线性回归模型

    本文将从多个方面详细阐述Python实现一元线性回归模型的代码。如果你对线性回归模型有一些了解,对Python语言也有所掌握,那么本文将对你有所帮助。在开始介绍具体代码前,让我们先…

    编程 2025-04-29
  • 深度查询宴会的文化起源

    深度查询宴会,是指通过对一种文化或主题的深度挖掘和探究,为参与者提供一次全方位的、深度体验式的文化品尝和交流活动。本文将从多个方面探讨深度查询宴会的文化起源。 一、宴会文化的起源 …

    编程 2025-04-29
  • VAR模型是用来干嘛

    VAR(向量自回归)模型是一种经济学中的统计模型,用于分析并预测多个变量之间的关系。 一、多变量时间序列分析 VAR模型可以对多个变量的时间序列数据进行分析和建模,通过对变量之间的…

    编程 2025-04-28
  • 如何使用Weka下载模型?

    本文主要介绍如何使用Weka工具下载保存本地机器学习模型。 一、在Weka Explorer中下载模型 在Weka Explorer中选择需要的分类器(Classifier),使用…

    编程 2025-04-28
  • Python下载深度解析

    Python作为一种强大的编程语言,在各种应用场景中都得到了广泛的应用。Python的安装和下载是使用Python的第一步,对这个过程的深入了解和掌握能够为使用Python提供更加…

    编程 2025-04-28
  • Python实现BP神经网络预测模型

    BP神经网络在许多领域都有着广泛的应用,如数据挖掘、预测分析等等。而Python的科学计算库和机器学习库也提供了很多的方法来实现BP神经网络的构建和使用,本篇文章将详细介绍在Pyt…

    编程 2025-04-28
  • Python AUC:模型性能评估的重要指标

    Python AUC是一种用于评估建立机器学习模型性能的重要指标。通过计算ROC曲线下的面积,AUC可以很好地衡量模型对正负样本的区分能力,从而指导模型的调参和选择。 一、AUC的…

    编程 2025-04-28

发表回复

登录后才能评论