YOLOv5、YOLOv8改进:BoTNet Transformer

news2024/10/6 12:59:33

 

目录

1.简介

2.YOLOv5改进

2.1增加以下yolov5s_botnet.yaml文件

2.2common.py配置

2.3 yolo.py配置修改


1.简介

论文地址

 Paper

 本文提出的BoTNet是一种简单高效的网络,有效的将SA应用到多种视觉任务,如图像识别、目标检测、实例分割任务。通过将ResNet50中最后三个bottleneck模块的空间卷积替换为全局的SA操作,有效提升了基线模型在签署任务上的性能。

Section I
常用的CNN大多采用3x3的卷积核,鉴于卷积操作可以有效的不糊哦局部信息,但是对于一些视觉任务如目标检测、实例分割、关键点检测还需要建立长程依赖关系。比如实例分割中需要收集场景相关的信息才能学习物体之间的关系;那么为了吧局部信息聚合就需要堆叠多个卷积层。但基于non-local操作可以更有效,也不需要堆叠那么多层。
而建模长程依赖对NLP任务也十分重要,Self-Attention可以有效学习每一对实体之间的关联,基于SA组成的Transformer已经成为NLP的主流,如GPT和BERT。


SA应用于视觉的一种简便方法及时将卷积层替换为MHSA层,参见Fig 1。按照这种思路有两种改进方向,一是将Resnet中的卷积层替换为各种SA操作,比如SASA,AACN,SANet;二是将图像切分成互补重叠的patch然后送入堆叠的Transformer模块。

虽然看起来是两种不同类型的体系结构,但是事实并非如此。本文提出ResNet 模块中使用MHSA层可以看做是一种带有瓶颈结构的Transformer模块,只不过有细微的变化比如残差连接、归一化层的选择上。因此本文将带有MHSA层的ResNet模块称之为BoT模块,具体结构参见Fig3.
将注意力应用到视觉领域有以下挑战:
(1)图像一般比用于分类的图像更大,分类一般(224,224)就够了,用于目标检测和实例分割的图像分辨率更高。

(2)SA的计算是输入分辨率的平方项,因此对内存和算力有要求

为了克服以上挑战本文进行以下设计:

(1)使用卷积来高效学习低分辨率、抽象的特征

(2)使用SA来处理、聚合卷积提取到的特征

这种混合设计可以有效利用卷积和SA的优点,同通过卷积进行下采样可以有效处理较高分辨率的输入图像。

因此本文的提出一种简单的设计方案:将ResNet最后三个block替换为BoT模块,其余不做任何改动。再说明白点,只将ResNet最后三个3x3卷积替换为MHSA层。


只做这一小小的改动,就将COCO上目标检测精度提升了1.2%;并且BoTNet在结构上并没什么新颖之处因此本文相信这种简洁性使其可以作为一个值得进一步研究的backbone。
使用BoTNet做实例分割,效果也有显著提升,尤其对小物体有显著提升。



最后本文还对BoTNet进行了放缩,发现BoTNet在更小数据集上没有什么实质性提升,但在ImageNet上达到了84.7%的top-1精度;在TPU-V3硬件测试上比目前流行的EfficientNet块1.64倍。基于BoTNet展现的结果本文希望SA未来可以在视觉任务中广泛使用。

 

Section II Related Work
Fig 2总结了计算机视觉任务中的注意力,本节主要关注:

(1)Transformer vs BoTNet


(2)DETR vs BoTNet

 
(3)Bon-Local vs BoTNet

Fig 3中左侧是Transformer ,中间是本文定义的BoT模块,右侧就是ResNet Block中将卷积层替换为MHSA后的结果


Connection to the Transformer


正如标题提到的本文的关键是将ResNet中的block替换为MHSA层,但BoT的架构设计并不是本文的贡献,本文只是指出MHSA ResNet Bottleneck与Transformer之间的关系,从而能够提升对计算机视觉中SA的理解和设计。



除了在Fig 3中恒看出的区别,如残差连接还有一些区别如:




(1)归一化 Transformer使用的是LN而ResNet使用的是BN

(2)非线性 Transforemr在FFN层引入非线性,ResNet则在BoT中使用了3个非线性变换

(3)输出映射 Transformer中的MHSA包含一个输出投影而BoT中没有

