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/zh-tw/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

發表回復

登錄後才能評論