注意力机制详解系列(二):通道注意力机制

news2024/12/22 20:21:47

在这里插入图片描述

👨‍💻作者简介: 大数据专业硕士在读,CSDN人工智能领域博客专家,阿里云专家博主,专注大数据与人工智能知识分享。
🎉专栏推荐: 目前在写CV方向专栏,更新不限于目标检测、OCR、图像分类、图像分割等方向,目前活动仅19.9,虽然付费但会长期更新,感兴趣的小伙伴可以关注下➡️专栏地址
🎉学习者福利: 强烈推荐一个优秀AI学习网站,包括机器学习、深度学习等理论与实战教程,非常适合AI学习者。➡️网站链接。
🎉技术控福利程序员兼职社区招募!靠谱覆盖技术范围广,CV、NLP均可,Pyhton、matlab各类编程语言, 有意向者➡️访问。


📝导读:本篇为注意力机制系列第二篇,主要介绍注意力机制中的通道注意力机制,对通道注意力机制方法进行详细讲解,会对重点论文会进行标注 * ,并配上论文地址和对应代码。
🆙 注意力机制详解系列目录:

1️⃣注意力机制详解系列(一):注意力机制概述
2️⃣注意力机制详解系列(二):通道注意力机制
3️⃣注意力机制详解系列(三):空间注意力机制(待更新)
4️⃣注意力机制详解系列(四):混合与时域注意力机制(待更新)
5️⃣注意力机制详解系列(五):注意力机制总结(待更新)

1.通道注意力机制

在这里插入图片描述

通道注意力机制模型总结

通道注意力机制在计算机视觉中,更关注特征图中channel之间的关系,而普通的卷积会对通道做通道融合,这个开山鼻祖是SENet,后面有GSoP-Net,FcaNet 对SENet中的squeeze部分改进,EACNet对SENet中的excitation部分改进,SRM,GCT等对SENet中的scale部分改进。

通道注意力机制模型对比:

在这里插入图片描述

对应论文链接:

论文缩写论文名称 | 链接权重范围论文投稿
SE BlockSqueeze-and-Excitation Networks(0,1)CVPR2018
GSoP BlockGlobal Second-order Pooling Convolutional Networks(0,1)CVPR2019
SRM BlockSRM : A Style-based Recalibration Module for Convolutional Neural Networks(0,1)ICCV2019
GCT BlockGated Channel Transformation for Visual Recognition(0,1)CVPR2020
ECA BlockECA-Net: Efficient Channel Attention for Deep Convolutional Neural Networks(0,1)CVPR2020
Fca BlockFcaNet: Frequency Channel Attention Networks(0,1)ICCV2021
Enc BlockContext Encoding for Semantic Segmentation(-1,1)CVPR2018

1.SENet

论文:https://arxiv.org/abs/1709.01507
Github:https://github.com/hujie-frank/SENet
https://github.com/moskomule/senet.pytorch

SENet是CVPR17年的一篇文章提出。在卷积神经网络中,卷积操作更多的是关注感受野,在通道上默认为是所有通道的融合(深度可分离卷积不对通道进行融合,但是没有学习通道之间的关系,其主要目的是为了减少计算量),SENet提出SE模块,通过学习的方式自动获取每个特征通道的重要程度,学习到不同通道之间的权重,并且利用得到的重要程度来提升特征并抑制对当前任务不重要的特征。
在这里插入图片描述
SE模块主要由三部分组成:squeezeexcitationscale。实现步骤如下:

总体概述:

(1)Squeeze:通过全局平均池化,将每个通道的二维特征(H*W)压缩为1个实数,将特征图从 [h, w, c] ==> [1,1,c]

(2)excitation:给每个特征通道生成一个权重值,论文中通过两个全连接层构建通道间的相关性,输出的权重值数目和输入特征图的通道数相同。[1,1,c] ==> [1,1,c]

(3)Scale:将前面得到的归一化权重加权到每个通道的特征上。论文中使用的是乘法,逐通道乘以权重系数。[h,w,c]*[1,1,c] ==> [h,w,c]

在这种方式下,每一个样本,都会有自己独立的一组权重。换言之,任意的两个样本,它们的权重,都是不一样的。在SENet中,获得权重的具体路径是,“全局池化→全连接层→ReLU函数→全连接层→Sigmoid函数”。
在这里插入图片描述

详细解释:

第一步首先对h* w* c大小的feature map 做squeeze操作将其变成1 * 1 * c大小,这一步原文中使用简单粗暴的GAP(全局平均池化);

