YOLOv5改进 | 添加CA注意力机制 + 增加预测层 + 更换损失函数之GIoU

前言:Hello大家好,我是小哥谈。在小目标场景的检测中,存在远距离目标识别效果差的情形,本节课提出一种基于改进YOLOv5的小目标检测方法。首先,在YOLOv5s模型的Neck网络层融合坐标注意力机制,以提升模型的特征提取能力;其次,增加一个预测层来提升对小目标的检测性能;进一步地,利用K-means聚类算法得到数据集合适的anchor框;最后,改进边界框回归损失函数以提高边界框的定位精度。经过试验表明,改进后的模型可以有效检测出远距离小目标,改进了漏报误报等情况,比原始YOLOv5s模型的平均精度均值(IOU=0.5)提升明显,模型在小目标场景下具有较强的泛化能力。🌈 

     目录

🚀1.基础概念

🚀2.改进思想

🚀3.添加位置

🚀4.添加步骤

🚀5.改进方法

💥💥步骤1:common.py文件修改

💥💥步骤2:yolo.py文件修改

💥💥步骤3:创建自定义yaml文件

💥💥步骤4:修改自定义yaml文件

💥💥步骤5:验证是否加入成功

💥💥步骤6:更改损失函数

💥💥步骤7:修改默认参数

💥💥步骤8:实际训练测试

🚀1.基础概念

YOLOv5主要有n、s、m、l、x 五种不同深度和宽度的网络模型,随着网络深度和宽度增加,检测速度越来越慢,考虑在实际场景应用时需要处理海量的视频,对实时性有较高要求,本次针对YOLOv5的改进就采用YOLOv5s模型作为基础模型。

YOLOv5s网络结构如下图所示,主要由4个模块组成:输入端主干网络Neck网络预测端

  • 输入端用于输入原始图像,并利用数据增强方法对输入图像进行随机缩放、裁剪、 排布;
  • 主干网络进行特征提取,主要包括CONV、C3 和 SPPF等;
  • Neck 网络实现图像特征融合,采用FPN+PAN结构,两种结构网络的结合对不同层特征进行融合,加强了特征信息;
  • 预测端输出3个尺度的特征图,用于预测大、中、小目标

 网络结构图:

说明:本文的改进是基于YOLOv5-6.0版本,其他版本的改进可自行试验,原理步骤一致。


🚀2.改进思想

小目标场景的检测中,存在远距离目标识别效果差的情形,本节课提出一种基于改进YOLOv5的小目标检测方法。首先,在YOLOv5s模型的Neck网络层融合坐标注意力机制,以提升模型的特征提取能力;其次,增加一个预测层来提升对小目标的检测性能;进一步地,利用K-means聚类算法得到数据集合适的anchor框;最后,改进边界框回归损失函数以提高边界框的定位精度。经过试验表明,改进后的模型可以有效检测出远距离小目标,改进了漏报误报等情况,比原始YOLOv5s模型的平均精度均值(IOU=0.5)提升明显,模型在小目标场景下具有较强的泛化能力。

总结:添加注意力机制 + 添加预测层 + 改进损失函数

针对本文所提出的改进,选择CA注意力机制和GIoU损失函数。分别介绍如下:

CA注意力机制:

CA(Channel Attention)注意力机制是一种用于计算机视觉任务的注意力机制,它可以通过学习通道之间的关系来提高模型的性能。CA注意力机制的基本思想是,对于给定的输入特征图,通过学习通道之间的关系来计算每个通道的权重,然后将这些权重应用于输入特征图中的每个像素点,以产生加权特征图。

具体来说,CA注意力机制包括两个步骤通道特征提取通道注意力计算。在通道特征提取阶段,我们使用一个全局平均池化层来计算每个通道的平均值和最大值,然后将它们连接起来并通过一个全连接层来产生通道特征。在通道注意力计算阶段,我们使用一个sigmoid函数来将通道特征映射到[0,1]范围内,并将其应用于输入特征图中的每个像素点,以产生加权特征图。

