【python】注意力机制代码
every blog every motto: You can do more than you think.
https://blog.csdn.net/weixin_39190382?type=blog
0. 前言
梳理目前主流的注意力机制代码,目前以pytorch为例。
说明:
- 特征图维度的组织形式为:(batch,channel,height,width)
- 后续增加
1. 正文
1.1 SEBlock 2017
考虑通道间的注意力之间的关系,在通道上加入注意力机制
论文:https://arxiv.org/abs/1709.01507
代码:https://github.com/hujie-frank/SENet
对于输入特征图C2,其后加上SE注意力模块
1.1.1 步骤
主要分三步:
- squeeze,对空间维度进行压缩,代码上即利用全局平均池化将每个通道平均成一个值,该值具有全局感受野。(通俗理解:一个通道理解为一个大饼,多个通道就是多个大饼垒在一起。全局平均池化即将一个大饼平均成一个点,整体看,类似一个垒起来的色子)
维度变化:(2,512,8,8)-> (2,512,1,1) ==> (2,512) - excitation, 利用权重学习上面各通道间的相关性,代码实现有全连接和卷积核为1的卷积操作两种方式。
维度变化:(2,512)-> (2,512//reducation)->(2,512) ==>(2,512,1,1)
说明: 该过程先降维在升维,降维倍数由reducation参数决定,降低网络的计算量,其中的激活函数增加了网络的非线性。 - 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.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
说明:
- 当使用全连接时,forward中平均池 (squeeze),
# 全局平均池化 (2,512,8,8) -> (2,512,1,1) -> (2,512)
y = self.avg_pool(x).view(b, c)
- 当使用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 概述
将通道注意力机制的的结果作为新的输入特征图,主要步骤:
- 输入特征图,经过最大池化,平均池化(通道维度压缩,与前面的通道注意力机制不同)
维度变化:(2,512,8,8 ) -> (2,1,8,8) - 将最大池化和平均池化在通道方向上合并
维度变化:(2,1,8,8)+ (2,1,8,8) -> (2,2,8,8)
3.经过卷积,通道变为1,再经过激活函数
维度变化:(2,2,8,8)-> (2,1,8,8) - 和输入特征图点乘
维度变化:(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】注意力机制代码相关推荐
- Attention is all you need注意力机制代码解析
在这篇文章中,我以逐行实施的形式介绍了本文的"注释"版本. 我已经重新排序并从原始论文中删除了一些部分,并在全文中添加了评论. 本文档本身是一个有效的笔记本,应完全可用. 总共有4 ...
- 深度学习中一些注意力机制的介绍以及pytorch代码实现
文章目录 前言 注意力机制 软注意力机制 代码实现 硬注意力机制 多头注意力机制 代码实现 参考 前言 因为最近看论文发现同一个模型用了不同的注意力机制计算方法,因此懵了好久,原来注意力机制也是多种多 ...
- 注意力机制(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 ...
- yolov7+SE注意力机制(个人备忘录)
目录 学习视频: yolov7各网络模型的结构图详解: 首先要了解网络结构对应部分 1.添加注意力机制在卷积里面 添加注意力机制代码链接: 添加SE注意力机制为例 步骤: 2.添加注意力机制在Conc ...
- transformer学习之多头注意力机制
文章目录 题目 注意力机制 多头注意力机制 为什么要使用多头注意力机制 代码实现 题目 transformer学习之多头注意力机制 注意力机制 详细了解 ➡️ 注意力机制 之前我们也学习过了Seq2S ...
- 学习注意力机制【1】
目录 注意力机制介绍: 自注意力机制三个步骤: (1)计算注意力分数:(Attention Scores): (2)计算注意力权重(Attention Weights): (3)得到加权和(Weigh ...
- YOLOv5添加注意力机制的具体步骤
本文以CBAM和SE注意力机制的添加过程为例,主要介绍了向YOLOv5中添加注意力机制的具体步骤 本文在此篇博客的基础上向YOLOv5-5.0版本代码中添加注意力机制 yolov5模型训练---使用y ...
- 循环神经网络RNN 2—— attention注意力机制(附代码)
attention方法是一种注意力机制,很明显,是为了模仿人的观察和思维方式,将注意力集中到关键信息上,虽然还没有像人一样,完全忽略到不重要的信息,但是其效果毋庸置疑,本篇我们来总结注意力机制的不同方 ...
- 【深度学习】(8) CNN中的通道注意力机制(SEnet、ECAnet),附Tensorflow完整代码
各位同学好,今天和大家分享一下attention注意力机制在CNN卷积神经网络中的应用,重点介绍三种注意力机制,及其代码复现. 在我之前的神经网络专栏的文章中也使用到过注意力机制,比如在MobileN ...
最新文章
- python特性和属性_Python之属性、特性和修饰符
- 灵动MM32 MCU助力全国大学生智能汽车竞赛
- Android studio 自定义打包apk名
- 工程化专题之Maven(上)
- 【教程】Linux DNS 服务器安装、配置及维护
- 纯Python包发布setup脚本编写示例
- python怎么设置颜色深浅变化_python之深浅拷贝
- ROS系统中的多个版本Boost问题
- Effective Java~23. 类层次优于标签类
- 数据库事务必须具备的特性:ACID【转】
- Windows下Jenkins的详细安装及使用
- opencl JAVA编程_《OpenCL异构并行编程实战》第十二至十四章
- 明星危机公关应该怎么做?
- vue3+typeScript项目运行提示Type string trivially inferred from a string literal, remove type annotatio怎么解决
- git cherry-pick 的时候出现git cherry-pick xxx fatal: bad object xxx
- android : 小米手机 打开开发者 选项 PC 端 安装 apk
- 小程序底部兼容iphoneX
- Java斗_Java集合练习:斗地主游戏
- Xv6学习之kinit1
- aix安装bff_AIX程序打包
热门文章
- 什么是熵(entropy)?
- python黑客库长安十二时辰 更新_爬取3万+评论,告诉你究竟是哪些人不喜欢《长安十二时辰》?...
- Android:从源码剖析Hander机制
- MySQL数据库查看时区
- 【视觉SLAM十四讲】第八讲 光流法与直接法
- JPA @PersistenceContext及@Transactional Annotation
- 爬虫基础_urllib
- Deep C (and C++) by Olve Maudal and Jon Jagger
- jQuery-file-upload插件的使用(小实例)
- ES迁移到OpenSearch