第二步excitation操作,对1 * 1 * c的特征图经过两次全连接,特征图大小1 * 1 * c→1 * 1 * 3→1* 1 * c,再对1 * 1* c的特征图做sigmoid将值限制到[0,1]范围内;

第三步scale,将1 * 1 * c的特征权重图与输入的h * w * c的feature map在通道上相乘;完成SE模块的通道注意力机制。

值得注意的是,在squeeze部分,作者使用的是最简单的全局平均池化的方式,主要原因是作者基于通道的整体信息,关注通道之间的相关性,而不是空间分布的相关性,也尽可能的屏蔽掉空间分布信息;在excitation部分,作者通过两个全连接实现1 * 1 * c2→1 * 1 * c3→1 * 1 * c2,第一个全连接层将c2压缩到c3,用于计算量减少,在原文中作者做实验后发现c3=c2/16时,能实现性能和计算量的平衡。

SE模型同Inception,可以即插即用,理论上可以安插在任意一个卷积后面,简单方便,只会增加一点参数量和计算量。

SENet的实现代码如下:

class SELayer(nn.Module):
    def __init__(self, channel, reduction=1):
        super(SELayer, self).__init__()
        self.avg_pool = nn.AdaptiveAvgPool2d(1)
        self.fc1 = nn.Sequential(
            nn.Linear(channel, channel / reduction),
            nn.ReLU(inplace=True),
            nn.Linear(channel / reduction, channel),
            nn.Sigmoid())
        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):
        b, c, _, _ = x.size()
        y = self.avg_pool(x).view(b, c)
        y = self.fc1(y).view(b, c, 1, 1)
        return x * y

SE模块插入Resnet代码:

class SEBottleneck(nn.Module):
        expansion = 4
 
        def __init__(self, inplanes, planes, stride=1, downsample=None, reduction=16):
            super(SEBottleneck, self).__init__()
            self.conv1 = nn.Conv2d(inplanes, planes, kernel_size=1, bias=False)
            self.bn1 = nn.BatchNorm2d(planes)
            self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, stride=stride,
                                   padding=1, bias=False)
            self.bn2 = nn.BatchNorm2d(planes)
            self.conv3 = nn.Conv2d(planes, planes * 4, kernel_size=1, bias=False)
            self.bn3 = nn.BatchNorm2d(planes * 4)
            self.relu = nn.ReLU(inplace=True)
            self.se = SELayer(planes * 4, reduction)
            self.downsample = downsample
            self.stride = stride
 
        def forward(self, x):
            residual = x
 
            out = self.conv1(x)
            out = self.bn1(out)
            out = self.relu(out)
 
            out = self.conv2(out)
            out = self.bn2(out)
            out = self.relu(out)
 
            out = self.conv3(out)
            out = self.bn3(out)
            out = self.se(out)
 
            if self.downsample is not None:
                residual = self.downsample(x)
 
            out += residual
            out = self.relu(out)
 
            return out

GSoP-Net

论文:https://arxiv.org/abs/1811.12006

github:https://github.com/ZilinGao/Global-Second-order-Pooling-Convolutional-Networks

img

SE模块中squeeze部分用的是全局平均池化,GSoP-Net的主要创新点是将一阶全局平均池化替换成二阶池化,主要操作为对输入为hwc‘的特征图先通过卷积降维到hwc,然后通道之间两两计算相关性,得到cc的协方差矩阵,第i行元素表明第i i个通道和其他通道的统计层面的依赖。由于二次运算涉及到改变数据的顺序,因此对协方差矩阵执行逐行归一化,保留固有的结构信息。然后通过激励模块对协方差特征图做非线性逐行卷积得到11*4c的特征信息,后面同SENet。相对于SNet,增加了全局的统计建模。

FcaNet

论文:http://arxiv.org/abs/2012.11879

github: https://github.com/cfzd/FcaNet

img

FCANet主要也是更新SE模块中squeeze部分,作者设计了一种新的高效多谱通道注意力框架。该框架在GAP是DCT的一种特殊形式的基础上,在频域上推广了GAP通道注意力机制,提出使用有限制的多个频率分量代替只有最低频的GAP。通过集成更多频率分量,不同的信息被提取从而形成一个多谱描述。此外,为了更好进行分量选择,作者设计了一种二阶段特征选择准则,在该准则的帮助下,提出的多谱通道注意力框架达到了SOTA效果。

ECA-Net

论文: https://arxiv.org/pdf/1910.03151

代码: https://github.com/BangguWu/ECANet

ECANet介绍:

ECANet主要对SENet模块进行了一些改进,提出了一种不降维的局部跨信道交互策略(ECA模块)和自适应选择一维卷积核大小的方法,使得通道数较大的层可以更多地进行跨通道交互,从而实现了性能上的提优。

