every blog every motto: You can do more than you think.
https://blog.csdn.net/weixin_39190382?type=blog

0. 前言

梳理目前主流的注意力机制代码,目前以pytorch为例。
说明:

  1. 特征图维度的组织形式为:(batch,channel,height,width)
  2. 后续增加

1. 正文

1.1 SEBlock 2017

考虑通道间的注意力之间的关系,在通道上加入注意力机制
论文:https://arxiv.org/abs/1709.01507
代码:https://github.com/hujie-frank/SENet

对于输入特征图C2,其后加上SE注意力模块

1.1.1 步骤

主要分三步:

  1. squeeze,对空间维度进行压缩,代码上即利用全局平均池化将每个通道平均成一个值,该值具有全局感受野。(通俗理解:一个通道理解为一个大饼,多个通道就是多个大饼垒在一起。全局平均池化即将一个大饼平均成一个点,整体看,类似一个垒起来的色子)
    维度变化:(2,512,8,8)-> (2,512,1,1) ==> (2,512)
  2. excitation, 利用权重学习上面各通道间的相关性,代码实现有全连接和卷积核为1的卷积操作两种方式。
    维度变化:(2,512)-> (2,512//reducation)->(2,512) ==>(2,512,1,1)
    说明: 该过程先降维在升维,降维倍数由reducation参数决定,降低网络的计算量,其中的激活函数增加了网络的非线性。
  3. scale: 通过上面excitation的操作输出了每个通道的重要性,在通过乘法加权操作乘以输入数据C2,从而提升重要特征,抑制不重要特征。
    维度变化:(2,512,8,8)*(2,512,1,1) -> (2,512,8,8)

小结: 即输入维度为(2,512,8,8),输出维度为:(2,512,8,8)
说明: 上述步骤中的“->”表示维度变化方向,“==>”表示通过view方法改变了维度。


1.1.2 更加清晰的理解图

说明:

  1. 全连接和1 × 1的卷积效果类似,上图显示为全连接,亦可为1*1的卷积,下同,不赘述。
  2. 激活函数位置见代码,下同。

1.1.3 代码

1. pytorch

class SELayer(nn.Module):def __init__(self, channel, reduction=4):""" SE注意力机制,输入x。输入输出特征图不变1.squeeze: 全局池化 (batch,channel,height,width) -> (batch,channel,1,1) ==> (batch,channel)2.excitaton: 全连接or卷积核为1的卷积(batch,channel)->(batch,channel//reduction)-> (batch,channel) ==> (batch,channel,1,1) 输出y3.scale: 完成对通道维度上原始特征的标定 y = x*y 输出维度和输入维度相同:param channel: 输入特征图的通道数:param reduction: 特征图通道的降低倍数"""super(SELayer, self).__init__()# 自适应全局平均池化,即,每个通道进行平均池化,使输出特征图长宽为1self.avg_pool = nn.AdaptiveAvgPool2d(1)# 全连接的excitationself.fc = nn.Sequential(nn.Linear(channel, channel // reduction),nn.ReLU(inplace=True),nn.Linear(channel // reduction, channel),nn.Sigmoid())# 卷积网络的excitation# 特征图变化:# (2,512,1,1) -> (2,512,1,1) -> (2,512,1,1)self.fc2 = nn.Sequential(nn.Conv2d(channel, channel // reduction, 1, bias=False),nn.ReLU(inplace=True),nn.Conv2d(channel // reduction, channel, 1, bias=False),nn.Sigmoid())def forward(self, x):# (batch,channel,height,width) (2,512,8,8)b, c, _, _ = x.size()# 全局平均池化 (2,512,8,8) -> (2,512,1,1) -> (2,512)y = self.avg_pool(x).view(b, c)# (2,512) -> (2,512//reducation) -> (2,512) -> (2,512,1,1)y = self.fc(y).view(b, c, 1, 1)# (2,512,8,8)* (2,512,1,1) -> (2,512,8,8)pro = x * yreturn x * y

2. tensorflow/keras

# SEBlock
feature_map_shape = input_x.shape  # input feature map shape
x = tf.reduce_mean(x, [1, 2])  # reduce along axis 1 and 2 ,height,width,
x = Dense(feature_map_shape[-1] / 16, activation=tf.nn.relu)(x)  # (batch,channel) -> (batch,channel/16)
x = Dense(feature_map_shape[-1], activation=tf.nn.relu)(x)  # (batch,channel/16) -> (batch,channel)
x = tf.multiply(input_x, x)  # multiply along channel

说明:

  1. 当使用全连接时,forward中平均池 (squeeze),
# 全局平均池化 (2,512,8,8) -> (2,512,1,1) -> (2,512)
y = self.avg_pool(x).view(b, c)
  1. 当使用1*1卷积,forward中平均池化(squeeze),
# 全局平均池化 (2,512,8,8) -> (2,512,1,1)
y = self.avg_pool(x)

1.2 CBAM 2018

论文:https://arxiv.org/abs/1807.06521
代码:https://github.com/luuuyi/CBAM.PyTorch
CBAM可以无缝集成任何CNN架构中,开销不大,早期的注意力机制一种。

实验结果表明:顺序链接比并行连接好,其中通道注意力在前优于空间注意力在前。

1.2.1 通道注意力机制

1.2.1.1 概述

通道注意力机制和上面的SEBlock类似,唯一不同的是加了一个最大池化。而后,最大池化和平均池化共用一个多层感知机(mlp), 再将结果相加和输入特征图进行点乘传入空间注意力机制。
说明: 主要步骤省略,可参考SEBlock和下面代码中的注释。

1.2.1.2 更加清晰的理解图

1.2.1.3 代码

说明: forward中,为了方便理解,展开书写了,等价于最开始注释了的几行。

class ChannelAttention(nn.Module):def __init__(self, in_channel, ratio=16):""" 通道注意力机制 同最大池化和平均池化两路分别提取信息,后共用一个多层感知机mlp,再将二者结合:param in_channel: 输入通道:param ratio: 通道降低倍率"""super(ChannelAttention, self).__init__()# 平均池化self.avg_pool = nn.AdaptiveAvgPool2d(1)# 最大池化self.max_pool = nn.AdaptiveMaxPool2d(1)# 通道先降维后恢复到原来的维数self.fc1 = nn.Conv2d(in_channel, in_channel // ratio, 1, bias=False)self.relu1 = nn.ReLU()self.fc2 = nn.Conv2d(in_channel // ratio, in_channel, 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 x*self.sigmoid(out)# 平均池化一支 (2,512,8,8) -> (2,512,1,1) -> (2,512/ration,1,1) -> (2,512,1,1)# (2,512,8,8) -> (2,512,1,1)avg = self.avg_pool(x)# 多层感知机mlp (2,512,8,8) -> (2,512,1,1) -> (2,512/ration,1,1) -> (2,512,1,1)# (2,512,1,1) -> (2,512/ratio,1,1)avg = self.fc1(avg)avg = self.relu1(avg)# (2,512/ratio,1,1) -> (2,512,1,1)avg_out = self.fc2(avg)# 最大池化一支# (2,512,8,8) -> (2,512,1,1)max = self.max_pool(x)# 多层感知机# (2,512,1,1) -> (2,512/ratio,1,1)max = self.fc1(max)max = self.relu1(max)# (2,512/ratio,1,1) -> (2,512,1,1)max_out = self.fc2(max)# (2,512,1,1) + (2,512,1,1) -> (2,512,1,1)out = avg_out + max_outreturn x*self.sigmoid(out)

1.2.2 空间注意力机制

1.2.2.1 概述

将通道注意力机制的的结果作为新的输入特征图,主要步骤:

  1. 输入特征图,经过最大池化,平均池化(通道维度压缩,与前面的通道注意力机制不同)
    维度变化:(2,512,8,8 ) -> (2,1,8,8)
  2. 将最大池化和平均池化在通道方向上合并
    维度变化:(2,1,8,8)+ (2,1,8,8) -> (2,2,8,8)
    3.经过卷积,通道变为1,再经过激活函数
    维度变化:(2,2,8,8)-> (2,1,8,8)
  3. 和输入特征图点乘
    维度变化:(2,512,8,8) * (2,1,8,8) -> (2,512,8,8)

1.2.2.2 更加清晰的理解图

说明: 下面两种图例其实是一个意思,即,单通道特征图,为了看起来更加清晰用了两种颜色。

1.2.2.3 代码

class SpatialAttention(nn.Module):def __init__(self, kernel_size=7):""" 空间注意力机制 将通道维度通过最大池化和平均池化进行压缩,然后合并,再经过卷积和激活函数,结果和输入特征图点乘:param kernel_size: 卷积核大小"""super(SpatialAttention, self).__init__()assert kernel_size in (3, 7), 'kernel size must be 3 or 7'padding = 3 if kernel_size == 7 else 1self.conv1 = nn.Conv2d(2, 1, kernel_size, padding=padding, bias=False)self.sigmoid = nn.Sigmoid()def forward(self, x):print('x shape', x.shape)# (2,512,8,8) -> (2,1,8,8)avg_out = torch.mean(x, dim=1, keepdim=True)# (2,512,8,8) -> (2,1,8,8)max_out, _ = torch.max(x, dim=1, keepdim=True)# (2,1,8,8) + (2,1,8,8) -> (2,2,8,8)cat = torch.cat([avg_out, max_out], dim=1)# (2,2,8,8) -> (2,1,8,8)out = self.conv1(cat)return x * self.sigmoid(out)

【python】注意力机制代码相关推荐

  1. Attention is all you need注意力机制代码解析

    在这篇文章中,我以逐行实施的形式介绍了本文的"注释"版本. 我已经重新排序并从原始论文中删除了一些部分,并在全文中添加了评论. 本文档本身是一个有效的笔记本,应完全可用. 总共有4 ...

  2. 深度学习中一些注意力机制的介绍以及pytorch代码实现

    文章目录 前言 注意力机制 软注意力机制 代码实现 硬注意力机制 多头注意力机制 代码实现 参考 前言 因为最近看论文发现同一个模型用了不同的注意力机制计算方法,因此懵了好久,原来注意力机制也是多种多 ...

  3. 注意力机制(SE, ECA, CBAM, SKNet, scSE, Non-Local, GCNet, ASFF) Pytorch代码

    注意力机制 1 SENet 2 ECANet 3 CBAM 3.1 通道注意力 3.2 空间注意力 3.3 CBAM 4 展示网络层具体信息 5 SKNet 6 scSE 7 Non-Local Ne ...

  4. yolov7+SE注意力机制(个人备忘录)

    目录 学习视频: yolov7各网络模型的结构图详解: 首先要了解网络结构对应部分 1.添加注意力机制在卷积里面 添加注意力机制代码链接: 添加SE注意力机制为例 步骤: 2.添加注意力机制在Conc ...

  5. transformer学习之多头注意力机制

    文章目录 题目 注意力机制 多头注意力机制 为什么要使用多头注意力机制 代码实现 题目 transformer学习之多头注意力机制 注意力机制 详细了解 ➡️ 注意力机制 之前我们也学习过了Seq2S ...

  6. 学习注意力机制【1】

    目录 注意力机制介绍: 自注意力机制三个步骤: (1)计算注意力分数:(Attention Scores): (2)计算注意力权重(Attention Weights): (3)得到加权和(Weigh ...

  7. YOLOv5添加注意力机制的具体步骤

    本文以CBAM和SE注意力机制的添加过程为例,主要介绍了向YOLOv5中添加注意力机制的具体步骤 本文在此篇博客的基础上向YOLOv5-5.0版本代码中添加注意力机制 yolov5模型训练---使用y ...

  8. 循环神经网络RNN 2—— attention注意力机制(附代码)

    attention方法是一种注意力机制,很明显,是为了模仿人的观察和思维方式,将注意力集中到关键信息上,虽然还没有像人一样,完全忽略到不重要的信息,但是其效果毋庸置疑,本篇我们来总结注意力机制的不同方 ...

  9. 【深度学习】(8) CNN中的通道注意力机制(SEnet、ECAnet),附Tensorflow完整代码

    各位同学好,今天和大家分享一下attention注意力机制在CNN卷积神经网络中的应用,重点介绍三种注意力机制,及其代码复现. 在我之前的神经网络专栏的文章中也使用到过注意力机制,比如在MobileN ...

最新文章

  1. python特性和属性_Python之属性、特性和修饰符
  2. 灵动MM32 MCU助力全国大学生智能汽车竞赛
  3. Android studio 自定义打包apk名
  4. 工程化专题之Maven(上)
  5. 【教程】Linux DNS 服务器安装、配置及维护
  6. 纯Python包发布setup脚本编写示例
  7. python怎么设置颜色深浅变化_python之深浅拷贝
  8. ROS系统中的多个版本Boost问题
  9. Effective Java~23. 类层次优于标签类
  10. 数据库事务必须具备的特性:ACID【转】
  11. Windows下Jenkins的详细安装及使用
  12. opencl JAVA编程_《OpenCL异构并行编程实战》第十二至十四章
  13. 明星危机公关应该怎么做?
  14. vue3+typeScript项目运行提示Type string trivially inferred from a string literal, remove type annotatio怎么解决
  15. git cherry-pick 的时候出现git cherry-pick xxx  fatal: bad object xxx
  16. android : 小米手机 打开开发者 选项 PC 端 安装 apk
  17. 小程序底部兼容iphoneX
  18. Java斗_Java集合练习:斗地主游戏
  19. Xv6学习之kinit1
  20. aix安装bff_AIX程序打包

热门文章

  1. 什么是熵(entropy)?
  2. python黑客库长安十二时辰 更新_爬取3万+评论,告诉你究竟是哪些人不喜欢《长安十二时辰》?...
  3. Android:从源码剖析Hander机制
  4. MySQL数据库查看时区
  5. 【视觉SLAM十四讲】第八讲 光流法与直接法
  6. JPA @PersistenceContext及@Transactional Annotation
  7. 爬虫基础_urllib
  8. Deep C (and C++) by Olve Maudal and Jon Jagger
  9. jQuery-file-upload插件的使用(小实例)
  10. ES迁移到OpenSearch