(4)一般视觉任务常使用SGD Optimizer而Transformer通常使用Adam Optimizer

Connection to DETR


DETR是基于Transformer的目标检测框架,DETR和BoTNet都尝试使用SA来提升目标检测和实例分割的性能,不同之处在于DETR是在主干之外使用了SA模块,主要目的是为了避免使用RP和非极大值抑制;


BoTNet目的是为了提出一个主干框架直接进行目标检测和实例分割。实验结果显示BoTNet对小物体的检测提升效果明显,相信在未来可以解决DETR对小物体检测不佳的问题。



Connection to Non-Local Neural Nets




Non-Local Nets主要是将Transformer与非局部算法结合,比如在ResNet最后的1-2个stage中引入非局部模块,来提升实例分割、视频分类的效果,BoT是一种混合设计,同时使用了卷积核SA。




Fig 4展示了Non-Local层和SA层的区别:





(1)MHSA中包含多个头来进行Q,K,V的映射





(2)NL Block中通常包含一个通道缩放因子对通道进行缩放,因子通常设置为2,而MHSA中设置为4





(3)NL Block是作为一个额外的模块插入到ResNet Block中 但是BoTNet是直接替换

Section III Method
BoTNet的设计很简单,将ResNet的最后三个3x3卷积替换为MHSA,这样就实现了featuremap的全局计算。通常ResNet包含4个stage[c2,c3,c4,c5],每一个stage中堆叠不同的block,并且使用残差连接。




 
本文的目标就是使用将SA用于高分辨率的实例分割,因此最简单的方法就是在主干网路低分辨率特征图中加入注意力,即c5阶段,c5一般包含3个残差快,因此将这3个残差快替换为MHSA模块就组成了BoTNet。

Table 1展示了BoTNet的网络结构,Fig 4展示了MHSA的结构。涉及到步长卷积的操作在本文都替换为了池化操作。




 
Relative Position Encodings




 
近期研究表明相对位置编码更有效,因为考虑了不同位置特征之间的相对距离,从而能够有效的将不同内容之间的相对距离考虑进来,因此BoTNet使用的是2D相对位置编码。

2.YOLOv5改进

2.1增加以下yolov5s_botnet.yaml文件

# parameters
nc: 80  # number of classes
depth_multiple: 0.33  # model depth multiple
width_multiple: 0.50  # layer channel multiple

anchors:
  - [10,13, 16,30, 33,23]  # P3/8
  - [30,61, 62,45, 59,119]  # P4/16
  - [116,90, 156,198, 373,326]  # P5/32

# YOLOv5 backbone
backbone:
  # [from, number, module, args]               # [c=channels,module,kernlsize,strides]
  [[-1, 1, Conv, [64, 6, 2, 2]],   # 0-P1/2           [c=3,64*0.5=32,3]
   [-1, 1, Conv, [128, 3, 2]],  # 1-P2/4    
   [-1, 3, C3, [128]],                                
   [-1, 1, Conv, [256, 3, 2]],  # 3-P3/8            
   [-1, 6, C3, [256]],                         
   [-1, 1, Conv, [512, 3, 2]],  # 5-P4/16       
   [-1, 9, C3, [512]],                     
   [-1, 1, Conv, [1024, 3, 2]],  # 7-P5/32
   [-1, 1, SPPF, [1024,5]],
   [-1, 3, BoT3, [1024]],  # 9
  ]

# YOLOv5 head
head:
  [[-1, 1, Conv, [512, 1, 1]], 
   [-1, 1, nn.Upsample, [None, 2, 'nearest']],
   [[-1, 5], 1, Concat, [1]],  # cat backbone P4
   [-1, 3, C3, [512, False]],  # 13

   [-1, 1, Conv, [256, 1, 1]],
   [-1, 1, nn.Upsample, [None, 2, 'nearest']],
   [[-1, 3], 1, Concat, [1]],  # cat backbone P3
   [-1, 3, C3, [256, False]],  # 17 (P3/8-small)
  
   [-1, 1, Conv, [256, 3, 2]],
   [[-1, 14], 1, Concat, [1]],  # cat head P4
   [-1, 3, C3, [512, False]],  # 20 (P4/16-medium)       [256, 256, 1, False]  
 
   [-1, 1, Conv, [512, 3, 2]],                           #[256, 256, 3, 2] 
   [[-1, 10], 1, Concat, [1]],  # cat head P5
   [-1, 3, C3, [1024, False]],  # 23 (P5/32-large)       [512, 512, 1, False]
  
   [[17, 20, 23], 1, Detect, [nc, anchors]],  # Detect(P3, P4, P5)
  ]