ECANet主要对SENet中的excitation部分改进,SENet采用的降维操作会对通道注意力的预测产生负面影响,且获取依赖关系效率低且不必要,因此提出了一种针对CNN的高效通道注意力(ECA)模块,避免了降维,有效地实现了跨通道交互。

ECANet通过大小为 k 的快速一维卷积实现,其中核大小k表示局部跨通道交互的覆盖范围,即有多少领域参与了一个通道的注意预测 ;同时为了避免通过交叉验证手动调整 k,开发了一种自适应方法确定 k,其中跨通道交互的覆盖范围 (即核大小k) 与通道维度成比例 。
在这里插入图片描述
这里 在这里插入图片描述表示最近的奇数t。本文中将γ设置为2,b设置为1。

在这里插入图片描述

ECANet实现流程:

(1)将输入特征图经过全局平均池化,特征图从 [h,w,c] 的矩阵变成 [1,1,c] 的向量

(2)根据特征图的通道数计算得到自适应的一维卷积核大小 kernel_size

(3)将 kernel_size 用于一维卷积中,得到对于特征图的每个通道的权重

(4)将归一化权重和原输入特征图逐通道相乘,生成加权后的特征图

核心:ECA 注意力机制模块直接在全局平均池化层之后使用1x1卷积层,去除了全连接层。该模块避免了维度缩减,并有效捕获了跨通道交互。并且ECANet 只涉及少数参数就能达到很好的效果。

ECANet实战代码:

#ECANet使用1D卷积代替SE注意力机制中的全连接层
import torch
from torch import nn
import math
from torchstat import stat  # 查看网络参数
 
# 定义ECANet的类
class eca_block(nn.Module):
    # 初始化, in_channel代表特征图的输入通道数, b和gama代表公式中的两个系数
    def __init__(self, in_channel, b=1, gama=2):
        # 继承父类初始化
        super(eca_block, self).__init__()
        
        # 根据输入通道数自适应调整卷积核大小
        kernel_size = int(abs((math.log(in_channel, 2)+b)/gama))
        # 如果卷积核大小是奇数,就使用它
        if kernel_size % 2:
            kernel_size = kernel_size
        # 如果卷积核大小是偶数,就把它变成奇数
        else:
            kernel_size = kernel_size
        
        # 卷积时,为例保证卷积前后的size不变,需要0填充的数量
        padding = kernel_size // 2
        
        # 全局平均池化,输出的特征图的宽高=1
        self.avg_pool = nn.AdaptiveAvgPool2d(output_size=1)
        # 1D卷积,输入和输出通道数都=1,卷积核大小是自适应的
        self.conv = nn.Conv1d(in_channels=1, out_channels=1, kernel_size=kernel_size,
                              bias=False, padding=padding)
        # sigmoid激活函数,权值归一化
        self.sigmoid = nn.Sigmoid()
    
    # 前向传播
    def forward(self, inputs):
        # 获得输入图像的shape
        b, c, h, w = inputs.shape
        
        # 全局平均池化 [b,c,h,w]==>[b,c,1,1]
        x = self.avg_pool(inputs)
        # 维度调整,变成序列形式 [b,c,1,1]==>[b,1,c]
        x = x.view([b,1,c])
        # 1D卷积 [b,1,c]==>[b,1,c]
        x = self.conv(x)
        # 权值归一化
        x = self.sigmoid(x)
        # 维度调整 [b,1,c]==>[b,c,1,1]
        x = x.view([b,c,1,1])
        
        # 将输入特征图和通道权重相乘[b,c,h,w]*[b,c,1,1]==>[b,c,h,w]
        outputs = x * inputs
        return outputs

SRM

论文: https://arxiv.org/pdf/1903.10829

代码:https://github.com/hyunjaelee410/style-based-recalibration-module

SRM受风格迁移的启发,对SENet中的squeeze和excitation部分进行更新:

img
提出了一种基于style的重新校准模块(SRM),可以通过利用其style自适应地重新校准中间特征图。SRM首先通过样式池从特征图的每个通道中提取样式信息,然后通过与通道无关的style集成来估计每个通道的重新校准权重。

img
给定一个输入特征特征图大小为C × H × W ,SRM首先通过结合全局平均池全局标准差池化的风格式池化收集全局信息。然后使用通道全连接层(即每个通道全连接)、批量归一化BN和sigmoid函数σ来提供注意力向量。最后,与SE块一样,输入特征乘以注意力向量。它利用输入特征的均值和标准差来提高捕获全局信息的能力。为了降低计算层(CFC)的完全连接要求,在全连接的地方也采用了CFC。通过将各个style的相对重要性纳入特征图,SRM有效地增强了CNN的表示能力。重点是轻量级,引入的参数非常少,同时效果还优于SENet.。

