YOLOv9有效提点|加入BAM、CloFormer、Reversible Column Networks、Lskblock等几十种注意力机制(二)

 


专栏介绍:YOLOv9改进系列 | 包含深度学习最新创新,主力高效涨点!!!


一、本文介绍

 本文只有代码注意力模块简介,YOLOv9中的添加教程:可以看这篇文章。

YOLOv9有效提点|加入SE、CBAM、ECA、SimAM等几十种注意力机制(一)


CloFormer:《Rethinking Local Perception in Lightweight Vision Transformer》

        CloFormer是一种轻量级视觉转换器,它通过利用上下文感知的本地增强,提高了在图像分类、目标检测和语义分割等任务上的性能。CloFormer通过引入一种名为AttnConv的卷积操作,结合共享权重和上下文感知权重,有效地捕捉了高频率的本地信息。实验结果表明,CloFormer在各种视觉任务中具有显著优势。

class AttnMap(nn.Module):
    def __init__(self, dim):
        super().__init__()
        self.act_block = nn.Sequential(
                            nn.Conv2d(dim, dim, 1, 1, 0),
                            MemoryEfficientSwish(),
                            nn.Conv2d(dim, dim, 1, 1, 0)
                            #nn.Identity()
                         )
    def forward(self, x):
        return self.act_block(x)