加入CA注意力机制的好处包括:

 (1)增强特征表达:CA注意力机制能够自适应地选择和调整不同通道的特征权重,从而更好地表达输入数据。它可以帮助模型发现和利用输入数据中重要的通道信息,提高特征的判别能力和区分性。

 (2)减少冗余信息:通过抑制不重要的通道,CA注意力机制可以减少输入数据中的冗余信息,提高模型对关键特征的关注度。这有助于降低模型的计算复杂度,并提高模型的泛化能力。

 (3)提升模型性能:加入CA注意力机制可以显著提高模型在多通道输入数据上的性能。它能够帮助模型更好地捕捉到通道之间的相关性和依赖关系,从而提高模型对输入数据的理解能力。

所以,加入CA注意力机制可以有效地增强模型对多通道输入数据的建模能力,提高模型性能和泛化能力。它在图像处理、视频分析等任务中具有重要的应用价值。

GIoU损失函数:

GIoU(Generalized Intersection over Union)是一种目标检测中常用的损失函数,它可以用来衡量预测框真实框之间的重叠程度。相比于传统的IoU损失函数,GIoU损失函数考虑了预测框和真实框之间的距离,因此更加准确。

关于更多YOLOv5基础知识及改进方法,可参考专栏:《YOLOv5:从入门到实战》


🚀3.添加位置

YOLOv5s (6.0 版本) 模型只有3个预测层,当将尺寸为640×640的图像输入网络时,Neck网络分别进行8倍16 倍32 倍下采样,对应的预测层特征图尺寸为80×8040×4020×20,分别用来检测小目标中目标大目标。为提升远距离小目标的识别准确率,在YOLOv5s原始网络上增加一个预测层。预测层增加的位置如下所示,在Neck网络中增加1次上 采样,第3次上采样后,与主干网络第2层融合,得到新增加的160×160的预测层,用以检测小目标。整个模型改进后采用4个预测尺度的预测层,将底层特征高分辨率和深层特征高语义信息充分利用,并且未显著增加网络复杂度。

原始YOLOv5s三个检测层,聚类anchor框数量为9,加入1个预测层后,聚类得到12个anchor 框,将anchor框按照特征图检测尺度分配,如下表所示:

特征图20×20

40×40

80×80160×160
感受野较小
锚框(116,90)(156,198)(373,326)(30,61)(62,45)(59,119)(10,13)(16,30)(33,23)(5,7)(9,13)(11,15)

本节课针对预测层的添加位置如下所示:

本文针对CA注意力机制的添加位置如下所示:

所以,改进后总的网络结构图如下所示:


🚀4.添加步骤

针对本文的改进,具体步骤如下所示:👇

步骤1:common.py文件修改

步骤2:yolo.py文件修改

步骤3:创建自定义yaml文件

步骤4:修改自定义yaml文件

步骤5:验证是否加入成功

步骤6:更改损失函数

步骤7:修改默认参数

步骤8:实际训练测试


🚀5.改进方法

💥💥步骤1:common.py文件修改

common.py中添加CA注意力机制模块,所要添加模块的代码如下所示,将其复制粘贴到common.py文件末尾的位置。

CA注意力机制模块代码:

# CA
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()
        #c*1*W
        x_h = self.pool_h(x)
        #c*H*1
        #C*1*h
        x_w = self.pool_w(x).permute(0, 1, 3, 2)
        y = torch.cat([x_h, x_w], dim=2)
        #C*1*(h+w)
        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

💥💥步骤2:yolo.py文件修改

首先在yolo.py文件中找到parse_model函数这一行,加入CoordAtt 。具体如下图所示:

💥💥步骤3:创建自定义yaml文件

models文件夹中复制yolov5s.yaml,粘贴并重命名为yolov5s_CA_SmallTarget.yaml。具体如下图所示:

💥💥步骤4:修改自定义yaml文件

本步骤是修改yolov5s_CA_SmallTarget.yaml,根据改进后的网络结构图进行修改。

由下面这张图可知,当添加CA注意力机制 + 增加预测层之后,后面的层数会发生相应的变化,需要修改相关参数。

