自我介绍:本人硕士期间全程放养,目前成果:一篇北大核心CSCD录用,两篇中科院三区已见刊,一篇中科院四区在投。如何找创新点,如何放养过程厚积薄发,如何写中英论文,找期刊等等。本人后续会以自己实战经验详细写出来,还请大家能够点个关注和赞,收藏一下,谢谢大家。
1. 文章主要内容
本篇博客主要涉及坐标注意力机制CA结构融合到YOLOv5模型中。(通读本篇博客需要7分钟左右的时间)。
2. 详细代码改进流程
2.1 CA源代码
博主这里使用YOLOv5的C3结构与坐标注意力机制CA结合的新结构C3CA,并提供的main函数的测试代码。其源代码如下:
import torch
import torch.nn as nnfrom models.common import Conv, Bottleneckclass 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) / 6class 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, 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, inp, kernel_size=1, stride=1, padding=0)self.conv_w = nn.Conv2d(mip, inp, kernel_size=1, stride=1, padding=0)def forward(self, x):identity = xn, 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_hreturn outclass C3CA(nn.Module):def __init__(self, c1, c2, n=1, shortcut=True, g=1,e=0.5): # ch_in, ch_out, number, shortcut, groups, expansion #iscyysuper(C3CA, self).__init__()c_ = int(c2 * e) # hidden channelsself.CA = CoordAtt(2 * c_)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(*[CB2d(c_) for _ in range(n)])self.m = nn.Sequential(*[Bottleneck(c_, c_, shortcut, g, e=1.0) for _ in range(n)])def forward(self, x):out = torch.cat((self.m(self.cv1(x)), self.cv2(x)), dim=1)out = self.CA(out) # C3 concat之后加入CAout = self.cv3(out)return outif __name__ == '__main__':input = torch.randn(512, 512, 7, 7)pna = C3CA(512, 512)output = pna(input)print(output.shape)
2.2 建立一个yolov5-C3CA.yaml文件
注意到,这里博主直接使用C3CA代替Backbone部分的四个C3结构,另外注意nc改为自己数据集的类别数。
# YOLOv5 🚀 by Ultralytics, GPL-3.0 license# Parameters
nc: 4 # 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 output_channel, kernel_size, stride, padding[-1, 1, Conv, [128, 3, 2]], # 1-P2/4[-1, 3, C3CA, [128]],[-1, 1, Conv, [256, 3, 2]], # 3-P3/8[-1, 6, C3CA, [256]],[-1, 1, Conv, [512, 3, 2]], # 5-P4/16[-1, 9, C3CA, [512]],[-1, 1, Conv, [1024, 3, 2]], # 7-P5/32[-1, 3, C3CA, [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, Conv, [256, 3, 2]],[[-1, 14], 1, Concat, [1]], # cat head P4[-1, 3, C3, [512, False]], # 20 (P4/16-medium)[-1, 1, Conv, [512, 3, 2]],[[-1, 10], 1, Concat, [1]], # cat head P5[-1, 3, C3, [1024, False]], # 23 (P5/32-large)[[17, 20, 23], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5)]
2.3 将C3CA引入到yolo.py文件中
在下图的位置处,引入相关的类即可。
2.4 修改train.py启动文件
修改配置文件为yolov5-C3CA.yaml即可,如下图所示:
3. 总结
本篇博客主要介绍了CA注意力机制融合到YOLOv5模型,多维度关注数据特征,使得模型高效涨点。另外,在修改过程中,要是有任何问题,评论区交流;如果博客对您有帮助,请帮忙点个赞,收藏一下;后续会持续更新本人实验当中觉得有用的点子,如果很感兴趣的话,可以关注一下,谢谢大家啦!