优化改进YOLOv5算法之添加SE、CBAM、CA模块(超详细)

news2024/12/27 13:56:35

目录

1 SENet

1.1 SENet原理

1.2 SENet代码(Pytorch)

1.3 YOLOv5中加入SE模块 

1.3.1 common.py配置

1.3.2 yolo.py配置

1.3.3 创建添加RepVGG模块的YOLOv5的yaml配置文件

2 CBAM

2.1 CBAM原理

2.2 CBAM代码(Pytorch)

2.3 YOLOv5中加入CBAM模块 

2.3.1 common.py配置

2.3.2 yolo.py配置

2.3.3 创建添加CBAM模块的YOLOv5的yaml配置文件

 3 CA

3.1 CA原理

3.2 CA代码(Pytorch)

3.3 YOLOv5中加入CA模块 

3.3.1 common.py配置

3.3.2 yolo.py配置

3.3.3 创建添加CA模块的YOLOv5的yaml配置文件

 4、实验效果对比

4.1 口罩检测数据集

4.2 效果对比

参考文章


在前面的文章中已经详细介绍了在本机上安装YOLOv5的教程,安装YOLOv5可参考前面的文章YOLOv5训练自己的数据集(超详细)https://blog.csdn.net/qq_40716944/article/details/118188085

1 SENet

论文名称:Squeeze-and-Excitation Networks

论文链接:https://arxiv.org/pdf/1709.01507.pdf

论文代码: GitHub - hujie-frank/SENet: Squeeze-and-Excitation Networks

1.1 SENet原理

对于卷积操作,很大一部分工作是提高感受野,即空间上融合更多特征融合,或者是提取多尺度空间信息,如Inception网络的多分支结构。对于channel维度的特征融合,卷积操作基本上默认对输入特征图的所有channel进行融合。而MobileNet网络中的组卷积(Group Convolution)和深度可分离卷积(Depthwise Separable Convolution)对channel进行分组也主要是为了使模型更加轻量级,减少计算量。而SENet网络的创新点在于关注channel之间的关系,希望模型可以自动学习到不同channel特征的重要程度。为此,SENet提出了Squeeze-and-Excitation (SE)模块,如图1所示。

图1 SEBlock结构图

SE模块首先对卷积得到的特征图进行Squeeze操作,得到channel级的全局特征,然后对全局特征进行Excitation操作,学习各个channel间的关系,也得到不同channel的权重,最后乘以原来的特征图得到最终特征。本质上,SE模块是在channel维度上做attention或者gating操作,这种注意力机制让模型可以更加关注信息量最大的channel特征,而抑制那些不重要的channel特征。另外一点是SE模块是通用的,这意味着其可以嵌入到现有的网络架构中。

为了更好的对SENet的核心原理进行放分析,可以将SENet分成4个步骤进行理解,如图2所示。

 图2 SEBlock模块分析图

  • 从单张图像开始,提取图像特征,当前特征层U的特征图维度为[C,H,W]。
  • 对特征图的[ H , W ]维度进行平均池化或最大池化,池化过后的特征图大小从[ C , H , W ] ->[ C , 1 , 1 ]。[ C , 1 , 1 ] 可理解为对于每一个通道C,都有一个数字和其一一对应。图3对应了步骤(2)的具体操作。

图3 平均池化(最大池化)操作,得到每个通道的权重,得到每个通道的权重 

  • 对[ C , 1 , 1 ]的特征可以理解为,从每个通道本身提取出来的权重,权重表示了每个通道对特征提取的影响力,全局池化后的向量通过MLP网络后,其意义为得到了每个通道的权重。图4对应了步骤(3)的具体操作。
     

图4 通道权重生成 

  • 上述步骤,得到了每个通道C的权重[ C , 1 , 1 ],将权重作用于特征图U[ C , H , W ],即每个通道各自乘以各自的权重。可以理解为,当权重大时,该通道特征图的数值相应的增大,对最终输出的影响也会变大;当权重小时,该通道特征图的数值就会更小,对最终输出的影响也会变小。图5对应了步骤(4)的具体操作。
     

图5 通道注意力——各通道乘以各自不同权重 

1.2 SENet代码(Pytorch)

