• 空间注意力
千次阅读
2021-08-26 10:39:25

# 一、空间注意力机制简介

空间注意力的示意图如下：

长条的是通道注意力机制，而平面则是空间注意力机制，可以发现：

• 通道注意力在意的是每个特怔面的权重
• 空间注意力在意的是面上每一个局部的权重。

注意：空间注意力是右边的部分：Spatial Attention Module

# 二、空间注意力与pytorch代码

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.sigmoid = nn.Sigmoid()

def forward(self, x):  # x.size() 30,40,50,30
avg_out = torch.mean(x, dim=1, keepdim=True)
max_out, _ = torch.max(x, dim=1, keepdim=True)  # 30,1,50,30
x = torch.cat([avg_out, max_out], dim=1)
x = self.conv1(x)  # 30,1,50,30
return self.sigmoid(x)  # 30,1,50,30


简单的使用方法如下：

import torch
import torch.nn as nn
import torch.utils.data as Data

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.sigmoid = nn.Sigmoid()

def forward(self, x):  # x.size() 30,40,50,30
avg_out = torch.mean(x, dim=1, keepdim=True)
max_out, _ = torch.max(x, dim=1, keepdim=True)  # 30,1,50,30
x = torch.cat([avg_out, max_out], dim=1)
x = self.conv1(x)  # 30,1,50,30
return self.sigmoid(x)  # 30,1,50,30

def get_total_train_data(H, W, C, class_count):
"""得到全部的训练数据，这里需要替换成自己的数据"""
import numpy as np
x_train = torch.Tensor(
np.random.random((1000, H, W, C)))  # 维度是 [ 数据量, 高H, 宽W, 长C]
y_train = torch.Tensor(
np.random.randint(0, class_count, size=(1000, 1))).long()  # [ 数据量, 句子的分类], 这里的class_count=4，就是四分类任务
return x_train, y_train

if __name__ == '__main__':
# ================训练参数=================
epochs = 100
batch_size = 30
output_class = 14
H = 40
W = 50
C = 30
# ================准备数据=================
x_train, y_train = get_total_train_data(H, W, C, class_count=output_class)
dataset=Data.TensorDataset(x_train, y_train),  # 封装进Data.TensorDataset()类的数据，可以为任意维度
batch_size=batch_size,  # 每块的大小
shuffle=True,  # 要不要打乱数据 (打乱比较好)
num_workers=6,  # 多进程（multiprocess）来读数据
drop_last=True,
)
# ================初始化模型=================
model = SpatialAttention()
# ================开始训练=================
for i in range(epochs):
attention_out = model(seq)
seq_attention_out = attention_out.squeeze()
for i in range(seq_attention_out.size()[0]):
print(seq_attention_out[i])


# 三、使用案例

import torch
import torch.nn as nn
import torch.utils.data as Data

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.sigmoid = nn.Sigmoid()

def forward(self, x):  # x.size() 30,40,50,30
avg_out = torch.mean(x, dim=1, keepdim=True)
max_out, _ = torch.max(x, dim=1, keepdim=True)  # 30,1,50,30
x = torch.cat([avg_out, max_out], dim=1)
x = self.conv1(x)  # 30,1,50,30
return self.sigmoid(x)  # 30,1,50,30

class UseAttentionModel(nn.Module):
def __init__(self):
super(UseAttentionModel, self).__init__()
self.channel_attention = SpatialAttention()

def forward(self, x):  # 反向传播
attention_value = self.channel_attention(x)
out = x.mul(attention_value)
return out

def get_total_train_data(H, W, C, class_count):
"""得到全部的训练数据，这里需要替换成自己的数据"""
import numpy as np
x_train = torch.Tensor(
np.random.random((1000, H, W, C)))  # 维度是 [ 数据量, 高H, 宽W, 长C]
y_train = torch.Tensor(
np.random.randint(0, class_count, size=(1000, 1))).long()  # [ 数据量, 句子的分类], 这里的class_count=4，就是四分类任务
return x_train, y_train

if __name__ == '__main__':
# ================训练参数=================
epochs = 100
batch_size = 30
output_class = 14
H = 40
W = 50
C = 30
# ================准备数据=================
x_train, y_train = get_total_train_data(H, W, C, class_count=output_class)
dataset=Data.TensorDataset(x_train, y_train),  # 封装进Data.TensorDataset()类的数据，可以为任意维度
batch_size=batch_size,  # 每块的大小
shuffle=True,  # 要不要打乱数据 (打乱比较好)
num_workers=6,  # 多进程（multiprocess）来读数据
drop_last=True,
)
# ================初始化模型=================
model = UseAttentionModel()
cross_loss = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)  # 优化器
model.train()
# ================开始训练=================
for i in range(epochs):
attention_out = model(seq)
print(attention_out.size())
print(attention_out)