GCT

论文: GCT
代码: https://github.com/z-x-yang/GCT

img
GCT是由百度提出,一种通用且轻量型变化单元,结合了归一化和注意力机制,分析通道之间的相互关系(竞争or协作),对SENet中的squeeze、excitation和scale部分进行更新:在squeeze部分中使用L2 norm进行了global context embeding,同时在excitation中,仍然使用L2 norm 对通道归一化,在scale中通过设置权重γ和偏置β来控制通道特征是否激活。当一个通道的特征权重γc被正激活,GCT将促进这个通道的特征和其它通道的特征“竞争”。当一个通道的特征 γc 被负激活,GCT将促进这个通道的特征和其它通道的特征“合作”。

参考论文

  • [1] Squeeze-and-Excitation Networks
  • [2] Global Second-order Pooling Convolutional Networks
  • [3] FcaNet: Frequency Channel Attention Networks
  • [4] ECA-Net: Efficient Channel Attention for Deep Convolutional Neural Networks
  • [5] SRM : A Style-based Recalibration Module for Convolutional Neural Networks
  • [6] Gated Channel Transformation for Visual Recognition
  • [7] Recurrent Models of Visual Attention

具体链接见对应介绍!

总结:
本篇主要介绍注意力机制中的通道注意力机制,对通道注意力机制方法进行详细讲解,通道注意力机制在计算机视觉中,更关注特征图中channel之间的关系,重点对SENet、ECANe进行重点讲解,下篇将对空间注意力机制展开详细介绍.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/372279.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

锁屏面试题百日百刷-Hive篇(三)

锁屏面试题百日百刷,每个工作日坚持更新面试题。锁屏面试题app、小程序现已上线,官网地址:https://www.demosoftware.cn/#/introductionPage。已收录了每日更新的面试题的所有内容,还包含特色的解锁屏幕复习面试题、每日编程题目邮…

函数库Rollup构建优化

本节涉及的内容源码可在vue-pro-components c7 分支[1]找到,欢迎 star 支持!前言本文是基于ViteAntDesignVue打造业务组件库[2] 专栏第 8 篇文章【函数库Rollup构建优化】,在上一篇文章的基础上,聊聊在使用 Rollup 构建函数库的过…

【从零开始制作 bt 下载器】一、了解 torrent 文件

【从零开始制作 bt 下载器】一、了解 torrent 文件写作背景了解 torrent 文件认识 bencodepython 解析 torrent 文件解密 torrent 文件结尾写作背景 最先开始是朋友向我诉说使用某雷下载结果显示因为版权无法下载,找其他的下载器有次数限制,于是来询问我…

Redis学习笔记(二)Redis基础(基于5.0.5版本)

一、Redis定位与特性 Redis是一个速度非常快的非关系数据库(non-relational database),用 Key-Value 的形式来存储数据。数据主要存储在内存中,所以Redis的速度非常快,另外Redis也可以将内存中的数据持久化到硬盘上。…

[SSD综述 1.3] SSD及固态存储技术半个世纪发展史

在我们今天看来,SSD已不再是个新鲜事物。这多亏了存储行业的前辈们却摸爬滚打了将近半个世纪,才有了SSD的繁荣, 可惜很多前辈都没有机会看到。所有重大的技术革新都是这样,需要长期的技术积累,一代一代的工程师们默默的…

华为OD机试用Python实现 -【狼羊过河 or 羊、狼、农夫过河】(2023-Q1 新题)

华为OD机试题 华为OD机试300题大纲狼羊过河 or 羊、狼、农夫过河题目描述输入描述输出描述说明示例一输入输出说明Python 代码实现代码实现思路华为OD机试300题大纲 参加华为od机试,一定要注意不要完全背诵代码,需要理解之后模仿写出,通过率才会高。 华为 OD 清单查看地址…

学到贫血之-贫血模型和充血模型

学习自:设计模式之美 1 基于贫血模型的传统开发模式 // ControllerVO(View Object) public class UserController {private UserService userService; //通过构造函数或者IOC框架注入public UserVo getUserById(Long userId) {UserBo userBo userService.getUser…

【华为OD机试模拟题】用 C++ 实现 - 相对开音节(2023.Q1)

最近更新的博客 【华为OD机试模拟题】用 C++ 实现 - 获得完美走位(2023.Q1) 文章目录 最近更新的博客使用说明相对开音节题目输入输出示例一输入输出说明示例二输入输出说明Code使用说明 参加华为od机试,一定要注意不要完全背诵代码,需要理解之后模仿写出,通过率才会高…