class EfficientAttention(nn.Module):

    def __init__(self, dim, num_heads, group_split: List[int], kernel_sizes: List[int], window_size=7, 
                 attn_drop=0., proj_drop=0., qkv_bias=True):
        super().__init__()
        assert sum(group_split) == num_heads
        assert len(kernel_sizes) + 1 == len(group_split)
        self.dim = dim
        self.num_heads = num_heads
        self.dim_head = dim // num_heads
        self.scalor = self.dim_head ** -0.5
        self.kernel_sizes = kernel_sizes
        self.window_size = window_size
        self.group_split = group_split
        convs = []
        act_blocks = []
        qkvs = []
        #projs = []
        for i in range(len(kernel_sizes)):
            kernel_size = kernel_sizes[i]
            group_head = group_split[i]
            if group_head == 0:
                continue
            convs.append(nn.Conv2d(3*self.dim_head*group_head, 3*self.dim_head*group_head, kernel_size,
                         1, kernel_size//2, groups=3*self.dim_head*group_head))
            act_blocks.append(AttnMap(self.dim_head*group_head))
            qkvs.append(nn.Conv2d(dim, 3*group_head*self.dim_head, 1, 1, 0, bias=qkv_bias))
            #projs.append(nn.Linear(group_head*self.dim_head, group_head*self.dim_head, bias=qkv_bias))
        if group_split[-1] != 0:
            self.global_q = nn.Conv2d(dim, group_split[-1]*self.dim_head, 1, 1, 0, bias=qkv_bias)
            self.global_kv = nn.Conv2d(dim, group_split[-1]*self.dim_head*2, 1, 1, 0, bias=qkv_bias)
            #self.global_proj = nn.Linear(group_split[-1]*self.dim_head, group_split[-1]*self.dim_head, bias=qkv_bias)
            self.avgpool = nn.AvgPool2d(window_size, window_size) if window_size!=1 else nn.Identity()

        self.convs = nn.ModuleList(convs)
        self.act_blocks = nn.ModuleList(act_blocks)
        self.qkvs = nn.ModuleList(qkvs)
        self.proj = nn.Conv2d(dim, dim, 1, 1, 0, bias=qkv_bias)
        self.attn_drop = nn.Dropout(attn_drop)
        self.proj_drop = nn.Dropout(proj_drop)

    def high_fre_attntion(self, x: torch.Tensor, to_qkv: nn.Module, mixer: nn.Module, attn_block: nn.Module):
        '''
        x: (b c h w)
        '''
        b, c, h, w = x.size()
        qkv = to_qkv(x) #(b (3 m d) h w)
        qkv = mixer(qkv).reshape(b, 3, -1, h, w).transpose(0, 1).contiguous() #(3 b (m d) h w)
        q, k, v = qkv #(b (m d) h w)
        attn = attn_block(q.mul(k)).mul(self.scalor)
        attn = self.attn_drop(torch.tanh(attn))
        res = attn.mul(v) #(b (m d) h w)
        return res
        
    def low_fre_attention(self, x : torch.Tensor, to_q: nn.Module, to_kv: nn.Module, avgpool: nn.Module):
        '''
        x: (b c h w)
        '''
        b, c, h, w = x.size()
        
        q = to_q(x).reshape(b, -1, self.dim_head, h*w).transpose(-1, -2).contiguous() #(b m (h w) d)
        kv = avgpool(x) #(b c h w)
        kv = to_kv(kv).view(b, 2, -1, self.dim_head, (h*w)//(self.window_size**2)).permute(1, 0, 2, 4, 3).contiguous() #(2 b m (H W) d)
        k, v = kv #(b m (H W) d)
        attn = self.scalor * q @ k.transpose(-1, -2) #(b m (h w) (H W))
        attn = self.attn_drop(attn.softmax(dim=-1))
        res = attn @ v #(b m (h w) d)
        res = res.transpose(2, 3).reshape(b, -1, h, w).contiguous()
        return res

    def forward(self, x: torch.Tensor):
        '''
        x: (b c h w)
        '''
        res = []
        for i in range(len(self.kernel_sizes)):
            if self.group_split[i] == 0:
                continue
            res.append(self.high_fre_attntion(x, self.qkvs[i], self.convs[i], self.act_blocks[i]))
        if self.group_split[-1] != 0:
            res.append(self.low_fre_attention(x, self.global_q, self.global_kv, self.avgpool))
        return self.proj_drop(self.proj(torch.cat(res, dim=1)))

《Reversible Column Networks》

        Reversible Column Networks一种新的神经网络设计范式——可逆列网络(RevCol)。RevCol主要由多个子网络(称为“列”)的副本组成,这些子网络之间使用了多级可逆连接。这种架构方案使得RevCol的行为与传统的网络非常不同:在正向传播过程中,当特征通过每个列时,它们被逐渐解开,同时保持总信息量,而不是像其他网络那样进行压缩或丢弃。

 这个暂时没调试,代码地址:RevCol/models/revcol.py at main · megvii-research/RevCol (github.com)icon-default.png?t=N7T8https://github.com/megvii-research/RevCol/blob/main/models/revcol.py


《BAM: Bottleneck Attention Module》

        瓶颈注意模块(BAM)关注深度神经网络中注意力机制的影响,提出了一个简单而有效的注意力模块,即瓶颈注意模块(BAM),可以与任何前馈卷积神经网络集成,沿着两个不同的路径(通道和空间)推断注意力映射。 将模块放在模型的每个瓶颈处(特征映射产生降采样),构建一个具有多个参数的分层注意,可以与任何前馈模型以端到端方式进行训练。

def autopad(k, p=None, d=1):  # kernel, padding, dilation
    """Pad to 'same' shape outputs."""
    if d > 1:
        k = d * (k - 1) + 1 if isinstance(k, int) else [d * (x - 1) + 1 for x in k]  # actual kernel-size
    if p is None:
        p = k // 2 if isinstance(k, int) else [x // 2 for x in k]  # auto-pad
    return p

class Flatten(nn.Module):
    def forward(self, x):
        return x.view(x.shape[0], -1)


class ChannelAttention(nn.Module):
    def __init__(self, channel, reduction=16, num_layers=3):
        super().__init__()
        self.avgpool = nn.AdaptiveAvgPool2d(1)
        gate_channels = [channel]
        gate_channels += [channel // reduction] * num_layers
        gate_channels += [channel]

        self.ca = nn.Sequential()
        self.ca.add_module('flatten', Flatten())
        for i in range(len(gate_channels) - 2):
            self.ca.add_module('fc%d' % i, nn.Linear(gate_channels[i], gate_channels[i + 1]))
            self.ca.add_module('bn%d' % i, nn.BatchNorm1d(gate_channels[i + 1]))
            self.ca.add_module('relu%d' % i, nn.ReLU())
        self.ca.add_module('last_fc', nn.Linear(gate_channels[-2], gate_channels[-1]))

    def forward(self, x):
        res = self.avgpool(x)
        res = self.ca(res)
        res = res.unsqueeze(-1).unsqueeze(-1).expand_as(x)
        return res


class SpatialAttention(nn.Module):
    def __init__(self, channel, reduction=16, num_layers=3, dia_val=2):
        super().__init__()
        self.sa = nn.Sequential()
        self.sa.add_module('conv_reduce1',
                           nn.Conv2d(kernel_size=1, in_channels=channel, out_channels=channel // reduction))
        self.sa.add_module('bn_reduce1', nn.BatchNorm2d(channel // reduction))
        self.sa.add_module('relu_reduce1', nn.ReLU())
        for i in range(num_layers):
            self.sa.add_module('conv_%d' % i, nn.Conv2d(kernel_size=3, in_channels=channel // reduction,
                                                        out_channels=channel // reduction, padding=autopad(3, None, dia_val), dilation=dia_val))
            self.sa.add_module('bn_%d' % i, nn.BatchNorm2d(channel // reduction))
            self.sa.add_module('relu_%d' % i, nn.ReLU())
        self.sa.add_module('last_conv', nn.Conv2d(channel // reduction, 1, kernel_size=1))

    def forward(self, x):
        res = self.sa(x)
        res = res.expand_as(x)
        return res


class BAMBlock(nn.Module):
    def __init__(self, channel=512, reduction=16, dia_val=2):
        super().__init__()
        self.ca = ChannelAttention(channel=channel, reduction=reduction)
        self.sa = SpatialAttention(channel=channel, reduction=reduction, dia_val=dia_val)
        self.sigmoid = nn.Sigmoid()

    def init_weights(self):
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                init.kaiming_normal_(m.weight, mode='fan_out')
                if m.bias is not None:
                    init.constant_(m.bias, 0)
            elif isinstance(m, nn.BatchNorm2d):
                init.constant_(m.weight, 1)
                init.constant_(m.bias, 0)
            elif isinstance(m, nn.Linear):
                init.normal_(m.weight, std=0.001)
                if m.bias is not None:
                    init.constant_(m.bias, 0)

    def forward(self, x):
        b, c, _, _ = x.size()
        sa_out = self.sa(x)
        ca_out = self.ca(x)
        weight = self.sigmoid(sa_out + ca_out)
        out = (1 + weight) * x
        return out

《Large Selective Kernel Network for Remote Sensing Object Detection》

         LSKnet是一种用于遥感目标检测的大规模选择性核网络,改论文提出了远程感应目标检测新方法LSKNet,这种网络可以动态地调整其大的空间感受野,以更好地模拟远程感应场景中不同物体的范围上下文。文章中提到,这是首次在远程感应目标检测领域探索大型和选择性核机制。

class LSKblock(nn.Module):
    def __init__(self, dim):
        super().__init__()
        self.conv0 = nn.Conv2d(dim, dim, 5, padding=2, groups=dim)
        self.conv_spatial = nn.Conv2d(dim, dim, 7, stride=1, padding=9, groups=dim, dilation=3)
        self.conv1 = nn.Conv2d(dim, dim//2, 1)
        self.conv2 = nn.Conv2d(dim, dim//2, 1)
        self.conv_squeeze = nn.Conv2d(2, 2, 7, padding=3)
        self.conv = nn.Conv2d(dim//2, dim, 1)

    def forward(self, x):   
        attn1 = self.conv0(x)
        attn2 = self.conv_spatial(attn1)

        attn1 = self.conv1(attn1)
        attn2 = self.conv2(attn2)
        
        attn = torch.cat([attn1, attn2], dim=1)
        avg_attn = torch.mean(attn, dim=1, keepdim=True)
        max_attn, _ = torch.max(attn, dim=1, keepdim=True)
        agg = torch.cat([avg_attn, max_attn], dim=1)
        sig = self.conv_squeeze(agg).sigmoid()
        attn = attn1 * sig[:,0,:,:].unsqueeze(1) + attn2 * sig[:,1,:,:].unsqueeze(1)
        attn = self.conv(attn)
        return x * attn

 

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

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

相关文章

【机器学习300问】25、常见的模型评估指标有哪些?

模型除了从数据划分的角度来评估,我上一篇文章介绍了数据集划分的角度: 【机器学习300问】24、模型评估的常见方法有哪些?http://t.csdnimg.cn/LRyEt 还可以从一些指标的角度来评估,这篇文章就带大家从两个最经典的任务场景介绍…

天津公租房租金怎么算?附计算方式

天津公共租赁住房租金如何计算?附计算方法 天津市公共租赁住房租金租金标准建筑面积(100分-减分)。 公共租赁住房租金按照建筑面积计算。 应收租金以人民币计算,低于人民币的部分四舍五入。 具体内容见正文。 申请天津公共租赁住…

Go 与 Rust:导航编程语言景观

在当今构建软件时,开发者在编程语言上有着丰富的选择。两种脱颖而出的语言是 Go 和 Rust - 都很强大但却截然不同。本文将从各种因素比较这两种语言,以帮助您确定哪种更适合您的需求。 我们将权衡它们在并发、安全性、速度、互操作性等方面的方法。我们将…

软件系统开发流程规范

目的:规范系统开发流程,提高系统开发效率。 立项申请需求分析方案设计方案评审开发调整测试阶段系统培训试运行测试验收投入使用 所有文档过去进主页获取。

基于 STM32U5 片内温度传感器正确测算温度

目录预览 1、引言 2、问题 3、小结 01 引言 STM32 在内部都集成了一个温度传感器,STM32U5 也不例外。这个位于晶圆上的温度传感器虽然不太适合用来测量外部环境的温度,但是用于监控晶圆上的温度还是挺好的,以防止芯片过温运行。 02 问题…

MATLAB知识点:利用智能缩进整理代码

​讲解视频:可以在bilibili搜索《MATLAB教程新手入门篇——数学建模清风主讲》。​ MATLAB教程新手入门篇(数学建模清风主讲,适合零基础同学观看)_哔哩哔哩_bilibili 节选自​第4章:MATLAB程序流程控制 小技巧&#x…

LZO索引文件失效说明

在hive中创建lzo文件和索引时,进行查询时会出现问题.hive的默认输入格式是开启小文件合并的,会把索引也合并进来。所以要关闭hive小文件合并功能!

GIT概述及安装

文章目录 01.GIT概述内容小结 02.GIT相关概念(掌握)目标内容小结 03.GIT下载与安装目标内容 01.GIT概述 内容 Git是目前世界上最先进的分布式文件版本控制系统(没有之一) 版本控制 所谓的版本控制就是将一组文件的改动记录下来,形成版本历史…

2024年新提出的算法|LEA爱情进化算法(Love Evolution Algorithm)

Love Evolution Algorithm: a stimulus–value–role theory-inspired evolutionary algorithm for global optimization 爱情进化算法Love Evolution Algorithm,LEA,于2024年2月发表在中科院3区SCI期刊 The Journal of Supercomputing。 1、简介 本文提…

新 Logo 正式发布,Tubi 品牌全面升级!

作为新一代观众的首选流媒体平台,Tubi 持续扩大自身影响力,并于近日推出了富有活力的新品牌形象。 根据 Nielsen 的 The Gauge 报告,Tubi 在 2024 年 1 月的电视总观看份额提升至 1.5%,在年轻人和多元化观众群体中的吸引力持续上升…

SpringCloud(18)之Sleuth +Zipkin链路追踪

一、Zipkin介绍 Zipkin是一个开放源代码分布式的跟踪系统,它可以帮助收集服务的时间数据,以解决微服务架构中的延迟问 题,包括数据的收集、存储、查找和展现。每个服务向zipkin报告计时数据,zipkin会根据调用关系通 过Zipkin UI…

安泰ATA-M4功率放大器在变压器老化中的应用研究

变压器是电力系统中不可或缺的元件,用于升降电压,以实现电能的传输和分配。然而,变压器在长期运行中会受到各种环境和电力因素的影响,导致老化和损耗。变压器老化问题对电力系统的可靠性和稳定性构成威胁。因此,为了确…

机器学习笔记 YOLOv9模型相关论文简读

一、YOLOv9简述 自 2015 年 Yolov1 推出以来,已经出现了多个版本。 基于Darknet的YOLOv2、YOLOv3和YOLOv4 YOLOv5 YOLOv8 基于 Ultralytics。 SCALED-YOLOv4 使用 Pytorch 而不是 Darknet。 YOLOR是YOLOv4的改进。 YOLOX是YOLOv3的改进。 YOLOv6专注于工业应用。 YOLOv7 来自 …

在线上传解压PHP文件代码,压缩/压缩(网站一键打包)支持密码登录

在线上传解压PHP文件代码,压缩/压缩(网站一键打包)支持密码登录 资源宝分享:www.httple.net 如果你没有主机控制面板这个是最好选择,不需要数据库,上传当控制面板使用,无需安装任何扩展,安全高,…

【Linux深入剖析】进程控制 | 进程程序替换--长篇深层次讨论

📙 作者简介 :RO-BERRY 📗 学习方向:致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 📒 日后方向 : 偏向于CPP开发以及大数据方向,欢迎各位关注,谢谢各位的支持 目录 1.进程创建1.1 fork函…

C#中什么是非托管代码?托管代码和非托管代码有什么区别

在C#中,托管代码和非托管代码是两种不同类型的代码,它们在内存管理和执行环境上有所不同。 托管代码(Managed Code): 托管代码是由.NET运行时(CLR,Common Language Runtime)管理和执…

【每日刷题】哈希-随想录2、3、4、5、8、LC49、LC128

随想录2、LC242 有效的字母异位词随想录3、LC349两个数组的交集 3. 随想录4、LC202 快乐数 给一个整数,计算该数字每一位数字的平方和。核心是先拿到每一位数字,怎么拿? int 2579 2579 / 10 257 … 9 257 10 25 … 7 25 / 10 2 … 5 2 …

期货开户坚持固定的盈利模式

1、超级操盘手比的往往不是技术,而是素质。成功的交易者有着一种与众不同的品质,他们拥有正确的思维方式,严谨的交易态度,强烈的自信心、果敢,和面对失败永不言败的精神,即使在系统最困难的时候&#xff0c…

python模型训练

目录 1、新建模型 train_model.py 2、运行模型 (1)首先会下载data文件库 (2)完成之后会开始训练模型(10次) 3、 训练好之后,进入命令集 4、输入命令:python -m tensorboard.ma…

解决Unable to load class ‘org.gradle.api.attributes.VerificationType‘

在使用AdnroidStudio开发过程中难免会遇到Unable to load class org.gradle.api.attributes.VerificationType报错,可以尝试清理缓存重启解决 打开 File-》Invalidate Caches... 重启AndroidStudio后,重新加载即可,但也不是百分百解决。