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

YOLOv5改进 | 添加CA注意力机制 + 增加预测层 + 更换损失函数之GIoU_第1张图片

前言: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:实际训练测试

YOLOv5改进 | 添加CA注意力机制 + 增加预测层 + 更换损失函数之GIoU_第2张图片

1.基础概念

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

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

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

 网络结构图:

YOLOv5改进 | 添加CA注意力机制 + 增加预测层 + 更换损失函数之GIoU_第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×80 160×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)

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

YOLOv5改进 | 添加CA注意力机制 + 增加预测层 + 更换损失函数之GIoU_第4张图片

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

YOLOv5改进 | 添加CA注意力机制 + 增加预测层 + 更换损失函数之GIoU_第5张图片

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

YOLOv5改进 | 添加CA注意力机制 + 增加预测层 + 更换损失函数之GIoU_第6张图片


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 。具体如下图所示:

YOLOv5改进 | 添加CA注意力机制 + 增加预测层 + 更换损失函数之GIoU_第7张图片

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

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

YOLOv5改进 | 添加CA注意力机制 + 增加预测层 + 更换损失函数之GIoU_第8张图片

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

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

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

YOLOv5改进 | 添加CA注意力机制 + 增加预测层 + 更换损失函数之GIoU_第9张图片

备注:层数从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行左右,具体如图所示:

YOLOv5改进 | 添加CA注意力机制 + 增加预测层 + 更换损失函数之GIoU_第10张图片

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

YOLOv5改进 | 添加CA注意力机制 + 增加预测层 + 更换损失函数之GIoU_第11张图片

说明:♨️♨️♨️

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

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

YOLOv5改进 | 添加CA注意力机制 + 增加预测层 + 更换损失函数之GIoU_第12张图片

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

步骤6:更改损失函数

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

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

YOLOv5改进 | 添加CA注意力机制 + 增加预测层 + 更换损失函数之GIoU_第13张图片

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

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

步骤7:修改默认参数

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

YOLOv5改进 | 添加CA注意力机制 + 增加预测层 + 更换损失函数之GIoU_第14张图片

步骤8:实际训练测试

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

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

YOLOv5改进 | 添加CA注意力机制 + 增加预测层 + 更换损失函数之GIoU_第15张图片

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

你可能感兴趣的:(YOLO算法:基础+进阶+改进,YOLO,目标检测,人工智能,机器学习,深度学习,神经网络,计算机视觉)