• 深度学习中的注意力机制模型及代码实现(SE Attention、CBAM Attention)


    目录

    常用的注意力机制模型

    SE Attention

    CBAM Attention

    CBAM Attention 模型结构​

    CBAM Attention 代码实现(Pytorch版):

     注意力机制加到网络的哪里合适


    常用的注意力机制模型

    常用的注意力机制多为SE Attention和CBAM Attention。它们基本都可以当成一个简单的网络。例如SE注意力机制,它主要就是由两个全连接层组成,这就是一个简单的MLP模型,只是它的输出变了样。所以,在我们把注意力机制加入主干网络里时,所选注意力机制的复杂程度也是我们要考虑的一个方面,因为增加注意力机制,也变相的增加了我们网络的深度,大小。

    SE Attention

    详见这篇博文

    经典网络模型-SENet注意力机制_L888666Q的博客-CSDN博客_senet网络模型

    CBAM Attention

    CBAM(Convolutional Block Attention Module) 表示卷积模块的注意力机制模块。是一种结合了空间(spatial)和通道(channel)的注意力机制模块。一般情况下,相比于SEnet只关注通道(channel)的注意力机制可以取得更好的效果。其中CBAM的结构如下面两张图,由Channel Attention和 Spatial Attention这两个模块组成,其中Channel Attention模块和SENet是十分相似的,只是在池化上做了最大和平均池化,把FC层换成了卷积。至于Spatial Attention模块,这个更为简单,本质上就是一个卷积层。论文地址

    CBAM Attention 模型结构

    CBAM Attention 代码实现(Pytorch版):

    1. import numpy as np
    2. import torch
    3. from torch import nn
    4. from torch.nn import init
    5. class ChannelAttention(nn.Module):
    6. def __init__(self,channel,reduction=16):
    7. super().__init__()
    8. self.maxpool=nn.AdaptiveMaxPool2d(1)
    9. self.avgpool=nn.AdaptiveAvgPool2d(1)
    10. self.se=nn.Sequential(
    11. nn.Conv2d(channel,channel//reduction,1,bias=False),
    12. nn.ReLU(),
    13. nn.Conv2d(channel//reduction,channel,1,bias=False)
    14. )
    15. self.sigmoid=nn.Sigmoid()
    16. def forward(self, x) :
    17. max_result=self.maxpool(x)
    18. avg_result=self.avgpool(x)
    19. max_out=self.se(max_result)
    20. avg_out=self.se(avg_result)
    21. output=self.sigmoid(max_out+avg_out)
    22. return output
    23. class SpatialAttention(nn.Module):
    24. def __init__(self,kernel_size=7):
    25. super().__init__()
    26. self.conv=nn.Conv2d(2,1,kernel_size=kernel_size,padding=kernel_size//2)
    27. self.sigmoid=nn.Sigmoid()
    28. def forward(self, x) :
    29. max_result,_=torch.max(x,dim=1,keepdim=True)
    30. avg_result=torch.mean(x,dim=1,keepdim=True)
    31. result=torch.cat([max_result,avg_result],1)
    32. output=self.conv(result)
    33. output=self.sigmoid(output)
    34. return output
    35. class CBAMBlock(nn.Module):
    36. def __init__(self, channel=512,reduction=16,kernel_size=49):
    37. super().__init__()
    38. self.ca=ChannelAttention(channel=channel,reduction=reduction)
    39. self.sa=SpatialAttention(kernel_size=kernel_size)
    40. def forward(self, x):
    41. b, c, _, _ = x.size()
    42. residual=x
    43. out=x*self.ca(x)
    44. out=out*self.sa(out)
    45. return out+residual

     注意力机制加到网络的哪里合适

    注意力机制是一个独立的块,一般来说加在哪里都是可以的,但是,注意机制加入我们的网络中时,他是会影响我们网络的特征提取的,即它注意的特征不一定都是我们重要的特征。所以注意力机制加入我们网络的位置就比较重要了。当我我们使用一个注意力机制不知道加在哪里时可以去看看提出注意力机制作者的源代码。如CBAM注意力机制的源代码,加在了残差网络(以resnet18为例)的残差块后面。如果我们使用的网络不是注意力机制作者使用的网络,建议加在最后一个卷积层后面或者第一个全连接层前面。当然并不是每个注意力机制或者每个网络都适用,因为不同的注意力机制注意的地方可能都不一样,所以加到主干网络的地方可能也不一样。
     

  • 相关阅读:
    【rabbitmq的消息堆积问题】
    Maven创建父子工程详解
    六一儿童节与AIGC:科技与童趣的奇妙融
    centos 安装指定版本mysql、redis
    一个故事看懂CPU的SIMD技术
    新型基础测绘与实景三维中国建设技术文件【2】基础地理实体分类、粒度及精度基本要求
    LabVIEW压电驱动迟滞补偿控制
    力扣刷题第二十七天--二叉树
    Java 在PDF中添加水印
    y126.第七章 服务网格与治理-Istio从入门到精通 -- 访问网格外部服务(十二)
  • 原文地址:https://blog.csdn.net/L888666Q/article/details/127665394