备注:层数从0开始计算,比如第0层、第1层、第2层......🍉 🍓 🍑 🍈 🍌 🍐  

综上所述,修改后的完整yaml文件如下所示:

# YOLOv5 🚀 by Ultralytics, GPL-3.0 license

# Parameters
nc: 80  # number of classes
depth_multiple: 0.33  # model depth multiple
width_multiple: 0.50  # layer channel multiple
anchors:
  - [5,7, 9,13, 11,15]     #P2/4,增加的anchor
  - [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 v6.0 backbone
backbone:
  # [from, number, module, args]
  [[-1, 1, Conv, [64, 6, 2, 2]],  # 0
   [-1, 1, Conv, [128, 3, 2]],    # 1
   [-1, 3, C3, [128]],            # 2
   [-1, 1, Conv, [256, 3, 2]],    # 3
   [-1, 6, C3, [256]],            # 4
   [-1, 1, Conv, [512, 3, 2]],    # 5
   [-1, 9, C3, [512]],            # 6
   [-1, 1, Conv, [1024, 3, 2]],   # 7
   [-1, 3, C3, [1024]],           # 8
   [-1, 1, SPPF, [1024, 5]],      # 9
  ]

# YOLOv5 v6.0 head
head:
  [ [ -1, 1, Conv, [ 512, 1, 1 ] ],  #10
    [ -1, 1, nn.Upsample, [ None, 2, 'nearest' ] ], #11
    [ [ -1, 6 ], 1, Concat, [ 1 ] ],   #12
    [ -1, 3, C3, [ 512, False ] ],     #13

    [ -1, 1, Conv, [ 256, 1, 1 ] ],    #14
    [ -1, 1, nn.Upsample, [ None, 2, 'nearest' ] ], #15
    [ [ -1, 4 ], 1, Concat, [ 1 ] ],    #16

    [ -1, 3, C3, [ 256, False ] ],       #17
    [ -1, 1, Conv, [ 128, 1, 1 ] ],      #18
    [ -1, 1, nn.Upsample, [ None, 2, 'nearest' ] ],   #19
    [ [ -1, 2 ], 1, Concat, [ 1 ] ],     #20
    [ -1, 3, C3, [ 128, False ] ],       #21

    [ -1, 1, Conv, [ 128, 3, 2 ] ],      #22
    [ [ -1, 18 ], 1, Concat, [ 1 ] ],    #23
    [ -1, 3, C3, [ 256, False ] ],       #24
    [ -1, 1, CoordAtt,[256]],                #25
    [ -1, 1, Conv, [ 256, 3, 2 ] ],      #26
    [ [ -1, 14 ], 1, Concat, [ 1 ] ],    #27

    [ -1, 3, C3, [ 512, False ] ],       #28
    [ -1, 1, CoordAtt,[512]],                #29
    [ -1, 1, Conv, [ 512, 3, 2 ] ],      #30
    [ [ -1, 10 ], 1, Concat, [ 1 ] ],    #31
    [ -1, 3, C3, [ 1024, False ] ],      #32
    [ -1, 1, CoordAtt,[1024]],               #33
    [ [ 21, 25, 29, 33 ], 1, Detect, [ nc, anchors ] ],  # 四个检测头,增加的为21
  ]

💥💥步骤5:验证是否加入成功

yolo.py文件里,将配置改为我们刚才自定义的yolov5s_CA_SmallTarget.yaml

修改1,位置位于yolo.py文件165行左右,具体如图所示:

修改2,位置位于yolo.py文件363行左右,具体如下图所示:

说明:♨️♨️♨️

需要根据自定义的yaml文件名进行配置。

配置完毕之后,点击“运行”,结果如下图所示:

由运行结果可知,与我们前面更改后的网络结构图相一致,证明添加成功了!✅

💥💥步骤6:更改损失函数

本文需要更改损失函数为GIoU。

通常用utils / loss.py文件下的__call__函数计算回归损失(bbox损失),具体如下图所示:

将画红框这一行改为下列代码即可:

iou = bbox_iou(pbox, tbox[i], GIoU=True).squeeze()  # iou(prediction, target)

💥💥步骤7:修改默认参数

train.py文件中找到parse_opt函数,然后将第二行 '--cfg的default改为 'models/yolov5s_CA_SmallTarget.yaml ',然后就可以开始进行训练了。🎈🎈🎈 

💥💥步骤8:实际训练测试

步骤7中,parse_opt函数中的参数'--weights'采用的是yolov5s.pt,'--data'所采用的是helmet.yaml(作者提前创建的安全帽佩戴检测地址及分类信息,同学可自定义),然后设置'--epochs'为100轮

相关参数设置完毕后,点击运行train.py文件,没有发生报错,模型正常训练,具体如下图所示:👇

结束语:同学们有任何问题,请在评论区给出,我看到了会及时回复~!🍉 🍓 🍑 🍈 🍌 🍐

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

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

相关文章

Linux离线安装cuda以及配置其环境

cuda安装 cuda版本适配 查看自己电脑所支持的cuda版本号 【若安装超算平台上的cuda toolkit这一步骤可以跳过】 CUDA toolkit Download官网下载cuda toolkit 下载好的.run可执行文件上传到平台进行离线安装 $ cd /上传的目录 $ chmod x cuda_12.2.2_535.104.05_linux.run /…

C++进阶-STL stack容器的简单认识

STL stack容器的简单认识 stack基本概念stack常用接口构造函数赋值操作数据存取大小操作 stack基本概念 stack是一种 先进后出 (First In Last out, FILO)的数据结构,它只有一个出口 栈只有顶端的元素才可以被外界使用,因此栈不允许有遍历行为 栈中进…

golang工程组件——redigo使用(redis协议,基本命令,管道,事务,发布订阅,stream)

redisgo redis 与 client 之间采用请求回应模式,一个请求包对应一个回应包;但是也有例外,pub/sub 模 式下,client 发送 subscribe 命令并收到回应包后,之后被动接收 redis 的发布包;所以若需要使 用 pub/s…

基于php js+mysql+laravel技术架构的手术麻醉管理系统源码 手麻系统源码

PHP手术麻醉管理系统源码 手麻系统源码 手术麻醉管理系统定义: 手术麻醉系统主要是由麻醉信息管理和监护设备数据采集系统两个部分组成,主要是将麻醉信息和从监护仪器上采集到的数据以及手术信息进行统计。 手术麻醉系统是指专用于住院患者手术与麻醉…

VueCli 自定义创建项目及配置

一、VueCli 自定义创建项目 1.安装脚手架 (已安装) npm i vue/cli -g2.创建项目 vue create hm-exp-mobile选项 Vue CLI v5.0.8 ? Please pick a preset:Default ([Vue 3] babel, eslint)Default ([Vue 2] babel, eslint) > Manually select features 选自定义手动…

【我悟了】异常断电导致的文件系统变为只读——案例分析

背景 应领导要求,临时支持其他项目上遇到的一个问题。由于该问题属于未涉及的知识领域,从接触到最终给出方案,也花了我不少精力。在此进行分享,主要介绍在面对不熟悉的问题领域时,分析问题的思路。希望能够给年轻的同学…

观点|周鸿祎:大模型真正的竞争在于使其与用户场景相结合

【网易科技11月9日报道】目前,人工智能技术尚未达到向手机一样的刚性、高频需求,各国和企业都在加大研发和应用力度,探索不同的技术路线和商业模式。 360集团创始人、董事长周鸿祎在2023世界互联网大会乌镇峰会上表示,目前人工智能…

AI批量剪辑矩阵托管系统----源码技术开发

AI批量剪辑矩阵托管系统----源码技术开发 抖音账号矩阵系统是基于抖音开放平台研发的用于管理和运营多个抖音账号的平台。它可以帮助用户管理账号、发布内容、营销推广、分析数据等多项任务,从而提高账号的曝光度和影响力。 具体来说,抖音账号矩阵系统可…

混沌系统在图像加密中的应用(基于哈密顿能量函数的混沌系统构造1.2)

混沌系统在图像加密中的应用(基于哈密顿能量函数的混沌系统构造1.2) 前言基于广义哈密顿系统的一类混沌系统构造1.基本动力学特性分析2.数值分析 总结python代码 前言 续接混沌系统在图像加密中的应用(基于哈密顿能量函数的混沌系统构造1.1&…

RT-Thread Env使用

Env用户手册 Env是RT-Thread推出的开发辅助工具,针对基于RT-Thread操作系统的项目工程,提供编译构建环境、图形化系统配置及软件包管理功能。 其内置的menuconfig提供了简单易用的配置裁剪工具,可对内核、组件和软件包进行自由裁剪&#xf…

运动耳机推荐,运动耳机哪个牌子好性价比高?哪个运动耳机好?

​无论你是喜欢户外跑步,还是喜欢室内健身,运动耳机都能为你提供强大的音乐动力,帮助你更好地享受运动的过程,边流汗边听歌太畅快了!因此。想了解哪个品牌的运动耳机更适合自己,就来看看我发布的这篇文章吧…

DevOps平台两种实现模式

我们需要一个DevOps平台 要讨论DevOps平台的实现模式,似乎就必须讨论它们的概念定义。然而,当大家要讨论它们的定义时,就像在讨论薛定谔的猫。 A公司认为它不过是自动化执行Shell脚本的平台,有些人认为它是一场运动,另…

4种最常用的LLM应用文本分块策略

在构建 LLM 应用程序时,分块(Chunking)是将大块文本分解成更小的片段的过程。 这是一项重要的技术,一旦我们使用LLM嵌入内容,它有助于优化我们从矢量数据库返回的内容的相关性。 在这篇博文中,我们将探讨它…

2023美团外卖商超药店月销量

数据包含:外卖商超、药店商品月销量、含商品skuid、规格spuid等内容 资源下载 ​​​​​​​https://download.csdn.net/download/WANJIAWEN1002/88444367?spm1001.2014.3001.5503

什么是网络中的服务质量 (QoS)?

什么是服务质量(QoS) 服务质量(QoS)是网络中用于管理质量并确定数据流量传输优先级的机制。它确保不同类型的数据流量,如语音、视频和数据,获得适当的服务水平。其主要目标是使网络和组织能够对流量进行优…

新发布的Java使用率均超Java8

Java 软件供应商 Azul 发布了首份年度 Java 现状调查报告,基于对全球 2062 名 Java 专业人士和基于 Java 的应用程序用户进行的调查。 Java 软件供应商 Azul 发布了首份年度 Java 现状调查报告,基于对全球 2062 名 Java 专业人士和基于 Java 的应用程序…

java命令行中文乱码原理和解决方式

今天发现用命令行javac编译文件时,若文件里有中文的话,可能会因为“源文件和javac编译使用的编码方式不同”导致乱码的产生,一般我的源文件用的是utf-8编码,但今天查资料发现javac默认使用系统的GBK编码方式,会出现乱码…

Error: “+“ and “-“ must be surrounded by whitespace in calculations.

加减之前一定要空格 改之前: 改之后: 然后就完美解决啦

Versal 自适应 SoC SelectMAP 启动检查表

Versal 自适应 SoC SelectMAP 启动检查表 本文档提供了有关 SelectMAP 启动设置的技巧和指南。在提交个案服务请求之前,应认真查看以下检查表。SelectMAP 启动模式的常规检查表: 是否已查看 SelectMAP 文档,了解连接和电源轨的用法&#…

vivado时序分析-3时序分析关键概念

1、时钟相移 时钟相移对应于延迟时钟波形 , 此波形与因时钟路径内的特殊硬件所导致的参考时钟相关。在 AMD FPGA 中 , 时钟相移通常是由 MMCM 或 PLL 原语引入的 , 前提是这些原语的输出时钟属性 CLKOUT*_PHASE 为非零值。 时序分析期间…