pytorch代码实现注意力机制之MLCA

本文介绍了一种新的轻量级混合局部通道注意力(MLCA)模块,它结合了信道、空间和局部、全局信息,提升目标检测网络性能。在PascalVOC和SMID数据集上,MLCA相比其他注意力机制如SE和CA表现出更好的性能和复杂度平衡,提升了模型精度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

MLCA注意力机制

简要:注意力机制是计算机视觉中使用最广泛的组件之一,可以帮助神经网络强调重要元素并抑制不相关的元素。然而,绝大多数信道注意力机制仅包含信道特征信息而忽略了空间特征信息,导致模型表示效果或目标检测性能较差,空间注意力模块往往复杂且成本高昂。为了在性能和复杂度之间取得平衡,该文提出一种轻量级的混合本地信道注意(MLCA)模块来提升目标检测网络的性能,该模块可以同时结合信道信息和空间信息,以及局部信息和全局信息来提高网络的表达效果。在此基础上,提出了用于比较各种注意力模块性能的MobileNet-Attention-YOLO(MAY)算法。在 Pascal VOC 和 SMID 数据集上,MLCA 在模型表示的功效、性能和复杂性之间实现了比其他注意力技术更好的平衡。与PASCAL VOC数据集上的Squeeze-and-Excitation(SE)注意力机制和SIMD数据集上的Coordinate Attention(CA)方法相比,mAP分别提高了1.0%和1.5%。

原文地址:Mixed local channel attention for object detection

结构图

pytorch代码实现MLCA

import math, torch
from torch import nn
import torch.nn.functional as F