更多相关内容
• CBAM 是一个轻量级的通用模块，其中包含了空间注意力和通道注意力。 通道注意力是先对空间进行全局平均或最大池化后，在通道层面求得注意力。 空间注意力是先对通道进行全局平均或最大池化后，在空间层面求得注意...
1. 各模块简介：

CBAM 是一个轻量级的通用模块，其中包含了空间注意力和通道注意力。

通道注意力是先对空间进行全局平均或最大池化后，在通道层面求得注意力。

空间注意力是先对通道进行全局平均或最大池化后，在空间层面求得注意力。

2.CBAM：

3.代码

空间注意力pytorch代码：

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.sigmoid = nn.Sigmoid()

def forward(self, x):  # x.size() 30,40,50,30
avg_out = torch.mean(x, dim=1, keepdim=True)
max_out, _ = torch.max(x, dim=1, keepdim=True)  # 30,1,50,30
x = torch.cat([avg_out, max_out], dim=1)
x = self.conv1(x)  # 30,1,50,30
return self.sigmoid(x)  # 30,1,50,30


参考：

展开全文
• 在分析现有注意力网络的基础上，提出使用自注意力模块（self-attention，SA）和空间推理注意力模块（spatial reasoning attention，SRA）对文本信息和图像目标进行映射，最终得到融合特征输出。相较于其他注意力机制...
• 通道注意力+空间注意力，可嵌入在大部分的主流网络中，在不显著增加计算量和参数量的前提下能提升模型的特征提取能力。

# 1、动机

卷积操作是通过混合通道和空间两个维度的信息来间特征提取的。在注意力方面，SE仅关注了通道注意力，没考虑空间方面的注意力。因此，本文提出了 CBAM——一种同时关注通道和空间注意力的卷积模块，可以用于CNNs架构中，以提升feature map的特征表达能力。

# 2、方法

CBAM的整体架构如上面图1所示，其包括两块内容：Channel Attention Module、Spatial Attention Module，也即通道注意力CAM、空间注意力SAM。假设CABM的输入feature map为$\mathbf{F} \in \mathbb{R}^{C \times H \times W}$，CBAM先用CAM得到1D通道注意力map $\mathbf{M}_{\mathbf{c}} \in \mathbb{R}^{C \times 1 \times 1}$，再用SAM得到2D空间注意力map $\mathbf{M}_{\mathbf{s}} \in \mathbb{R}^{1 \times H \times W}$，该过程公式表示如下：

\begin{aligned} \mathbf{F}^{\prime} &=\mathbf{M}_{\mathbf{c}}(\mathbf{F}) \otimes \mathbf{F} \\ \mathbf{F}^{\prime \prime} &=\mathbf{M}_{\mathbf{s}}\left(\mathbf{F}^{\prime}\right) \otimes \mathbf{F}^{\prime} \end{aligned}   （1）

CAM和SAM的架构如图2所示：

CAM：对于输入的feature map F，首先在每个空间位置上应用MaxPooling、AvgPooling，得到两个C*1*1的向量，然后分别送入一个共享的包含两层FC的MLP，最后最像素相加融合，经过一个激活函数，得到通道注意力map，其公式表达为：

\begin{aligned} \mathbf{M}_{\mathbf{c}}(\mathbf{F}) &=\sigma(M L P(\text { AvgPool }(\mathbf{F}))+M L P(\operatorname{MaxPool}(\mathbf{F}))) \\ &=\sigma\left(\mathbf{W}_{\mathbf{1}}\left(\mathbf{W}_{\mathbf{0}}\left(\mathbf{F}_{\mathbf{a v g}}^{\mathbf{c}}\right)\right)+\mathbf{W}_{\mathbf{1}}\left(\mathbf{W}_{\mathbf{0}}\left(\mathbf{F}_{\mathbf{m a x}}^{\mathbf{c}}\right)\right)\right), \end{aligned}   （2）

SAM：CAM输出的feature map，将送入SAM。首先在每个通道上应用MaxPooling、AvgPooling，得到两个1*H*W的feature map，然后按通道concat起来，送入一个标准卷积层，经过激活函数之后就得到了空间注意力map，其公式表达为：

