目錄
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 創(chuàng)建添加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 創(chuàng)建添加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 創(chuàng)建添加CA模塊的YOLOv5的yaml配置文件
?4、實(shí)驗(yàn)效果對比
4.1 口罩檢測數(shù)據(jù)集
4.2 效果對比
參考文章
在前面的文章中已經(jīng)詳細(xì)介紹了在本機(jī)上安裝YOLOv5的教程,安裝YOLOv5可參考前面的文章YOLOv5訓(xùn)練自己的數(shù)據(jù)集(超詳細(xì))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網(wǎng)絡(luò)的多分支結(jié)構(gòu)。對于channel維度的特征融合,卷積操作基本上默認(rèn)對輸入特征圖的所有channel進(jìn)行融合。而MobileNet網(wǎng)絡(luò)中的組卷積(Group Convolution)和深度可分離卷積(Depthwise Separable Convolution)對channel進(jìn)行分組也主要是為了使模型更加輕量級,減少計(jì)算量。而SENet網(wǎng)絡(luò)的創(chuàng)新點(diǎn)在于關(guān)注channel之間的關(guān)系,希望模型可以自動學(xué)習(xí)到不同channel特征的重要程度。為此,SENet提出了Squeeze-and-Excitation (SE)模塊,如圖1所示。
圖1 SEBlock結(jié)構(gòu)圖
SE模塊首先對卷積得到的特征圖進(jìn)行Squeeze操作,得到channel級的全局特征,然后對全局特征進(jìn)行Excitation操作,學(xué)習(xí)各個channel間的關(guān)系,也得到不同channel的權(quán)重,最后乘以原來的特征圖得到最終特征。本質(zhì)上,SE模塊是在channel維度上做attention或者gating操作,這種注意力機(jī)制讓模型可以更加關(guān)注信息量最大的channel特征,而抑制那些不重要的channel特征。另外一點(diǎn)是SE模塊是通用的,這意味著其可以嵌入到現(xiàn)有的網(wǎng)絡(luò)架構(gòu)中。
為了更好的對SENet的核心原理進(jìn)行放分析,可以將SENet分成4個步驟進(jìn)行理解,如圖2所示。
?圖2 SEBlock模塊分析圖
- 從單張圖像開始,提取圖像特征,當(dāng)前特征層U的特征圖維度為[C,H,W]。
- 對特征圖的[ H , W ]維度進(jìn)行平均池化或最大池化,池化過后的特征圖大小從[ C , H , W ] ->[ C , 1 , 1 ]。[ C , 1 , 1 ] 可理解為對于每一個通道C,都有一個數(shù)字和其一一對應(yīng)。圖3對應(yīng)了步驟(2)的具體操作。
圖3?平均池化(最大池化)操作,得到每個通道的權(quán)重,得到每個通道的權(quán)重?
- 對[ C , 1 , 1 ]的特征可以理解為,從每個通道本身提取出來的權(quán)重,權(quán)重表示了每個通道對特征提取的影響力,全局池化后的向量通過MLP網(wǎng)絡(luò)后,其意義為得到了每個通道的權(quán)重。圖4對應(yīng)了步驟(3)的具體操作。
?
圖4?通道權(quán)重生成?
- 上述步驟,得到了每個通道C的權(quán)重[ C , 1 , 1 ],將權(quán)重作用于特征圖U[ C , H , W ],即每個通道各自乘以各自的權(quán)重。可以理解為,當(dāng)權(quán)重大時,該通道特征圖的數(shù)值相應(yīng)的增大,對最終輸出的影響也會變大;當(dāng)權(quán)重小時,該通道特征圖的數(shù)值就會更小,對最終輸出的影響也會變小。圖5對應(yīng)了步驟(4)的具體操作。
?
圖5 通道注意力——各通道乘以各自不同權(quán)重?
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文件中增加以下模塊,直接復(fù)制即可。
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配置
然后找到y(tǒng)olov5-6.1/models//yolo.py文件下里的parse_model函數(shù),將類名加入進(jìn)去,如下所示。
1.3.3 創(chuàng)建添加RepVGG模塊的YOLOv5的yaml配置文件
完成上述兩步操作之后,就可以在原有的YOLOv5的yaml配置文件的基礎(chǔ)上進(jìn)行修改,在適當(dāng)位置添加RepVGG模塊或者利用RepVGG模塊替換原始yaml配置文件中的一些模塊,這里為了能夠快速的訓(xùn)練模型,選擇YOLOv5s模型進(jìn)行修改,修改后的yolov5s_se.yaml文件內(nèi)容如下所示。
# 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) 表示卷積模塊的注意力機(jī)制模塊,是一種結(jié)合了空間(spatial)和通道(channel)的注意力機(jī)制模塊。相比于senet只關(guān)注通道(channel)的注意力機(jī)制可以取得更好的效果。
?圖6 CBAM模塊的結(jié)構(gòu)圖?
上圖給出了添加CBAM模塊之后的整體結(jié)構(gòu)??梢钥吹降氖?,卷積層輸出的結(jié)果,會先通過一個通道注意力模塊,得到加權(quán)結(jié)果之后,會再經(jīng)過一個空間注意力模塊,最終進(jìn)行加權(quán)得到結(jié)果。
圖8 通道注意力模塊圖
通道注意力模塊如圖8所示。將輸入的特征圖,分別經(jīng)過基于width和height的global max pooling 和global average pooling,然后分別經(jīng)過MLP。將MLP輸出的特征進(jìn)行基于element-wise的加和操作,再經(jīng)過sigmoid激活操作,生成最終的channel attention featuremap。將該channel attention featuremap和input featuremap做elementwise乘法操作,生成Spatial attention模塊需要的輸入特征。以上是通道注意力機(jī)制的步驟。
換一個角度考慮,通道注意力機(jī)制(Channel Attention Module)是將特征圖在空間維度上進(jìn)行壓縮,得到一個一維矢量后再進(jìn)行操作。在空間維度上進(jìn)行壓縮時,不僅考慮到了平均值池化(Average Pooling)還考慮了最大值池化(Max Pooling)。平均池化和最大池化可用來聚合特征映射的空間信息,送到一個共享網(wǎng)絡(luò),壓縮輸入特征圖的空間維數(shù),逐元素求和合并,以產(chǎn)生通道注意力圖。單就一張圖來說,通道注意力,關(guān)注的是這張圖上哪些內(nèi)容是有重要作用的。平均值池化對特征圖上的每一個像素點(diǎn)都有反饋,而最大值池化在進(jìn)行梯度反向傳播計(jì)算時,只有特征圖中響應(yīng)最大的地方有梯度的反饋。通道注意力機(jī)制可以表達(dá)為:
空間注意力模塊如圖9所示。將Channel attention模塊輸出的特征圖作為本模塊的輸入特征圖。首先做一個基于channel的global max pooling 和global average pooling,然后將這2個結(jié)果基于channel 做concat操作。然后經(jīng)過一個卷積操作,降維為1個channel。再經(jīng)過sigmoid生成spatial attention feature。最后將該feature和該模塊的輸入feature做乘法,得到最終生成的特征。
?圖9 空間注意力模塊圖
同樣,空間注意力機(jī)制(Spatial Attention Module)是對通道進(jìn)行壓縮,在通道維度分別進(jìn)行了平均值池化和最大值池化。MaxPool的操作就是在通道上提取最大值,提取的次數(shù)是高乘以寬;AvgPool的操作就是在通道上提取平均值,提取的次數(shù)也是是高乘以寬;接著將前面所提取到的特征圖(通道數(shù)都為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文件中增加以下模塊,直接復(fù)制即可。
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配置
然后找到y(tǒng)olov5-6.1/models//yolo.py文件下里的parse_model函數(shù),將類名加入進(jìn)去,如下所示。
2.3.3 創(chuàng)建添加CBAM模塊的YOLOv5的yaml配置文件
完成上述兩步操作之后,就可以在原有的YOLOv5的yaml配置文件的基礎(chǔ)上進(jìn)行修改,在適當(dāng)位置添加RepVGG模塊或者利用RepVGG模塊替換原始yaml配置文件中的一些模塊,這里為了能夠快速的訓(xùn)練模型,選擇YOLOv5s模型進(jìn)行修改,修改后的yolov5s_se.yaml文件內(nèi)容如下所示。
# 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原理
目前,輕量級網(wǎng)絡(luò)的注意力機(jī)制大都采用SE模塊,僅考慮了通道間的信息,忽略了位置信息。盡管后來的BAM和CBAM嘗試在降低通道數(shù)后通過卷積來提取位置注意力信息,但卷積只能提取局部關(guān)系,缺乏長距離關(guān)系提取的能力。為此,論文提出了新的高效注意力機(jī)制coordinate attention,能夠?qū)M向和縱向的位置信息編碼到channel attention中,使得移動網(wǎng)絡(luò)能夠關(guān)注大范圍的位置信息又不會帶來過多的計(jì)算量。
coordinate attention的優(yōu)勢主要有以下幾點(diǎn):
- 不僅獲取了通道間信息,還考慮了方向相關(guān)的位置信息,有助于模型更好地定位和識別目標(biāo)。
- 足夠靈活和輕量,能夠簡單地插入移動網(wǎng)絡(luò)的核心結(jié)構(gòu)中。
- 可以作為預(yù)訓(xùn)練模型用于多種任務(wù)中,如檢測和分割,均有不錯的性能提升。
CA注意力機(jī)制的詳細(xì)原理可以參考我前期寫的博客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文件中增加以下模塊,直接復(fù)制即可。
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配置
然后找到y(tǒng)olov5-6.1/models//yolo.py文件下里的parse_model函數(shù),將類名加入進(jìn)去,如下所示。
3.3.3 創(chuàng)建添加CA模塊的YOLOv5的yaml配置文件
完成上述兩步操作之后,就可以在原有的YOLOv5的yaml配置文件的基礎(chǔ)上進(jìn)行修改,在適當(dāng)位置添加RepVGG模塊或者利用RepVGG模塊替換原始yaml配置文件中的一些模塊,這里為了能夠快速的訓(xùn)練模型,選擇YOLOv5s模型進(jìn)行修改,修改后的yolov5s_se.yaml文件內(nèi)容如下所示。
# 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、實(shí)驗(yàn)效果對比
4.1 口罩檢測數(shù)據(jù)集
前期收集了口罩檢測識別數(shù)據(jù)集,主要是未佩戴口罩和佩戴口罩兩個類別,圖片總數(shù)在10000張左右,部分圖片如下所示。
4.2 效果對比
?為了對比加入SE、CBAM和CA模塊后YOLOv5算法的效果,選擇同樣的數(shù)據(jù)集和實(shí)驗(yàn)參數(shù)進(jìn)行算法模型訓(xùn)練和測試,實(shí)驗(yàn)參數(shù)設(shè)置如下。
在同樣的訓(xùn)練參數(shù)和訓(xùn)練集的情況,得到訓(xùn)練后的模型,然后在同樣的測試集上進(jìn)行測試驗(yàn)證,測試集上的測試效果如下表所示,可以看出加入CBAM和CA模塊后的YOLOv5s的效果比原始的yolov5s有所提升,但是加入SE注意力機(jī)制后的效果是下降的,數(shù)據(jù)集不同,加入SE、CBAM和CA模塊后的效果也是存在區(qū)別的,需要根據(jù)自己的數(shù)據(jù)集調(diào)整SE、CBAM和CA模塊的位置以及數(shù)量。
face | face_mask | all | |
yolov5s | 0.885 | 0.932 | 0.908 |
yolov5s_se | 0.875 | 0.917 | 0.896 |
yolov5s_cbam | 0.876 | 0.942 | 0.909 |
yolov5s_ca | 0.893 | 0.932 | 0.913 |
?
?
參考文章
1?https://github.com/ultralytics/yolov5
2?CBAM——即插即用的注意力模塊(附代碼)_Billie使勁學(xué)的博客-CSDN博客_cbam文章來源:http://www.zghlxwxcb.cn/news/detail-854064.html
3?注意力機(jī)制——CAM、SAM、CBAM、SE_Billie使勁學(xué)的博客-CSDN博客_cam注意力機(jī)制文章來源地址http://www.zghlxwxcb.cn/news/detail-854064.html
到了這里,關(guān)于優(yōu)化改進(jìn)YOLOv5算法之添加SE、CBAM、CA模塊(超詳細(xì))的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!