class MLCA(nn.Module):
    def __init__(self, in_size, local_size=5, gamma = 2, b = 1,local_weight=0.5):
        super(MLCA, self).__init__()

        # ECA 计算方法
        self.local_size=local_size
        self.gamma = gamma
        self.b = b
        t = int(abs(math.log(in_size, 2) + self.b) / self.gamma)   # eca  gamma=2
        k = t if t % 2 else t + 1

        self.conv = nn.Conv1d(1, 1, kernel_size=k, padding=(k - 1) // 2, bias=False)
        self.conv_local = nn.Conv1d(1, 1, kernel_size=k, padding=(k - 1) // 2, bias=False)

        self.local_weight=local_weight

        self.local_arv_pool = nn.AdaptiveAvgPool2d(local_size)
        self.global_arv_pool=nn.AdaptiveAvgPool2d(1)

    def forward(self, x):
        local_arv=self.local_arv_pool(x)
        global_arv=self.global_arv_pool(local_arv)

        b,c,m,n = x.shape
        b_local, c_local, m_local, n_local = local_arv.shape

        # (b,c,local_size,local_size) -> (b,c,local_size*local_size) -> (b,local_size*local_size,c) -> (b,1,local_size*local_size*c)
        temp_local= local_arv.view(b, c_local, -1).transpose(-1, -2).reshape(b, 1, -1)
        # (b,c,1,1) -> (b,c,1) -> (b,1,c)
        temp_global = global_arv.view(b, c, -1).transpose(-1, -2)

        y_local = self.conv_local(temp_local)
        y_global = self.conv(temp_global)

        # (b,c,local_size,local_size) <- (b,c,local_size*local_size)<-(b,local_size*local_size,c) <- (b,1,local_size*local_size*c)
        y_local_transpose=y_local.reshape(b, self.local_size * self.local_size,c).transpose(-1,-2).view(b, c, self.local_size , self.local_size)
        # (b,1,c) -> (b,c,1) -> (b,c,1,1)
        y_global_transpose = y_global.transpose(-1,-2).unsqueeze(-1)

        # 反池化
        att_local = y_local_transpose.sigmoid()
        att_global = F.adaptive_avg_pool2d(y_global_transpose.sigmoid(),[self.local_size, self.local_size])
        att_all = F.adaptive_avg_pool2d(att_global*(1-self.local_weight)+(att_local*self.local_weight), [m, n])

        x = x * att_all
        return x

if __name__ == '__main__':
    attention = MLCA(in_size=256)
    inputs = torch.randn((2, 256, 16, 16))
    result = attention(inputs)
    print(result.size())
### 混合注意力机制代码实现 混合注意力机制融合了多种类型的注意力方法,旨在提高模型性能的同时保持较低的计算开销。下面提供了一个基于PyTorch框架下简单的混合注意力机制实现案例。 #### 定义基本组件 为了构建混合注意力模块,先定义一些基础函数和类: ```python import torch import torch.nn as nn import math class ScaledDotProductAttention(nn.Module): """缩放点积注意力""" def __init__(self, temperature, attn_dropout=0.1): super(ScaledDotProductAttention, self).__init__() self.temperature = temperature self.dropout = nn.Dropout(attn_dropout) def forward(self, q, k, v, mask=None): attn = torch.matmul(q / self.temperature, k.transpose(2, 3)) if mask is not None: attn = attn.masked_fill(mask == 0, -1e9) attn = self.dropout(torch.softmax(attn, dim=-1)) output = torch.matmul(attn, v) return output, attn def get_subsequent_mask(seq): '''获取后续掩码''' sz_b, len_s = seq.size() subsequent_mask = (1 - torch.triu( torch.ones((1, 1, len_s, len_s), device=seq.device), diagonal=1)).bool() return subsequent_mask ``` #### 构建混合注意力层 接下来创建一个包含局部通道注意与全局多头关注相结合的新类`HybridAttentionLayer`: ```python class HybridAttentionLayer(nn.Module): def __init__(self, d_model, n_head, d_k, d_v, dropout=0.1): super(HybridAttentionLayer, self).__init__() self.n_head = n_head self.d_k = d_k self.d_v = d_v self.w_qs = nn.Linear(d_model, n_head * d_k, bias=False) self.w_ks = nn.Linear(d_model, n_head * d_k, bias=False) self.w_vs = nn.Linear(d_model, n_head * d_v, bias=False) self.fc = nn.Linear(n_head * d_v, d_model, bias=False) self.attention = ScaledDotProductAttention( temperature=d_k ** 0.5, attn_dropout=dropout ) self.layer_norm = nn.LayerNorm(d_model, eps=1e-6) self.dropout = nn.Dropout(dropout) def forward(self, q, k, v, mask=None): d_k, d_v, n_head = self.d_k, self.d_v, self.n_head sz_b, len_q, _ = q.size() sz_b, len_k, _ = k.size() sz_b, len_v, _ = v.size() residual = q # Pass through the pre-attention projection: b x lq x (n*dv) # Separate different heads: b x lq x n x dv q = self.w_qs(q).view(sz_b, len_q, n_head, d_k) k = self.w_ks(k).view(sz_b, len_k, n_head, d_k) v = self.w_vs(v).view(sz_b, len_v, n_head, d_v) # Transpose for attention dot product: b x n x lq x dv q, k, v = q.transpose(1, 2), k.transpose(1, 2), v.transpose(1, 2) if mask is not None: mask = mask.unsqueeze(1) # For head axis broadcasting. q, attn = self.attention(q, k, v, mask=mask) # Transpose to move the head dimension back: b x lq x n x dv # Combine the last two dimensions to concatenate all the heads together: b x lq x (n*dv) q = q.transpose(1, 2).contiguous().view(sz_b, len_q, -1) q = self.dropout(self.fc(q)) q += residual q = self.layer_norm(q) return q, attn ``` 此部分实现了标准的多头自注意力结构,并允许在此基础上加入其他形式的关注逻辑,比如局部区域内的特殊处理或者特定任务导向的设计调整[^1]。 对于更具体的MLCA(Mixed Local Channel Attention),由于其涉及到特殊的局部化操作以及针对不同应用场景下的优化策略,在上述通用模板的基础上还需要进一步定制开发相应的子模块来满足具体需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

「已注销」

你的激励是我肝下去的动力~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值