\begin{aligned} \mathbf{M}_{\mathbf{s}}(\mathbf{F}) &=\sigma\left(f^{7 \times 7}([\operatorname{AvgPool}(\mathbf{F}) ; \operatorname{MaxPool}(\mathbf{F})])\right) \\ &=\sigma\left(f^{7 \times 7}\left(\left[\mathbf{F}_{\mathbf{a v g}}^{\mathbf{s}} ; \mathbf{F}_{\mathbf{m a x}}^{\mathbf{s}}\right]\right)\right) \end{aligned}   （3）

CAM和SAM，一个关注“what”，一个关注“where”，两者可以并行或者串行使用。

# 3、Pytorch实现

CBAM包含了个子模块：CAM和SAM，使用时，分别实例化它们，然后顺序应用在某个feature map之后即可。下面给出其Pytorch代码：

import torch
from torch import nn

class ChannelAttention(nn.Module):
def __init__(self, in_planes, ratio=16):
super(ChannelAttention, self).__init__()

self.fc1   = nn.Conv2d(in_planes, in_planes // 16, 1, bias=False)
self.relu1 = nn.ReLU()
self.fc2   = nn.Conv2d(in_planes // 16, 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.sigmoid = nn.Sigmoid()
self.register_buffer()

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)

展开全文
• 空间注意力模型(spatial attention) 不是图像中所有的区域对任务的贡献都是同样重要的，只有任务相关的区域才是需要关心的，比如分类任务的主体，空间注意力模型就是寻找网络中最重要的部位进行处理。 我们在这里给...

Attention机制在近几年来在图像，自然语言处理等领域中都取得了重要的突破，被证明有益于提高模型的性能。

Attention机制本身也是符合人脑和人眼的感知机制，这次我们主要以计算机视觉领域为例，讲述Attention机制的原理，应用以及模型的发展

#### 何为Attention机制？

所谓Attention机制，便是聚焦于局部信息的机制，比如，图像中的某一个图像区域。随着任务的变化，注意力区域往往会发生变化。

面对上面这样的一张图，如果你只是从整体来看，只看到了很多人头，但是你拉近一个一个仔细看就了不得了，都是天才科学家。

图中除了人脸之外的信息其实都是无用的，也做不了什么任务，Attention机制便是要找到这些最有用的信息，可以想到，最简单的场景就是从照片中检测人脸了。

#### 基于Attention的显著目标检测

和注意力机制相伴而生的一个任务便是显著目标检测，即salient object detection。它的输入是一张图，输出是一张概率图，概率越大的地方，代表是图像中重要目标的概率越大，即人眼关注的重点，一个典型的显著图如下：

右图就是左图的显著图，在头部位置概率最大，另外腿部，尾巴也有较大概率，这就是图中真正有用的信息。

显著目标检测需要一个数据集，而这样的数据集的收集便是通过追踪多个实验者的眼球在一定时间内的注意力方向进行平均得到，典型的步骤如下：
(1) 让被测试者观察图。

(2) 用eye tracker记录眼睛的注意力位置。

(3) 对所有测试者的注意力位置使用高斯滤波进行综合。

(4) 结果以0～1的概率进行记录。

于是就能得到下面这样的图，第二行是眼球追踪结果，第三行就是显著目标概率图。

上面讲述的都是空间上的注意力机制，即关注的是不同空间位置，而在CNN结构中，还有不同的特征通道，因此不同特征通道也有类似的原理 ，下面一起讲述。

#### Attention模型架构

注意力机制的本质就是定位到感兴趣的信息，抑制无用信息，结果通常都是以概率图或者概率特征向量的形式展示，从原理上来说，主要分为空间注意力模型，通道注意力模型，空间和通道混合注意力模型三种，这里不区分soft和hard attention。

###### 1.空间注意力模型(spatial attention)

不是图像中所有的区域对任务的贡献都是同样重要的，只有任务相关的区域才是需要关心的，比如分类任务的主体，空间注意力模型就是寻找网络中最重要的部位进行处理。

这里的Localization Net用于生成仿射变换系数，输入是C×H×W维的图像，输出是一个空间变换系数，它的大小根据要学习的变换类型而定，如果是仿射变换，则是一个6维向量。

这样的一个网络要完成的效果如下图：

即定位到目标的位置，然后进行旋转等操作，使得输入样本更加容易学习。这是一种一步调整的解决方案，当然还有很多迭代调整的方案，感兴趣可以去有三知识星球星球中阅读。

相比于Spatial Transformer Networks 一步完成目标的定位和仿射变换调整，Dynamic Capacity Networks[2]则采用了两个子网络，分别是低性能的子网络(coarse model)和高性能的子网络(fine model)。

• 低性能的子网络(coarse model)用于对全图进行处理，定位感兴趣区域，如下图中的操作fc。
• 高性能的子网络(fine model)则对感兴趣区域进行精细化处理，如下图的操作ff。
• 两者共同使用，可以获得更低的计算代价和更高的精度。

由于在大部分情况下我们感兴趣的区域只是图像中的一小部分，因此空间注意力的本质就是定位目标并进行一些变换或者获取权重。
###### 2 通道注意力机制

对于输入2维图像的CNN来说，一个维度是图像的尺度空间，即长宽，另一个维度就是通道，因此基于通道的Attention也是很常用的机制。

SENet(Sequeeze and Excitation Net)[3]是2017届ImageNet分类比赛的冠军网络，本质上是一个基于通道的Attention模型，它通过建模各个特征通道的重要程度，然后针对不同的任务增强或者抑制不同的通道，原理图如下。

在正常的卷积操作后分出了一个旁路分支，首先进行Squeeze操作(即图中Fsq(·))，它将空间维度进行特征压缩，即每个二维的特征图变成一个实数，相当于具有全局感受野的池化操作，特征通道数不变。

然后是Excitation操作(即图中的Fex(·))，它通过参数w为每个特征通道生成权重，w被学习用来显式地建模特征通道间的相关性。在文章中，使用了一个2层bottleneck结构(先降维再升维)的全连接层+Sigmoid函数来实现。

得到了每一个特征通道的权重之后，就将该权重应用于原来的每个特征通道，基于特定的任务，就可以学习到不同通道的重要性。

将其机制应用于若干基准模型，在增加少量计算量的情况下，获得了更明显的性能提升。作为一种通用的设计思想，它可以被用于任何现有网络，具有较强的实践意义。而后SKNet[4]等方法将这样的通道加权的思想和Inception中的多分支网络结构进行结合，也实现了性能的提升。

通道注意力机制的本质，在于建模了各个特征之间的重要性，对于不同的任务可以根据输入进行特征分配，简单而有效。

###### 3 空间和通道注意力机制的融合

前述的Dynamic Capacity Network是从空间维度进行Attention，SENet是从通道维度进行Attention，自然也可以同时使用空间Attention和通道Attention机制

CBAM(Convolutional Block Attention Module)[5]是其中的代表性网络，结构如下：

通道方向的Attention建模的是特征的重要性，结构如下：

同时使用最大pooling和均值pooling算法，然后经过几个MLP层获得变换结果，最后分别应用于两个通道，使用sigmoid函数得到通道的attention结果。

空间方向的Attention建模的是空间位置的重要性，结构如下：

首先将通道本身进行降维，分别获取最大池化和均值池化结果，然后拼接成一个特征图，再使用一个卷积层进行学习。

这两种机制，分别学习了通道的重要性和空间的重要性，还可以很容易地嵌入到任何已知的框架中。

除此之外，还有很多的注意力机制相关的研究，比如残差注意力机制，多尺度注意力机制，递归注意力机制等。

展开全文
• 包含两个模块：通道注意力模块和空间注意力模块，两个注意力模块采用串联的方式。 1.通道注意力模块 通道注意力是关注哪个通道上的特征是有意义的，输入feature map是H x W x C，先分别进行一个全局平均池化和全局...
• 初学通道注意力模块和空间注意力模块简单理解，不涉及详细原理
• Spatial Attention空间注意力及Resnet_cbam实现 前言 一、Attention表达改进 二、SpatialAttention空间注意力 三、Resnet_CBAM 总结 前言 上一次介绍Renest时，介绍了CNN里的通道注意力Channel-Wise的...
• 空间注意力模块 空间注意力模块 空间注意力聚焦在“哪里”是最具信息量的部分，这是对通道注意力的补充。为了计算空间注意力，沿着通道轴应用平均池化和最大池操作，然后将它们连接起来生成一个有效的特征描述符。...
• 注意力机制可以分为： 通道注意力机制：对通道生成掩码mask，进行打分，代表是senet, Channel Attention Module 空间注意力机制：对空间进行掩码的生成，进行打分，代表是Spatial Attention Module 混合域注意力机制...
• 因此，本文提出了 CBAM——一种同时关注通道和空间注意力的卷积模块，可以用于CNNs架构中，以提升feature map的特征表达能力。 网络结构： 网络主结构 CAM和SAM的结构 CAM：通道注意力机制就是学习一个不同通道的...
• 注意力模块通道（时间）注意力模块空间注意力模块 通道（时间）注意力模块 为了汇总空间特征，作者采用了全局平均池化和最大池化两种方式来分别利用不同的信息。 输入是一个 H×W×C 的特征 F， 我们先分别进行一...
• Attention机制理解笔记声明Attention分类(主要SA和CA)spitial attentionchannel attentionSA + CA(spitial attention+channel attention)加强SA+CA理解空间注意力机制和通道注意力机制解释attention机制Attention...
• soft attention（包括空间注意力、通道注意力）它们是pixel级 hard attention( local 注意力)它们是region级 下面讲解空间注意力、通道注意力、local 注意力的生成 本人知识水平有限，要是错误的话，欢迎指正，感谢...
• 参考链接: 深度学习卷积神经网络重要结构之通道注意力和空间注意力模块 参考链接: 用于卷积神经网络的注意力机制(Attention)----CBAM: Convolutional Block Attention Module 参考链接: link 参考链接: link 参考...
• 目录基本概念配置实现源码分析训练效果小结 在上一篇《【YOLOv4探讨 之七】利用... 基本概念 空间注意力机制使用SAM模块，在Darknet中，新添加的sam_layer层就是用于SAM模块，该层在darknet.h中的定义为sam. 其原理
• 文章目录前言1、matplotlib常用操作2、hook简介3、可视化resnet50最后一层特征图2.1.引入库 前言  本篇主要借助matplotlib可视化pytorch中的特征图可视化，首先介绍matplotlib模块使用，其次介绍pytorch中hook的...
• 为了更好地理解注意力机制，我们提供了一项经验研究，可以消除广义注意力公式中的各种空间注意力元素，包括占主导地位的Transformer注意力以及流行的可变形卷积和动态卷积模块。 在各种应用中进行的研究得出了有关...
• 空间注意力机制就是学习整个画面不同区域的系数，同时考虑到了所有通道 class ChannelAttention(nn.Module): def __init__(self, in_planes, ratio=16): super(ChannelAttention, self).__init__() self.avg_...
• Twins 提出的空间可分离自注意力机制 （SSSA） 空间可分离自注意力使用局部-全局注意力交替（LSA-GSA）的机制，可以大幅降低计算成本，复杂度从输入的平方 O(H2W2d) 降为线性 O(mnHWd)，通过将分组计算的注意力进行...
• U-Net网络模型（简单改进版） 这一段时间做项目用到了U-Net网络模型...***下采样的过程中加入了通道注意力和空间注意力（大概就是这样）*** 代码跑出来后，效果比原来的U-Net大概提升了一个点左右，证明是有效的。 ...
• #空间注意力模块 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 =...
• 图像处理源码-多尺度空间注意力的语义分割
• SCA-CNN在多层特征映射中动态调整句子生成上下文，编码重要的空间位置和通道特征。
• 为什么CBAM通道与空间注意力模块顺序排列性能最好 《CBAM–Convolutional Block Attention Module》 《SENet——Squeeze-and-Excitation Networks》 CBAM的核心是结合通道注意力与空间注意力,文章的很多内容也是对比...
• 在了解了基于通道的注意力机制SE-NET之后，发现CBAM对于upsample造成的图像损失有一定的弥补作用，这让改进网络结构有了一定的思路。 Abstract 我们提出了卷积块注意模块（CBAM），一种简单而有效的前馈卷积神经网络...
• ## 注意力机制总结

万次阅读 多人点赞 2020-12-31 17:41:11
导读 注意力机制，其本质是一种通过网络自主学习出的一组权重系数，并以“动态加权”的方式来强调我们所感兴趣的区域...软注意力按照不同维度（如通道、空间、时间、类别等）出发，目前主流的注意力机制可以分为以下
• ## 注意力的理解心得

千次阅读 多人点赞 2021-07-31 14:41:29
空间注意力是获得H，W维度上的权值（输出是B×1×W×H），然后与feature map相乘。 通道注意力则是获得C 维度上的权值（输出为B×C×1×1），再与feature map 相乘。常见的就是SE注意力。 一个网络中通常会同时使用...
• 文章目录一，注意力机制二，自注意力（self-attention）三，软注意力机制1，空域注意力2,通道注意力机制3，混合域模型4，Non-Local5,位置注意力机制四，强注意力机制 一，注意力机制 attention 机制可以认为是一种...

...