2.2common.py配置

class MHSA(nn.Module):
    def __init__(self, n_dims, width=14, height=14, heads=4,pos_emb=False):
        super(MHSA, self).__init__()

        self.heads = heads
        self.query = nn.Conv2d(n_dims, n_dims, kernel_size=1)
        self.key = nn.Conv2d(n_dims, n_dims, kernel_size=1)
        self.value = nn.Conv2d(n_dims, n_dims, kernel_size=1)
        self.pos=pos_emb
        if self.pos :
            self.rel_h_weight = nn.Parameter(torch.randn([1, heads, (n_dims ) // heads, 1, int(height)]), requires_grad=True)
            self.rel_w_weight = nn.Parameter(torch.randn([1, heads, (n_dims )// heads, int(width), 1]), requires_grad=True)
        self.softmax = nn.Softmax(dim=-1)
     
    def forward(self, x):
        n_batch, C, width, height = x.size() 
        q = self.query(x).view(n_batch, self.heads, C // self.heads, -1)
        k = self.key(x).view(n_batch, self.heads, C // self.heads, -1)
        v = self.value(x).view(n_batch, self.heads, C // self.heads, -1)
        #print('q shape:{},k shape:{},v shape:{}'.format(q.shape,k.shape,v.shape))  #1,4,64,256
        content_content = torch.matmul(q.permute(0,1,3,2), k) #1,C,h*w,h*w
        # print("qkT=",content_content.shape)
        c1,c2,c3,c4=content_content.size()
        if self.pos:
       # print("old content_content shape",content_content.shape) #1,4,256,256
            content_position = (self.rel_h_weight + self.rel_w_weight).view(1, self.heads, C // self.heads, -1).permute(0,1,3,2)   #1,4,1024,64
           
            content_position = torch.matmul(content_position, q)# ([1, 4, 1024, 256])
            content_position=content_position if(content_content.shape==content_position.shape)else content_position[:,: , :c3,]
            assert(content_content.shape==content_position.shape)
        #print('new pos222-> shape:',content_position.shape)
       # print('new content222-> shape:',content_content.shape)
            energy = content_content + content_position
        else:
            energy=content_content
        attention = self.softmax(energy)
        out = torch.matmul(v, attention.permute(0,1,3,2)) #1,4,256,64
        out = out.view(n_batch, C, width, height)
        return out
class BottleneckTransformer(nn.Module):
    # Transformer bottleneck
    #expansion = 1

    def __init__(self, c1, c2, stride=1, heads=4, mhsa=True, resolution=None,expansion=1):
        super(BottleneckTransformer, self).__init__()
        c_=int(c2*expansion)
        self.cv1 = Conv(c1, c_, 1,1)
        #self.bn1 = nn.BatchNorm2d(c2)
        if not mhsa:
            self.cv2 = Conv(c_,c2, 3, 1)
        else:
            self.cv2 = nn.ModuleList()
            self.cv2.append(MHSA(c2, width=int(resolution[0]), height=int(resolution[1]), heads=heads))
            if stride == 2:
                self.cv2.append(nn.AvgPool2d(2, 2))
            self.cv2 = nn.Sequential(*self.cv2)
        self.shortcut = c1==c2 
        if stride != 1 or c1 != expansion*c2:
            self.shortcut = nn.Sequential(
                nn.Conv2d(c1, expansion*c2, kernel_size=1, stride=stride),
                nn.BatchNorm2d(expansion*c2)
            )
        self.fc1 = nn.Linear(c2, c2)     

    def forward(self, x):
        out=x + self.cv2(self.cv1(x)) if self.shortcut else self.cv2(self.cv1(x))
        return out
        
class BoT3(nn.Module):
    # CSP Bottleneck with 3 convolutions
    def __init__(self, c1, c2, n=1,e=0.5,e2=1,w=20,h=20):  # ch_in, ch_out, number, , expansion,w,h
        super(BoT3, self).__init__()
        c_ = int(c2*e)  # hidden channels
        self.cv1 = Conv(c1, c_, 1, 1)
        self.cv2 = Conv(c1, c_, 1, 1)
        self.cv3 = Conv(2 * c_, c2, 1)  # act=FReLU(c2)
        self.m = nn.Sequential(*[BottleneckTransformer(c_ ,c_, stride=1, heads=4,mhsa=True,resolution=(w,h),expansion=e2) for _ in range(n)])
        # self.m = nn.Sequential(*[CrossConv(c_, c_, 3, 1, g, 1.0, shortcut) for _ in range(n)])

    def forward(self, x):
        return self.cv3(torch.cat((self.m(self.cv1(x)), self.cv2(x)), dim=1)) 

2.3 yolo.py配置修改

然后找到./models/yolo.py文件下里的parse_model函数,将加入的模块名BoT3加入进去
在 models/yolo.py文件夹下

 

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

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

相关文章

(十九)大数据实战——Flume数据采集框架安装部署

前言 本节内容我们主要介绍一下大数据数据采集框架flume的安装部署,Flume 是一款流行的开源分布式系统,用于高效地采集、汇总和传输大规模数据。它主要用于处理大量产生的日志数据和事件流。Flume 支持从各种数据源(如日志文件、消息队列、数…

【C/C++】虚析构 | 抽象类

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; &#x1f525;c系列专栏&#xff1a;C/C零基础到精通 &#x1f525; 给大…

【核磁共振成像】并行采集MRI

目录 一、并行成像二、SENSE重建三、SMASH重建四、灵敏度校准五、AUTO-SMASH和VD-AUTO-SMASH六、GRAPPA重建七、SPACE RIP重建算法八、PILS重建算法九、PRUNO重建算法十、UNFOLD算法 一、并行成像 并行MR成像(pMRI):相位阵列接受线圈不但各有自己专用的接受通道&#xff0c;而且…

ChatGPT⼊门到精通(2):ChatGPT 能为我们做什么

⼀、雇佣免费的⼲活⼩弟 有了ChatGPT后&#xff0c;就好⽐你有了好⼏个帮你免费打⼯的「⼩弟」&#xff0c;他们可以帮你做很多 ⼯作。我简单总结⼀些我⽬前使⽤过的⽐较好的基于ChatGPT的服务和应⽤。 1、总结、分析 当我们在阅读⼀些⽂章和新闻的时候&#xff0c;有的⽂章写…

Redis-监听过期key-JAVA实现方案

一、创建监听配置类 RedisListenerConfig。 import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.d…

mysql与msql2数据驱动

mysql基本使用 数据库操作&#xff08;DDL&#xff09; -- 数据考操作 -- 1.查询所有数据库 SHOW DATABASES;-- 2.选择数据库 USE learn_mysql;-- 3.当前正在使用的数据库 SELECT DATABASE();-- 4.创建数据库 CREATE DATABASE IF NOT EXISTS learn_mysql;-- 5.删除数据库 DRO…

贸易行业:财务信息化流程优化解决方案

一、整体架构图 1.1 价值分析 SAP财务流程优化V2.0版本 ——建立跨部门协作的“信息流”桥梁 &#xff0c;优化SAP与异构系统之间的数据交换 &#xff0c;信息传递由人工整理到EXCEL 到 系统导出 标准化EXCEL &#xff0c;提升作业人员数据整理、搬运的工作&#xff0c;提高…

二级MySQL(十)——单表查询

这里我们只在一个表内查询&#xff0c;用到的是较为简单的SELECT函数形式 1、查询指定的字段&#xff1a; 用到的数据库是之前提到的S、P、SP数据库 S表格用到的总数据&#xff1a; 首先我们查询所有供应商的序号和名字 这时都是独立的&#xff0c;没有关系&#xff0c;我们找…

pm2部署nuxt3项目

pm2部署nuxt3项目 阅读时长&#xff1a;8分钟 本文内容&#xff1a;本文其实前面开发AI数字人网站的延续。 window上安装ubuntu虚拟机&#xff0c;并在虚拟机中使用pm2部署 Nuxt3 项目. Nuxt3Vitetypescriptpm2 1. 安装node环境 下载 # 进入node目录 cd /node # 下载 wget h…

input时间表单默认样式修改(input[type=“date“])

一、时间选择的种类: HTML代码&#xff1a; <input type"date" value"2018-11-15" />选择日期&#xff1a; 选择时间&#xff1a; <input type"time" value"22:52" />在这里插入图片描述 选择星期&#xff1a; <…

POSTGRESQL WAL 日志问题合集之WAL 如何解析

开头还是介绍一下群&#xff0c;如果感兴趣polardb ,mongodb ,mysql ,postgresql ,redis 等有问题&#xff0c;有需求都可以加群群内有各大数据库行业大咖&#xff0c;CTO&#xff0c;可以解决你的问题。加群请加 liuaustin3微信号 &#xff0c;在新加的朋友会分到3群 &#xf…

Python实战之数据表提取和下载自动化

在网络爬虫领域&#xff0c;动态渲染类型页面的数据提取和下载自动化是一个常见的挑战。本文将介绍如何利用Pyppeteer库完成这一任务&#xff0c;帮助您轻松地提取动态渲染页面中的数据表并实现下载自动化。 一、环境准备 首先&#xff0c;确保您已经安装了Python环境。接下来…

uniapp 支持图片放大

<view class"list" v-for"(item, index) in urls" :key"index"><image :src"item" click"viewImg(item, index)" disabled></image></view> js // 预览大图 viewImg(data, index) {uni.previewImag…

《游戏编程模式》学习笔记(九)游戏循环 Sequencing Patterns

定义 一个游戏循环会在游玩时不断运行。 每一次循环&#xff0c;它都会无阻塞地处理玩家的输入&#xff0c;更新游戏的状态&#xff0c;渲染游戏。它追踪时间的消耗并控制游戏的速度。游戏循环需要做到始终以固定的速度运行游戏。 一个游戏循环中通常包含处理输入部分&#xf…

01-基础例程1

基础例程1 01-LED /* 深圳市普中科技有限公司&#xff08;PRECHIN 普中&#xff09;技术支持&#xff1a;www.prechin.net* 实验名称&#xff1a;LED流水灯实验* 接线说明&#xff1a;LED模块-->ESP32 IO* (D1-D8)-->(15,2,0,4,16,17,5,18)* * 实验现象&#x…

stm32----SPI协议

一、概述 SPI&#xff08;Serial Peripheral Interface&#xff0c;串行外围设备接口&#xff09;&#xff0c;是Motorola公司提出的一种同步串行接口技术&#xff0c;是一种高速、全双工、同步通信总线&#xff0c;在芯片中只占用四根管脚用来控制及数据传输&#xff0c;节约…

jmeter性能测试入门完整版

1. Jmeter简介 Apache JMeter是一款纯java编写负载功能测试和性能测试开源工具软件。相比Loadrunner而言&#xff0c;JMeter小巧轻便且免费&#xff0c;逐渐成为了主流的性能测试工具&#xff0c;是每个测试人员都必须要掌握的工具之一。 本文为JMeter性能测试完整入门篇&…

IT项目标准实施流程

一、IT项目标准实施流程、参与角色与职责架构图 二、IT项目阶段交付文档明细目录 NO. 阶段 中文名称 英文名称 缩写 是否必须 1 1.分析 1.1 项目业务需求分析文档 Business Requirement analysis Document BRD X 2 2.设计 2.1 硬件&软件配置清单 Bill Of Ma…

Excel:如何实现分组内的升序和降序?

一、POWER 1、构建辅助列D列&#xff0c;在D2单元格输入公式&#xff1a; -POWER(10,COUNTA($A$2:A2)3)C2 2、选中B1:D10&#xff0c;注意不能宣导A列的合并单元格&#xff0c;进行以下操作&#xff1a; 3、删除辅助列即可 二、COUNTA 第一步&#xff0c;D2建立辅助列&#xf…

6.Redis-hash

hash 哈希类型中的映射关系通常称为field-value&#xff0c;⽤于区分 Redis 整体的键值对&#xff08;key-value&#xff09;&#xff0c;注意这⾥的value是指field对应的值&#xff0c;不是键&#xff08;key&#xff09;对应的值&#xff0c;请注意 value 在不同上下⽂的作⽤…