CV常用注意力机制总结

本文总结了近几年CV领域常用的注意力机制,包括:SE(Squeeze and Excitation)、ECA(Efficient Channel Attention)、CBAM(Convolutional Block Attention Module)、CA(Coordinate attention for efficient mobile network design)

一、SE

目的是给特征图中不同的通道赋予不同的权重,步骤如下:

  1. 对特征图进行Squeeze,该步骤是通过全局平均池化把特征图从大小为(N,C,H,W)转换为(N,C,1,1),这样就达到了全局上下文信息的融合
  2. Excitation操作,该步骤使用两个全连接层,其中第一个全连接层使用ReLU激活函数,第二个全连接层采用Sigmoid激活函数,目的是将权重中映射到(0,1)之间。值得注意的是,为了减少计算量进行降维处理,将第一个全连接的输出采用输入的1/4或者1/16
  3. 通过广播机制将权重与输入特征图相乘,得到不同权重下的特征图

代码实现如下, 

import torch
import torch.nn as nn


class Se(nn.Module):
    def __init__(self, in_channel, reduction=16):
        super(Se, self).__init__()
        self.pool = nn.AdaptiveAvgPool2d(output_size=1)
        self.fc = nn.Sequential(
            nn.Linear(in_features=in_channel, out_features=in_channel//reduction, bias=False),
            nn.ReLU(),
            nn.Linear(in_features=in_channel//reduction, out_features=in_channel, bias=False),
            nn.Sigmoid()
        )

    def forward(self,x):
        out = self.pool(x)
        out = self.fc(out.view(out.size(0),-1))
        out = out.view(x.size(0),x.size(1),1,1)
        return out*x

二、ECA

可参考《注意力机制 ECA-Net 学习记录_eca注意力机制_chen_zn95的博客-CSDN博客》

ECA也是一个通道注意力机制,该算法是在SE的基础上做出了一定的改进,首先ECA作者认为SE中的全连接降维可以降低模型的复杂度,但这也破坏了通道与其权重之间的直接对应关系,先降维后升维,这样权重和通道的对应关系是间接的。为了解决以上问题,作者提出一维卷积的方法,避免了降维对数据的影响,步骤如下:

  1. 对特征图进行Squeeze,该步骤是通过全局平均池化把特征图从大小为(N,C,H,W)转换为(N,C,1,1),这样就达到了全局上下文信息的融合(与SE的步骤1相同)
  2. 计算自适应卷积核的大小,k=\left | \frac{log_{2}^{C}}{\gamma }+\frac{b}{\gamma } \right |,其中,C:输入通道数,b=1,γ=2;对经过步骤一处理的特征进行一维卷积操作(获得局部跨通道信息),再采用Sigmoid激活函数将权重映射在0到1之间
  3. 通过广播机制将权重与输入特征图相乘,得到不同权重下的特征图

代码实现如下,

import torch
import torch.nn as nn
import math


class ECA(nn.Module):
    def __init__(self, in_channel, gamma=2, b=1):
        super(ECA, self).__init__()
        k = int(abs((math.log(in_channel,2)+b)/gamma))
        kernel_size = k if k % 2 else k+1
        padding = kernel_size//2
        self.pool = nn.AdaptiveAvgPool2d(output_size=1)
        self.conv = nn.Sequential(
            nn.Conv1d(in_channels=1, out_channels=1, kernel_size=kernel_size, padding=padding, bias=False),
            nn.Sigmoid()
        )

    def forward(self,x):
        out=self.pool(x)
        out=out.view(x.size(0), 1, x.size(1))
        out=self.conv(out)
        out=out.view(x.size(0), x.size(1), 1, 1)
        return out*x

三、CBAM

CBAM是一种将通道与空间注意力机制相结合的算法,输入特征图先进行通道注意力机制再进行空间注意力机制操作,这样从通道和空间两个方面达到了强化感兴趣区域的目的

通道注意力机制的实现步骤如下:

  1. 对特征图进行Squeeze,该步骤分别采用全局平均池化和全局最大池化把特征图从大小为(N,C,H,W)转换为(N,C,1,1),这样就达到了全局上下文信息的融合
  2. 分别将全局最大池化和全局平均池化结果进行MLP操作,MLP在这里定义与SE的全连接层操作一样,为两层全连接层,中间采用ReLU激活,最后将两者相加后利用Sigmoid函数激活
  3. 通过广播机制将权重与输入特征图相乘,得到不同权重下的特征图

空间注意力机制的实现步骤如下:

  1. 将上述通道注意力操作的结果,分别在通道维度上进行最大池化和平均池化,即将经过通道注意力机制的特征图从(N,C,H,W)转换为(N,1,H,W),融合不同通道的信息,然后在通道维度上将最大池化与平均池化的结果concat起来
  2. 将叠加后2个通道的结果做卷积运算,输出通道为1,卷积核大小为7,最后将输出结果进行Sigmoid处理
  3. 通过广播机制将权重与输入特征图相乘,得到不同权重下的特征图

代码实现如下,

import torch
import torch.nn as nn
import math


class CBAM(nn.Module):
    def __init__(self, in_channel, reduction=16, kernel_size=7):
        super(CBAM, self).__init__()
        # 通道注意力机制
        self.max_pool = nn.AdaptiveMaxPool2d(output_size=1)
        self.avg_pool = nn.AdaptiveAvgPool2d(output_size=1)
        self.mlp = nn.Sequential(
            nn.Linear(in_features=in_channel, out_features=in_channel//reduction, bias=False),
            nn.ReLU(),
            nn.Linear(in_features=in_channel//reduction, out_features=in_channel,bias=False)
        )
        self.sigmoid = nn.Sigmoid()
        # 空间注意力机制
        self.conv = nn.Conv2d(in_channels=2, out_channels=1, kernel_size=kernel_size , stride=1, padding=kernel_size//2, bias=False)

    def forward(self,x):
        # 通道注意力机制
        max_out = self.max_pool(x)
        max_out = self.mlp(max_out.view(maxout.size(0), -1))
        avg_out = self.avg_pool(x)
        avg_out = self.mlp(avg_out.view(avgout.size(0), -1))
        channel_out = self.sigmoid(max_out+avg_out)
        channel_out = channel_out.view(x.size(0), x.size(1),1,1)
        channel_out = channel_out*x
        # 空间注意力机制
        max_out, _ = torch.max(channel_out, dim=1, keepdim=True)
        mean_out = torch.mean(channel_out, dim=1, keepdim=True)
        out = torch.cat((max_out, mean_out), dim=1)
        out = self.sigmoid(self.conv(out))
        out = out*channel_out
        return out

四、CA

SE对提升模型性能具有显著的有效性,但它们通常忽略了位置信息。CA利用x、y两个方向的全局池化,分别将垂直和水平方向上的输入特征聚合为两个独立的方向感知特征映射,将输入Feature Map的位置信息嵌入到通道注意力的聚合特征向量。这两个嵌入方向特定信息的特征图被分别编码到两个注意图中,然后通过乘法将这两种注意图应用于输入特征图,加强感兴趣区域的表示。实现步骤如下:

  1. 沿着x、y方向对输入特征图分别进行自适应池化操作,将特征图大小从(N,C,H,W)变为(N,C,H,1)、(N,C,1,W),对大小为(N,C,1,W)的特征进行permute操作,使得该特征大小变为(N,C,W,1),再沿着(dim=2)对这两个特征进行concat,得到大小为(N,C,H+W,1)的特征图
  2. 对步骤一处理后的特征进行1*1卷积操作(目的是降维),随后再经过BN和h_swish激活函数
  3. 沿着dim=2对步骤二处理后的特征进行分割操作(torch.split),将特征分为(N,C/r,H,1)、(N,C/r,W,1),其中r为通道降维因子。随后对大小为(N,C/r,W,1)的特征进行permute操作,变为(N,C/r,1,W)。最后对以上两个特征进行1*1卷积操作(目的是改变特征图的通道数)并经Sigmoid处理
  4. 通过广播机制将步骤三的两个特征先后与输入特征图相乘(out = identity * a_w * a_h),得到不同权重下的特征图

【下图有点小问题,应该是对1D Global Avg Pool(W)特征进行permute操作】

代码实现如下,

import torch
import torch.nn as nn
import math
import torch.nn.functional as F


class h_sigmoid(nn.Module):
    def __init__(self, inplace=True):
        super(h_sigmoid, self).__init__()
        self.relu = nn.ReLU6(inplace=inplace)

    def forward(self, x):
        return self.relu(x + 3) / 6

class h_swish(nn.Module):
    def __init__(self, inplace=True):
        super(h_swish, self).__init__()
        self.sigmoid = h_sigmoid(inplace=inplace)

    def forward(self, x):
        return x * self.sigmoid(x)

class CoordAtt(nn.Module):
    def __init__(self, inp, oup, reduction=32):
        super(CoordAtt, self).__init__()
        self.pool_h = nn.AdaptiveAvgPool2d((None, 1))
        self.pool_w = nn.AdaptiveAvgPool2d((1, None))

        mip = max(8, inp // reduction)

        self.conv1 = nn.Conv2d(inp, mip, kernel_size=1, stride=1, padding=0)
        self.bn1 = nn.BatchNorm2d(mip)
        self.act = h_swish()
        
        self.conv_h = nn.Conv2d(mip, oup, kernel_size=1, stride=1, padding=0)
        self.conv_w = nn.Conv2d(mip, oup, kernel_size=1, stride=1, padding=0)
        

    def forward(self, x):
        identity = x
        
        n,c,h,w = x.size()
        x_h = self.pool_h(x)
        x_w = self.pool_w(x).permute(0, 1, 3, 2)

        y = torch.cat([x_h, x_w], dim=2)
        y = self.conv1(y)
        y = self.bn1(y)
        y = self.act(y) 
        
        x_h, x_w = torch.split(y, [h, w], dim=2)
        x_w = x_w.permute(0, 1, 3, 2)

        a_h = self.conv_h(x_h).sigmoid()
        a_w = self.conv_w(x_w).sigmoid()

        out = identity * a_w * a_h

        return out

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

切换.net Framework 版本后,出现NuGet 包是使用不同于当前目标框架的目标框架安装的,可能需要重新安装

问题现象: 由于添加新的dll文件,依赖的.NET Framework版本与当前的不一致,在vs 中切换了目标框架版本后,运行程序,出现以下的warnning信息: 一些 NuGet 包是使用不同于当前目标框架的目标框架安装的&#…

MacOS系统(M1/M2)安装AI绘画StableDiffusion保姆级教程

TOC 安装完成后,推荐阅读这篇教程:AI绘画:Stable Diffusion 终极炼丹宝典:从入门到精通 实操环境: macOS 13 Arm64(建议12以上的系统使用) Apple M1 先来看几个样例: AI绘画S…

SDN系统方法 | 1. 概述

随着互联网和数据中心流量的爆炸式增长,SDN已经逐步取代静态路由交换设备成为构建网络的主流方式,本系列是免费电子书《Software-Defined Networks: A Systems Approach》的中文版,完整介绍了SDN的概念、原理、架构和实现方式。原文: Softwar…

MongoDB负载均衡集群监控

对负载均衡的集群监控,不仅仅集中在对集群所有的资源、服务等进行监控,还要兼顾整体逻辑。以MongoDB高可用负载均衡集群为例,对逻辑层面的监控,就是模拟用户行为,访问集群数据,判断运行状态是否正常。 Mong…

数据库用户管理

数据库用户管理 一、创建: 1.新建用户: CREATE USER 用户名来源地址 [IDENTIFIED BY [PASSWORD] 密码];‘用户名’:指定将创建的用户名. ‘来源地址’:指定新创建的用户可在哪些主机上登录,可使用IP地址、网段、主机…

手撕自定义类型:结构体,枚举,联合——【C语言】

在开始学习之前我们先来欣赏一下五岳之一华山的风景,来营造一个好心情,只有一个好心情我们才能更好的学习 目录 结构体 1 结构体的声明 1.1 结构的基础知识 1.2 结构的声明 1.3 特殊的声明 1.4 结构的自引用 1.5 结构体变量的定义和初始化 1.6 …

golang单元测试及mock总结

文章目录 一、前言1、单测的定位2、vscode中生成单测 二、构造测试case的注意事项1、项目初始化2、构造空interface{}3、构造结构体的time.Time类型4、构造json格式的test case 三、运行单测文件1、整体运行单测文件2、运行单个单测文件报错(1)command-l…

无法找到docker.sock

os环境:麒麟v10(申威) 问题描述: systemctl start docker 然后无法使用docker [rootnode2 ~]# systemctl restart docker [rootnode2 ~]# docker ps Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon r…

PLEX如何搭建个人局域网的视频网站

Plex是一款功能非常强大的影音媒体管理系统,最大的优势是多平台支持和界面优美,几乎可以在所有的平台上安装plex服务器和客户端,让你可以随时随地享受存储在家中的电影、照片、音乐,并且可以实现观看记录无缝衔接,手机…

PROFINET转TCP/IP网关TCP/IP协议的含义是

大家好,今天要和大家分享一款自主研发的通讯网关,远创智控YC-PN-TCPIP。这款网关可是集多种功能于一身,PROFINET从站功能,让它在通讯领域独领风骚。想知道这款网关如何实现PROFINET和TCP/IP网络的连接吗?一起来看看吧&…

iPad远控Windows解决方案

最近入手了一台iPad,但我不想让它沦为爱奇艺的工具,遂考虑如何在iPad上获得桌面级Windows的生产力。主要还是之前背着电脑出远门太累了,这也是促成我买iPad的重要因素。 一种方案就是通过远程控制,在iPad上远程操作自己的电脑&am…

C# PaddleInference OCR 表格识别

效果 项目 VS2022.net4.8OpenCvSharp4Sdcb.PaddleInferenceSdcb.PaddleOCR 测试图片 代码 using OpenCvSharp.Extensions; using OpenCvSharp; using Sdcb.PaddleInference; using Sdcb.PaddleOCR; using Sdcb.PaddleOCR.Models; using Sdcb.PaddleOCR.Models.Details; using…

一次零基础靶机渗透细节全程记录

一、打靶总流程 1.确定目标: 在本靶场中,确定目标就是使用nmap进行ip扫描,确定ip即为目标,只是针对此靶场而言。其他实战中确定目标的方式包括nmap进行扫描,但不局限于这个nmap。 2.信息收集: 比如平常挖…

数据结构(2.1)——时间复杂度和空间复杂度计算

前言 (1)因为上一篇博客:数据结构(2)—算法对于时间复杂度和空间复杂度计算的讲解太少。所以我在次增加多个案例讲解。 (2)上一篇已经详细介绍了,为什么我们的算法要使用复杂度这一个…

Stable Diffusion (持续更新)

引言 本文的目的为记录stable diffusion的风格迁移,采用diffusers example中的text_to_image和textual_inversion目录 2023.7.11 收集了6张水墨画风格的图片,采用textual_inversion进行训练,以"The street of Paris, in the style of …

uniApp之同步资源失败,未得到同步资源的授权,请停止运行后重新运行,并注意手机上的授权提示、adb、shell、package、uninstall

文章目录 背景解决思路执行查找第三方应用的指令执行卸载指令 背景 一开始正常编译运行,由于应用页面有些许奇怪的错误,便想着卸载,重新运行安装调试基座。卸载后,运行还是会出现,明明已经把应用卸载了,还是…

基于深度学习的高精度Caltech行人检测系统(PyTorch+Pyside6+YOLOv5模型)

摘要:基于深度学习的高精度Caltech数据集行人检测识别系统可用于日常生活中或野外来检测与定位行人目标,利用深度学习算法可实现图片、视频、摄像头等方式的行人目标检测识别,另外支持结果可视化与图片或视频检测结果的导出。本系统采用YOLOv…

HTTP、HTTPS协议详解

文章目录 HTTP是什么报文结构请求头部响应头部 工作原理用户点击一个URL链接后,浏览器和web服务器会执行什么http的版本持久连接和非持久连接无状态与有状态Cookie和Sessionhttp方法:get和post的区别 状态码 HTTPS是什么ssl如何搞到证书nginx中的部署 加…

什么是人工智能大模型?

目录 1. 人工智能大模型的概述:2. 典型的人工智能大模型:3. 人工智能大模型的应用领域:4. 人工智能大模型的挑战与未来:5. 人工智能大模型的开发和应用:6. 人工智能大模型的学习资源: 人工智能大模型是指具…

计数排序

计数排序 排序步骤 1、以最大值和最小值的差值加一为长度创建一个新数组 2、将索引为0对应最小值,索引为1对应最小值1,索引为2对应最小值2,以此类推,将索引对应最小值到最大值之间所有的值 3、遍历一遍,遇到一个数字…