【云原生】搭建k8s高可用集群—20230225

文章目录多master(高可用)介绍高可用集群使用技术介绍搭建高可用k8s集群步骤1. 准备环境-系统初始化2. 在所有master节点上部署keepalived3.1 安装相关包3.2 配置master节点3.3 部署haproxy错误解决3. 所有节点安装Docker/kubeadm/kubelet4. 部署Kuberne…

《痞子衡嵌入式半月刊》 第 72 期

痞子衡嵌入式半月刊: 第 72 期 这里分享嵌入式领域有用有趣的项目/工具以及一些热点新闻,农历年分二十四节气,希望在每个交节之日准时发布一期。 本期刊是开源项目(GitHub: JayHeng/pzh-mcu-bi-weekly),欢迎提交 issue&#xff0c…

【华为OD机试模拟题】用 C++ 实现 - 求解连续数列+和最大子矩阵(2023.Q1 双倍快乐)

最近更新的博客 【华为OD机试模拟题】用 C++ 实现 - 获得完美走位(2023.Q1) 文章目录 最近更新的博客使用说明求解连续数列题目输入输出描述示例一输入输出Code和最大子矩阵题目输入输出示例一输入输出说明

CMU15-445 Project.0总结

在线测试 本地测试 Project #0 - C Primer 以下是Project #0的网址,2022FALL的Project #0本质上是实现一棵字典树,关于字典树的相关内容可以参考C实现字典树。 在本题中,为了存储对应着字符串的任意类型值,题目设计了一个Tri…

CV——day79 读论文:基于小目标检测的扩展特征金字塔网络

Extended Feature Pyramid Network for Small Object DetectionI. INTRODUCTIONII. RELATED WORKA. 深层物体探测器B. 跨尺度特征C. 目标检测中的超分辨率III. OUR APPROACHA. 扩展特征金字塔网络B. 特征纹理传输C. 交叉分辨蒸馏IV. EXPERIMENTSA. Experimental Settings1&…

SEATA是什么?它的四种分布式事务模式

一、SEATA是什么? Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案。 在继续学习使用SEATA之前,对s…

电子科技大学数据库与软件工程实验五

适用于网工和物联网专业 期末考试会考 目录 一、实验目的 二、实验内容 三、实验软件 四、实验步骤及数据记录 1. 权限管理 2. 数据库备份 3. 生成 AWR 报告 五、实验结论及思考题 六、总结及心得体会 七、对本实验过程及方法、手段的改进建议 一、实验目的 1、掌握…

工作九年的机器人讲师收入如何

如下都是个人情况,供各位朋友参考,仅为个人情况,只代表我个人。为何写这样一篇博客:看了最近的热点我在一所普普通通的不知名高校工作了九年。如果问及我存款……我实在是非常非常惭愧的。真实数值如下(组合贷&#xf…

【数据库】第八章 数据库编程

第八章 数据库编程 8.1 嵌入式SQL&#xff08;C语言版&#xff09; 被嵌入的语言&#xff08;java ,C)等被称为宿主语言&#xff0c;简称主语言 当主语言 为 C 语言的时候 ​ 语法格式为 EXEC SQL <SQL语句>当主语言为java的时候 格式为 #SQL {<SQL语句>}以下讲解…

MATLAB | 如何解决实验数据散点图重叠问题(overlap)

本期部分实验效果&#xff1a; 这期讲一下如果数据重合严重该咋办(overlap)&#xff0c;事先说明&#xff0c;本文中的绘图均使用一个几行的简单小代码进行了修饰&#xff1a; function defualtAxes axgca;hold on;box on ax.XGridon; ax.YGridon; ax.XMinorTickon; ax.YMinor…

Redis 之企业级解决方案

文章目录一、缓存预热二、缓存雪崩三、缓存击穿四、缓存穿透五、性能指标监控5.1 监控指标5.2 监控方式&#x1f34c;benchmark&#x1f34c;monitor&#x1f34c;slowlog提示&#xff1a;以下是本篇文章正文内容&#xff0c;Redis系列学习将会持续更新 一、缓存预热 1.1 现象…

云服务器产生背景与历史演进

云服务器产生背景  业务量爆发和衰退周期考验后端服务器性能匹配 在传统IT架构中&#xff0c;需要提前预估业务爆发时间和业务量&#xff0c;提前部署服务器以支撑业务。但是&#xff0c;往往预估与实际结果是有差距的&#xff0c;预估量过大会造成服务器采购成本高&#x…