class SEAttention(nn.Module):

    def __init__(self, channel=512, reduction=16):
        super().__init__()
        self.avg_pool = nn.AdaptiveAvgPool2d(1)
        self.fc = nn.Sequential(
            nn.Linear(channel, channel // reduction, bias=False),
            nn.ReLU(inplace=True),
            nn.Linear(channel // reduction, channel, bias=False),
            nn.Sigmoid()
        )

    def forward(self, x):
        b, c, _, _ = x.size()
        y = self.avg_pool(x).view(b, c)
        y = self.fc(y).view(b, c, 1, 1)
        return x * y.expand_as(x)

1.3 YOLOv5中加入SE模块 

1.3.1 common.py配置

在yolov5-6.1/models/common.py文件中增加以下模块,直接复制即可。

class SEAttention(nn.Module):

    def __init__(self, channel=512, reduction=16):
        super().__init__()
        self.avg_pool = nn.AdaptiveAvgPool2d(1)
        self.fc = nn.Sequential(
            nn.Linear(channel, channel // reduction, bias=False),
            nn.ReLU(inplace=True),
            nn.Linear(channel // reduction, channel, bias=False),
            nn.Sigmoid()
        )

    def forward(self, x):
        b, c, _, _ = x.size()
        y = self.avg_pool(x).view(b, c)
        y = self.fc(y).view(b, c, 1, 1)
        return x * y.expand_as(x)

1.3.2 yolo.py配置

然后找到yolov5-6.1/models//yolo.py文件下里的parse_model函数,将类名加入进去,如下所示。

1.3.3 创建添加RepVGG模块的YOLOv5的yaml配置文件

完成上述两步操作之后,就可以在原有的YOLOv5的yaml配置文件的基础上进行修改,在适当位置添加RepVGG模块或者利用RepVGG模块替换原始yaml配置文件中的一些模块,这里为了能够快速的训练模型,选择YOLOv5s模型进行修改,修改后的yolov5s_se.yaml文件内容如下所示。

# YOLOv5 🚀 by YOLOAir, GPL-3.0 license

# Parameters
nc: 2  # 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 v6.0 backbone
backbone:
  # [from, number, module, args]
  [[-1, 1, Conv, [64, 6, 2, 2]],  # 0-P1/2
   [-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, 3, C3, [1024]],
   [-1, 1, SPPF, [1024, 5]],  # 9
  ]

# YOLOv5 v6.0 head
head:
  [[-1, 1, Conv, [512, 1, 1]],
   [-1, 1, nn.Upsample, [None, 2, 'nearest']],
   [[-1, 6], 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, 4], 1, Concat, [1]],  # cat backbone P3
   [-1, 3, C3, [256, False]],  # 17 (P3/8-small)
   [-1, 1, SEAttention, [256]],

   [-1, 1, Conv, [256, 3, 2]],
   [[-1, 14], 1, Concat, [1]],  # cat head P4
   [-1, 3, C3, [512, False]],  # 20 (P4/16-medium)
   [-1, 1, SEAttention, [512]],

   [-1, 1, Conv, [512, 3, 2]],
   [[-1, 10], 1, Concat, [1]],  # cat head P5
   [-1, 3, C3, [1024, False]],  # 23 (P5/32-large)
   [-1, 1, SEAttention, [1024]],

   [[18, 21, 24], 1, Detect, [nc, anchors]],  # Detect(P3, P4, P5)
  ]

2 CBAM

论文名称:CBAM: Convolutional Block Attention Module

论文链接:https://arxiv.org/pdf/1807.06521.pdf

论文代码: GitHub - luuuyi/CBAM.PyTorch: Non-official implement of Paper:CBAM: Convolutional Block Attention Module

2.1 CBAM原理

Convolutional Block Attention Module (CBAM) 表示卷积模块的注意力机制模块,是一种结合了空间(spatial)和通道(channel)的注意力机制模块。相比于senet只关注通道(channel)的注意力机制可以取得更好的效果。

 图6 CBAM模块的结构图 

上图给出了添加CBAM模块之后的整体结构。可以看到的是,卷积层输出的结果,会先通过一个通道注意力模块,得到加权结果之后,会再经过一个空间注意力模块,最终进行加权得到结果。

图8 通道注意力模块图

通道注意力模块如图8所示。将输入的特征图,分别经过基于width和height的global max pooling 和global average pooling,然后分别经过MLP。将MLP输出的特征进行基于element-wise的加和操作,再经过sigmoid激活操作,生成最终的channel attention featuremap。将该channel attention featuremap和input featuremap做elementwise乘法操作,生成Spatial attention模块需要的输入特征。以上是通道注意力机制的步骤。

换一个角度考虑,通道注意力机制(Channel Attention Module)是将特征图在空间维度上进行压缩,得到一个一维矢量后再进行操作。在空间维度上进行压缩时,不仅考虑到了平均值池化(Average Pooling)还考虑了最大值池化(Max Pooling)。平均池化和最大池化可用来聚合特征映射的空间信息,送到一个共享网络,压缩输入特征图的空间维数,逐元素求和合并,以产生通道注意力图。单就一张图来说,通道注意力,关注的是这张图上哪些内容是有重要作用的。平均值池化对特征图上的每一个像素点都有反馈,而最大值池化在进行梯度反向传播计算时,只有特征图中响应最大的地方有梯度的反馈。通道注意力机制可以表达为:

空间注意力模块如图9所示。将Channel attention模块输出的特征图作为本模块的输入特征图。首先做一个基于channel的global max pooling 和global average pooling,然后将这2个结果基于channel 做concat操作。然后经过一个卷积操作,降维为1个channel。再经过sigmoid生成spatial attention feature。最后将该feature和该模块的输入feature做乘法,得到最终生成的特征。

 图9 空间注意力模块图

同样,空间注意力机制(Spatial Attention Module)是对通道进行压缩,在通道维度分别进行了平均值池化和最大值池化。MaxPool的操作就是在通道上提取最大值,提取的次数是高乘以宽;AvgPool的操作就是在通道上提取平均值,提取的次数也是是高乘以宽;接着将前面所提取到的特征图(通道数都为1)合并得到一个2通道的特征图。

2.2 CBAM代码(Pytorch)

class ChannelAttention(nn.Module):
    def __init__(self, in_planes, ratio=16):
        super(ChannelAttention, self).__init__()
        self.avg_pool = nn.AdaptiveAvgPool2d(1)
        self.max_pool = nn.AdaptiveMaxPool2d(1)

        self.f1 = nn.Conv2d(in_planes, in_planes // ratio, 1, bias=False)
        self.relu = nn.ReLU()
        self.f2 = nn.Conv2d(in_planes // ratio, in_planes, 1, bias=False)

        self.sigmoid = nn.Sigmoid()

    def forward(self, x):
        avg_out = self.f2(self.relu(self.f1(self.avg_pool(x))))
        max_out = self.f2(self.relu(self.f1(self.max_pool(x))))
        out = self.sigmoid(avg_out + max_out)
        return out


class SpatialAttention(nn.Module):
    def __init__(self, kernel_size=7):
        super(SpatialAttention, self).__init__()

        assert kernel_size in (3, 7), 'kernel size must be 3 or 7'
        padding = 3 if kernel_size == 7 else 1

        self.conv = nn.Conv2d(2, 1, kernel_size, padding=padding, bias=False)
        self.sigmoid = nn.Sigmoid()

    def forward(self, x):
        avg_out = torch.mean(x, dim=1, keepdim=True)
        max_out, _ = torch.max(x, dim=1, keepdim=True)
        x = torch.cat([avg_out, max_out], dim=1)
        x = self.conv(x)
        return self.sigmoid(x)



class CBAM(nn.Module):
    def __init__(self, c1, c2):
        super(CBAM, self).__init__()
        self.channel_attention = ChannelAttention(c1)
        self.spatial_attention = SpatialAttention()

    def forward(self, x):
        out = self.channel_attention(x) * x
        out = self.spatial_attention(out) * out
        return out

2.3 YOLOv5中加入CBAM模块 

2.3.1 common.py配置

在yolov5-6.1/models/common.py文件中增加以下模块,直接复制即可。

class ChannelAttention(nn.Module):
    def __init__(self, in_planes, ratio=16):
        super(ChannelAttention, self).__init__()
        self.avg_pool = nn.AdaptiveAvgPool2d(1)
        self.max_pool = nn.AdaptiveMaxPool2d(1)

        self.f1 = nn.Conv2d(in_planes, in_planes // ratio, 1, bias=False)
        self.relu = nn.ReLU()
        self.f2 = nn.Conv2d(in_planes // ratio, in_planes, 1, bias=False)

        self.sigmoid = nn.Sigmoid()

    def forward(self, x):
        avg_out = self.f2(self.relu(self.f1(self.avg_pool(x))))
        max_out = self.f2(self.relu(self.f1(self.max_pool(x))))
        out = self.sigmoid(avg_out + max_out)
        return out


class SpatialAttention(nn.Module):
    def __init__(self, kernel_size=7):
        super(SpatialAttention, self).__init__()

        assert kernel_size in (3, 7), 'kernel size must be 3 or 7'
        padding = 3 if kernel_size == 7 else 1

        self.conv = nn.Conv2d(2, 1, kernel_size, padding=padding, bias=False)
        self.sigmoid = nn.Sigmoid()

    def forward(self, x):
        avg_out = torch.mean(x, dim=1, keepdim=True)
        max_out, _ = torch.max(x, dim=1, keepdim=True)
        x = torch.cat([avg_out, max_out], dim=1)
        x = self.conv(x)
        return self.sigmoid(x)



class CBAM(nn.Module):
    def __init__(self, c1, c2):
        super(CBAM, self).__init__()
        self.channel_attention = ChannelAttention(c1)
        self.spatial_attention = SpatialAttention()

    def forward(self, x):
        out = self.channel_attention(x) * x
        out = self.spatial_attention(out) * out
        return out

2.3.2 yolo.py配置

然后找到yolov5-6.1/models//yolo.py文件下里的parse_model函数,将类名加入进去,如下所示。

2.3.3 创建添加CBAM模块的YOLOv5的yaml配置文件

完成上述两步操作之后,就可以在原有的YOLOv5的yaml配置文件的基础上进行修改,在适当位置添加RepVGG模块或者利用RepVGG模块替换原始yaml配置文件中的一些模块,这里为了能够快速的训练模型,选择YOLOv5s模型进行修改,修改后的yolov5s_se.yaml文件内容如下所示。

# YOLOv5 🚀 by YOLOAir, GPL-3.0 license

# Parameters
nc: 2  # 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 v6.0 backbone
backbone:
  # [from, number, module, args]
  [[-1, 1, Conv, [64, 6, 2, 2]],  # 0-P1/2
   [-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, 3, C3, [1024]],
   [-1, 1, SPPF, [1024, 5]],  # 9
  ]

# YOLOv5 v6.0 head
head:
  [[-1, 1, Conv, [512, 1, 1]],
   [-1, 1, nn.Upsample, [None, 2, 'nearest']],
   [[-1, 6], 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, 4], 1, Concat, [1]],  # cat backbone P3
   [-1, 3, C3, [256, False]],  # 17 (P3/8-small)
   [-1, 1, CBAM, [256]],

   [-1, 1, Conv, [256, 3, 2]],
   [[-1, 14], 1, Concat, [1]],  # cat head P4
   [-1, 3, C3, [512, False]],  # 20 (P4/16-medium)
   [-1, 1, CBAM, [512]],

   [-1, 1, Conv, [512, 3, 2]],
   [[-1, 10], 1, Concat, [1]],  # cat head P5
   [-1, 3, C3, [1024, False]],  # 23 (P5/32-large)
   [-1, 1, CBAM, [1024]],

   [[18, 21, 24], 1, Detect, [nc, anchors]],  # Detect(P3, P4, P5)
  ]

 3 CA

论文名称:Coordinate Attention for Efficient Mobile Network Design

论文链接:https://arxiv.org/pdf/2103.02907.pdf

论文代码:CoordAttention/coordatt.py at main · houqb/CoordAttention · GitHub 

3.1 CA原理

目前,轻量级网络的注意力机制大都采用SE模块,仅考虑了通道间的信息,忽略了位置信息。尽管后来的BAM和CBAM尝试在降低通道数后通过卷积来提取位置注意力信息,但卷积只能提取局部关系,缺乏长距离关系提取的能力。为此,论文提出了新的高效注意力机制coordinate attention,能够将横向和纵向的位置信息编码到channel attention中,使得移动网络能够关注大范围的位置信息又不会带来过多的计算量。
coordinate attention的优势主要有以下几点:

  • 不仅获取了通道间信息,还考虑了方向相关的位置信息,有助于模型更好地定位和识别目标。
  • 足够灵活和轻量,能够简单地插入移动网络的核心结构中。
  • 可以作为预训练模型用于多种任务中,如检测和分割,均有不错的性能提升。

CA注意力机制的详细原理可以参考我前期写的博客https://blog.csdn.net/qq_40716944/article/details/121787103?spm=1001.2014.3001.5502

3.2 CA代码(Pytorch)

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 

3.3 YOLOv5中加入CA模块 

3.3.1 common.py配置

在yolov5-6.1/models/common.py文件中增加以下模块,直接复制即可。

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 

3.3.2 yolo.py配置

然后找到yolov5-6.1/models//yolo.py文件下里的parse_model函数,将类名加入进去,如下所示。

3.3.3 创建添加CA模块的YOLOv5的yaml配置文件

完成上述两步操作之后,就可以在原有的YOLOv5的yaml配置文件的基础上进行修改,在适当位置添加RepVGG模块或者利用RepVGG模块替换原始yaml配置文件中的一些模块,这里为了能够快速的训练模型,选择YOLOv5s模型进行修改,修改后的yolov5s_se.yaml文件内容如下所示。

# YOLOv5 🚀 by YOLOAir, GPL-3.0 license

# Parameters
nc: 2  # 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 v6.0 backbone
backbone:
  # [from, number, module, args]
  [[-1, 1, Conv, [64, 6, 2, 2]],  # 0-P1/2
   [-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, 3, C3, [1024]],
   [-1, 1, SPPF, [1024, 5]],  # 9
  ]

# YOLOv5 v6.0 head
head:
  [[-1, 1, Conv, [512, 1, 1]],
   [-1, 1, nn.Upsample, [None, 2, 'nearest']],
   [[-1, 6], 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, 4], 1, Concat, [1]],  # cat backbone P3
   [-1, 3, C3, [256, False]],  # 17 (P3/8-small)
   [-1, 1, CoordAtt, [256]],

   [-1, 1, Conv, [256, 3, 2]],
   [[-1, 14], 1, Concat, [1]],  # cat head P4
   [-1, 3, C3, [512, False]],  # 20 (P4/16-medium)
   [-1, 1, CoordAtt, [512]],

   [-1, 1, Conv, [512, 3, 2]],
   [[-1, 10], 1, Concat, [1]],  # cat head P5
   [-1, 3, C3, [1024, False]],  # 23 (P5/32-large)
   [-1, 1, CoordAtt, [1024]],

   [[18, 21, 24], 1, Detect, [nc, anchors]],  # Detect(P3, P4, P5)
  ]

 4、实验效果对比

4.1 口罩检测数据集

前期收集了口罩检测识别数据集,主要是未佩戴口罩和佩戴口罩两个类别,图片总数在10000张左右,部分图片如下所示。

4.2 效果对比

 为了对比加入SE、CBAM和CA模块后YOLOv5算法的效果,选择同样的数据集和实验参数进行算法模型训练和测试,实验参数设置如下。

在同样的训练参数和训练集的情况,得到训练后的模型,然后在同样的测试集上进行测试验证,测试集上的测试效果如下表所示,可以看出加入CBAM和CA模块后的YOLOv5s的效果比原始的yolov5s有所提升,但是加入SE注意力机制后的效果是下降的,数据集不同,加入SE、CBAM和CA模块后的效果也是存在区别的,需要根据自己的数据集调整SE、CBAM和CA模块的位置以及数量。

faceface_maskall
yolov5s0.8850.9320.908
yolov5s_se0.8750.9170.896
yolov5s_cbam0.8760.9420.909
yolov5s_ca0.8930.9320.913

 

 

参考文章

1 https://github.com/ultralytics/yolov5

2 CBAM——即插即用的注意力模块(附代码)_Billie使劲学的博客-CSDN博客_cbam

3 注意力机制——CAM、SAM、CBAM、SE_Billie使劲学的博客-CSDN博客_cam注意力机制

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

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

相关文章

敏捷是一种态度:有了敏捷建模,就有了敏捷需求

目 录01 缘起02 敏捷需求5W1H的思考‍‍‍‍‍‍03 关于敏捷需求体系的一些思考‍‍‍‍‍‍04 写在敏捷需求后的话01缘起对研发效能提升的研究,是近年来各家企业技术部门一直在研究的课题。早期,针对敏捷开发的实践,让大多技术管理者尝到…

114.(leaflet之家)leaflet空间判断-点与圆的空间关系

听老人家说:多看美女会长寿 地图之家总目录(订阅之前建议先查看该博客) 文章末尾处提供保证可运行完整代码包,运行如有问题,可“私信”博主。 效果如下所示: 下面献上完整代码,代码重要位置会做相应解释 <!DOCTYPE html> <html>

每个开发人员都应该使用的可扩展和可维护的 React 项目结构

一个好的项目结构可以在理解代码库、灵活性和维护方面对项目的成功产生巨大影响。结构和维护不当的项目很快就会变成一团糟和可怕的遗产&#xff0c;没有人愿意与之共事。我现在将向您展示我在项目中经常使用的结构&#xff0c;并解释其背后的原因。这种结构应该是大规模应用程…

开源代码 | FMCW-MIMO雷达仿真MATLAB

本文编辑&#xff1a;调皮哥的小助理 本程序来源&#xff1a;https://github.com/ekurtgl/FMCW-MIMO-Radar-Simulation&#xff0c;作者是阿拉巴马大学博士生艾库特格尔&#xff0c;研究方向主要是雷达信号处理人类活动识别以及雷达数据的机器学习应用&#xff0c;这份比较新的…

STM32MP157驱动开发——4G通信模块驱动

STM32MP157驱动开发——4G通信模块驱动一、简介二、驱动开发1.高新兴 ME3630 驱动开发驱动修改添加 ECM 支持程序配置 Linux 内核ppp拨号功能测试ECM 联网测试ME3630 4G 模块 GNSS 定位测试2.移远EC20 4G驱动开发驱动修改配置 Linux 内核EC20 ppp 拨号上网移远 GobiNET 驱动移植…

go语言学习(一):Mac环境安装及初始化

​ ​为什么要学习go语言? 1、简洁&#xff0c;快速&#xff0c;安全&#xff1b; ​ ​2、并行&#xff0c;有趣&#xff0c;开源​&#xff1b; 3、内存管理&#xff0c;数据安全&#xff0c;编译迅速 首先&#xff0c;去官网&#xff1a;https://golang.google.cn/dl…

面向对象3(多态、多态调用成员函数的特点、多态的优势和弊端及改进、包、final、权限修饰符、代码块、抽象方法和抽象类、接口、内部类)

1、多态 2、多态调用成员函数的特点 示例如下&#xff1a; 理解&#xff1a; 因为是Animal类型的&#xff0c;所以在输出name时会在父类继承下来的变量里面找 &#xff0c;没有就报错。而一般是先找自己再找父类继承下来的。 3、多态的优势和弊端及改进 优势&#xff1a; 弊端…

Arduino——野火GPS模块

GPS模块 文章目录GPS模块前言一、Arduino代码前言 手上还有一个GPS&#xff0c;用arduino做模块很方便&#xff0c;打算和短信模块结合&#xff0c;短信模块上次已经使用完成了&#xff0c;这次学习一下GPS模块 看模块很容易知道&#xff0c;这个模块用的是串口通信&#xff…

基于STM32智能家居控制系统软件设计及实现

1.1 系统流程图 智能家居控制系统的软件设计主要使用Keil uVision5进行STM32主烧录程序的编写&#xff0c;主程序完成的功能主要为接收并判断语音识别模块传过来的信息&#xff0c;然后根据满足条件的不同进行对应的操作。例如&#xff0c;当语音模块传过来的信息为“打开电视…

top详解--查看cpu及内存使用情况

top详解--查看cpu及内存使用情况 参考链接:http://t.zoukankan.com/guoyu1-p-12237660.html 一、top命令 top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器。 运行 top 命令后,CPU 使用状态会以全屏的方式显示,…

基于Java+SpringBoot+vue+element实现婚纱摄影网系统

基于JavaSpringBootvueelement实现婚纱摄影网系统 &#x1f345; 作者主页 超级帅帅吴 &#x1f345; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; &#x1f345; 文末获取源码联系方式 &#x1f4dd; 文章目录基于JavaSpringBootvueelement实现婚纱摄影网系统前言介绍&…

Flask中的后端并发思考(以Mysql:too many connections为例)

之前写过一篇《CentOS 下部署NginxGunicornSupervisor部署Flask项目》&#xff0c;最近对该工程的功能进行了完善&#xff0c;基本的功能单元测试也做了。觉得也是时候进行一下压力测试了&#xff0c;所以利用Jmeter对部署到服务器的项目进行了简单的压力测试。在之前的笔记中写…

10个 Python 高效编程小技巧

初识Python语言&#xff0c;觉得python满足了你上学时候对编程语言的所有要求。python语言的高效编程技巧让那些曾经苦逼学了四年c或者c的人&#xff0c;兴奋的不行不行的&#xff0c;终于解脱了。高级语言&#xff0c;如果做不到这样&#xff0c;还扯啥高级呢&#xff1f; 01…

【密码学】HMAC与HS256算法

哈希算法加盐 传统的哈希算法&#xff1a; digest hash(input)因为相同的输入会产生相同的输出&#xff0c;所以想要加盐&#xff0c;加盐的目的就在于&#xff0c;使输入有所变化&#xff1a; digest hash(salt input)这个salt可以看作是一个额外的“认证码”&#xff0…

ChatGPT 使用 API 进行 Postman 调用测试

当获得 ChatGPT 的 API Key 以后&#xff0c;想使用 Postman 来进行一下调用。调用的方法为 POST。需要设置几个参数。我们希望使用的 EndPoint 是&#xff1a;API EndPoint访问使用的 EndPoint 是&#xff1a;https://api.openai.com/v1/completions授权方法授权的方法使用的是…

FortiGate FGCP HA 配置文档

概述 FortiOS 提供 6 种冗余解决方案&#xff0c;工业标准的 VRRP 和 5 种专有的解决方案&#xff1a; FortiGate Cluster Protocol (FGCP) high availability&#xff0c;FortiGate Session Life Support Protocol (FGSP) high availability&#xff0c;Session-Aware Load …

Spring Cloud LoadBalancer(负载均衡)

简介 了解过Spring Cloud&#xff0c;就知道&#xff0c;之前Spring Cloud中默认的负载均衡组件为ribbon&#xff0c;ribbon是Netflix开源的组件&#xff0c;但是目前已经停止更新了。所以Spring官方推出了Spring Cloud LoadBalancer。而且Spring Cloud LoadBalancer是目前唯一…

win11下通过qemu 安装win10 arm系统

安装qemu QEMU for Windows – Installers (64 bit) 我选了最新的20221230的版本&#xff0c;我将其安装在c:\qemu7\下&#xff0c;另外在环境变量中加入这个路径 然后在别的盘上建立一个路径&#xff0c;名称随意&#xff0c;不要有中文和空格即可&#xff0c;我放在了e:\qe…

电脑蓝屏提示错误代码0X000000B4怎么办?

电脑蓝屏可以说是Windows的一个常见问题了。蓝屏状况数不胜数&#xff0c;关键还得看是何终止代码。 如果电脑蓝屏&#xff0c;提示错误代码0X000000B4是什么意思&#xff1f;这是由于Windows不能启动显卡驱动&#xff0c;从而无法进入图形界面。 蓝屏错误0X000000B4可能由驱…

docker搭建redis集群(Cluster版三主三从)

docker搭建redis集群(Cluster版三主三从编写脚步建立配置redis的配置文件启动六个redis服务创建cluster集群测试集群的高可用编写脚步建立配置redis的配置文件 建立配置文件脚本 vim redis.shfor port in $(seq 1 6); \ do \ mkdir -p /volumn/redis/node-${port}/conf touch…