秋招面试专栏推荐 :深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转
💡💡💡本专栏所有程序均经过测试,可成功执行💡💡💡
专栏目录 :《YOLOv8改进有效涨点》专栏介绍 & 专栏目录 | 目前已有110+篇内容,内含各种Head检测头、损失函数Loss、Backbone、Neck、NMS等创新点改进——点击即可跳转
本文介绍了网络设计中“星运算”(逐元素乘法)的潜力,这一操作能在不增加网络规模的情况下,实现输入到高维非线性特征空间的映射。StarNet模型,结构紧凑、高效,展现了出色的性能和低延迟,展示了星运算广阔的应用前景。文章在介绍主要的原理后,将手把手教学如何进行模块的代码添加和修改,并将修改后的完整代码放在文章的最后,方便大家一键运行,小白也可轻松上手实践。以帮助您更好地学习深度学习目标检测YOLO系列的挑战。
专栏地址:YOLOv8改进——更新各种有效涨点方法——点击即可跳转
目录
1.原理
2. 将C2f_Star_CAA添加到yolov8网络中
2.1 C2f_Star_CAA代码实现
2.2 C2f_Star_CAA的神经网络模块代码解析
2.3 更改init.py文件
2.4 添加yaml文件
2.5 注册模块
2.6 执行程序
3. 完整代码分享
4. GFLOPs
5. 进阶
6. 总结
1.原理
论文地址:Rewrite the Stars⭐ ——点击即可跳转
官方代码:官方代码仓库——点击即可跳转
StarNet的主要原理可以总结如下:
StarNet的核心思想
-
星操作(Star Operation):
-
星操作是指元素级乘法(element-wise multiplication),用于融合不同子空间的特征。
-
这种操作能够将输入特征映射到高维非线性特征空间,类似于核技巧(kernel tricks),而不需要增加网络的宽度(通道数)。
-
-
高维非线性特征映射:
-
星操作通过元素级乘法生成一个新的特征空间,这个特征空间具有大约((d\sqrt{2})^2)个线性独立的维度。
-
这种操作与传统神经网络通过增加网络宽度来获得高维特征的方式不同,更像是多项式核函数(polynomial kernel functions)的操作。
-
-
高效的紧凑网络结构:
-
通过堆叠多个星操作层,每一层都显著增加隐含的维度复杂度。
-
即使在紧凑的特征空间中操作,星操作仍然能够利用隐含的高维特征。
-
-
性能和效率:
-
星操作在性能和效率上表现出色,尤其是在网络宽度较小的情况下。
-
StarNet使用星操作设计了一个简单但高效的网络结构,证明了其在紧凑网络中的有效性。
-
StarNet的实现
网 络结构:
-
StarNet通过堆叠多层星操作层构建
- 星操作层的基本形式为,即通过元素级乘法融合两个线性变换后的特征。
理 论分析和实验验证:
-
通过理论分析证明了星操作能够在一个层内将输入特征映射到一个高维非线性特征空间,并且在多层堆叠下能够递归地显著增加隐含的特征维度。
-
实验结果表明,StarNet在ImageNet-1K验证集上的表现优于许多精心设计的高效模型,并且在实际应用中具有较低的延迟和较高的运行效率。
比较与优势:
-
与现有的高效网络设计相比,StarNet没有复杂的设计和超参数调优,仅依赖于星操作的高效性。
-
StarNet的设计理念与传统方法(如卷积、线性层和非线性激活的结合)有明显的不同,强调利用隐含的高维特征来提升网络效率。
综上所述,StarNet通过星操作实现了在紧凑网络中的高效性和高性能,展示了元素级乘法在特征融合中的巨大潜力和应用前景。
2. 将C2f_Star_CAA添加到yolov8网络中
2.1 C2f_Star_CAA代码实现
关键步骤一: 将下面代码粘贴到在/ultralytics/ultralytics/nn/modules/block.py中,并在该文件的__all__中添加“C2f_Star_CAA”
python">from timm.models.layers import DropPathclass CAA(nn.Module):def __init__(self, ch, h_kernel_size=11, v_kernel_size=11) -> None:super().__init__()self.avg_pool = nn.AvgPool2d(7, 1, 3)self.conv1 = Conv(ch, ch)self.h_conv = nn.Conv2d(ch, ch, (1, h_kernel_size), 1, (0, h_kernel_size // 2), 1, ch)self.v_conv = nn.Conv2d(ch, ch, (v_kernel_size, 1), 1, (v_kernel_size // 2, 0), 1, ch)self.conv2 = Conv(ch, ch)self.act = nn.Sigmoid()def forward(self, x):attn_factor = self.act(self.conv2(self.v_conv(self.h_conv(self.conv1(self.avg_pool(x))))))return attn_factor * xclass Star_Block(nn.Module):def __init__(self, dim, mlp_ratio=3, drop_path=0.):super().__init__()self.dwconv = Conv(dim, dim, 7, g=dim, act=False)self.f1 = nn.Conv2d(dim, mlp_ratio * dim, 1)self.f2 = nn.Conv2d(dim, mlp_ratio * dim, 1)self.g = Conv(mlp_ratio * dim, dim, 1, act=False)self.dwconv2 = nn.Conv2d(dim, dim, 7, 1, (7 - 1) // 2, groups=dim)self.act = nn.ReLU6()self.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity()def forward(self, x):input = xx = self.dwconv(x)x1, x2 = self.f1(x), self.f2(x)x = self.act(x1) * x2x = self.dwconv2(self.g(x))x = input + self.drop_path(x)return xclass Star_Block_CAA(Star_Block):def __init__(self, dim, mlp_ratio=3, drop_path=0):super().__init__(dim, mlp_ratio, drop_path)self.attention = CAA(mlp_ratio * dim)def forward(self, x):input = xx = self.dwconv(x)x1, x2 = self.f1(x), self.f2(x)x = self.act(x1) * x2x = self.dwconv2(self.g(self.attention(x)))x = input + self.drop_path(x)return xclass C2f_Star_CAA(C2f):def __init__(self, c1, c2, n=1, shortcut=False, g=1, e=0.5):super().__init__(c1, c2, n, shortcut, g, e)self.m = nn.ModuleList(Star_Block_CAA(self.c) for _ in range(n))
2.2 C2f_Star_CAA的神经网络模块代码解析
C2f_Star_CAA
模块结合了卷积神经网络和注意力机制
-
继承自
C2f
:-
C2f_Star_CAA
模块继承自一个自定义模块C2f
,它可能实现了一种在多个层上进行特征聚合或处理的机制。这个类负责确定模型的结构,比如通道数(c1
,c2
)、层数(n
)、以及是否有快捷连接(shortcut)。虽然C2f
的具体行为依赖于其内部实现,但它提供了一个基础框架来堆叠多个模块。
-
-
使用
Star_Block_CAA
:-
C2f_Star_CAA
的核心处理单元是多个Star_Block_CAA
实例。这一块结合了卷积操作、注意力机制(CAA
模块)和 dropout(通过DropPath
实现)。 -
每个
Star_Block_CAA
包含以下内容:-
深度卷积(
dwconv
),这是一个空间卷积,但对每个输入通道独立应用。 -
两个单独的逐点卷积(
f1
和f2
),将通道维度扩展为mlp_ratio
倍,用于复杂的通道间交互建模。 -
一个门控机制,其中
f1
的输出(经过ReLU6
激活)与f2
的输出进行逐元素相乘。 -
CAA
(通道注意力增强)模块,通过水平和垂直卷积来捕捉通道间的依赖性,增强空间和通道交互。 -
注意力机制的输出通过额外的深度卷积(
dwconv2
)和逐点卷积(g
)处理。 -
使用
drop_path
应用残差连接,这意味着在正则化过程中可能会随机丢弃部分路径。
-
-
-
注意力机制 (
CAA
):-
CAA
(通道注意力增强)通过平均池化,然后进行逐通道卷积(水平和垂直方向)来建模通道间的依赖关系。最终输出通过 sigmoid 激活函数生成注意力因子,然后与输入特征图相乘。
-
-
类似 C2f 的结构:
-
C2f_Star_CAA
由一系列的Star_Block_CAA
组成,其中n
决定了块的数量。快捷连接(shortcut)机制可能会将模块的输入连接到输出,以确保有效的梯度传播,减少梯度消失问题。
-
主要原理:
-
特征注意力:通过结合
CAA
模块,模型能够根据空间和通道信息动态地强调重要特征。 -
残差连接:残差连接确保模型能够学习到更深的表示,同时最小化梯度消失的风险。
-
DropPath 正则化:
DropPath
机制作为一种随机深度正则化方法,通过在训练过程中随机丢弃部分网络,提升模型的泛化能力。 -
模块化与灵活性:设计是模块化的,层数(
n
)、通道数(c1
,c2
)和扩展比例(mlp_ratio
)都可以配置。
总的来说,C2f_Star_CAA
结合了 C2f
结构的灵活性和 Star_Block_CAA
的强大特征学习能力,后者融合了卷积与注意力机制,用于特征提取和精炼。
2.3 更改init.py文件
关键步骤二:修改modules文件夹下的__init__.py文件,先导入函数
然后在下面的__all__中声明函数
2.4 添加yaml文件
关键步骤三:在/ultralytics/ultralytics/cfg/models/v8下面新建文件yolov8_C2f_Star_CAA.yaml文件,粘贴下面的内容
- OD【目标检测】
python"># Ultralytics YOLO 🚀, AGPL-3.0 license
# YOLOv8 object detection model with P3-P5 outputs. For Usage examples see https://docs.ultralytics.com/tasks/detect# Parameters
nc: 80 # number of classes
scales: # model compound scaling constants, i.e. 'model=yolov8n.yaml' will call yolov8.yaml with scale 'n'# [depth, width, max_channels]n: [0.33, 0.25, 1024] # YOLOv8n summary: 225 layers, 3157200 parameters, 3157184 gradients, 8.9 GFLOPss: [0.33, 0.50, 1024] # YOLOv8s summary: 225 layers, 11166560 parameters, 11166544 gradients, 28.8 GFLOPsm: [0.67, 0.75, 768] # YOLOv8m summary: 295 layers, 25902640 parameters, 25902624 gradients, 79.3 GFLOPsl: [1.00, 1.00, 512] # YOLOv8l summary: 365 layers, 43691520 parameters, 43691504 gradients, 165.7 GFLOPsx: [1.00, 1.25, 512] # YOLOv8x summary: 365 layers, 68229648 parameters, 68229632 gradients, 258.5 GFLOPs# YOLOv8.0n backbone
backbone:# [from, repeats, module, args]- [-1, 1, Conv, [64, 3, 2]] # 0-P1/2- [-1, 1, Conv, [128, 3, 2]] # 1-P2/4- [-1, 3, C2f_Star_CAA, [128, True]]- [-1, 1, Conv, [256, 3, 2]] # 3-P3/8- [-1, 3, C2f_Star_CAA, [256, True]]- [-1, 1, Conv, [512, 3, 2]] # 5-P4/16- [-1, 3, C2f_Star_CAA, [512, True]]- [-1, 1, Conv, [1024, 3, 2]] # 7-P5/32- [-1, 3, C2f_Star_CAA, [1024, True]]- [-1, 1, SPPF, [1024, 5]] # 9# YOLOv8.0n head
head:- [-1, 1, nn.Upsample, [None, 2, 'nearest']]- [[-1, 6], 1, Concat, [1]] # cat backbone P4- [-1, 3, C2f_Star_CAA, [512]] # 12- [-1, 1, nn.Upsample, [None, 2, 'nearest']]- [[-1, 4], 1, Concat, [1]] # cat backbone P3- [-1, 3, C2f_Star_CAA, [256]] # 15 (P3/8-small)- [-1, 1, Conv, [256, 3, 2]]- [[-1, 12], 1, Concat, [1]] # cat head P4- [-1, 3, C2f_Star_CAA, [512]] # 18 (P4/16-medium)- [-1, 1, Conv, [512, 3, 2]]- [[-1, 9], 1, Concat, [1]] # cat head P5- [-1, 3, C2f_Star_CAA, [1024]] # 21 (P5/32-large)- [[15, 18, 21], 1, Detect, [nc]] # Detect(P3, P4, P5)
- Seg【语义分割】
python"># Ultralytics YOLO 🚀, AGPL-3.0 license
# YOLOv8 object detection model with P3-P5 outputs. For Usage examples see https://docs.ultralytics.com/tasks/detect# Parameters
nc: 80 # number of classes
scales: # model compound scaling constants, i.e. 'model=yolov8n.yaml' will call yolov8.yaml with scale 'n'# [depth, width, max_channels]n: [0.33, 0.25, 1024] # YOLOv8n summary: 225 layers, 3157200 parameters, 3157184 gradients, 8.9 GFLOPss: [0.33, 0.50, 1024] # YOLOv8s summary: 225 layers, 11166560 parameters, 11166544 gradients, 28.8 GFLOPsm: [0.67, 0.75, 768] # YOLOv8m summary: 295 layers, 25902640 parameters, 25902624 gradients, 79.3 GFLOPsl: [1.00, 1.00, 512] # YOLOv8l summary: 365 layers, 43691520 parameters, 43691504 gradients, 165.7 GFLOPsx: [1.00, 1.25, 512] # YOLOv8x summary: 365 layers, 68229648 parameters, 68229632 gradients, 258.5 GFLOPs# YOLOv8.0n backbone
backbone:# [from, repeats, module, args]- [-1, 1, Conv, [64, 3, 2]] # 0-P1/2- [-1, 1, Conv, [128, 3, 2]] # 1-P2/4- [-1, 3, C2f_Star_CAA, [128, True]]- [-1, 1, Conv, [256, 3, 2]] # 3-P3/8- [-1, 3, C2f_Star_CAA, [256, True]]- [-1, 1, Conv, [512, 3, 2]] # 5-P4/16- [-1, 3, C2f_Star_CAA, [512, True]]- [-1, 1, Conv, [1024, 3, 2]] # 7-P5/32- [-1, 3, C2f_Star_CAA, [1024, True]]- [-1, 1, SPPF, [1024, 5]] # 9# YOLOv8.0n head
head:- [-1, 1, nn.Upsample, [None, 2, 'nearest']]- [[-1, 6], 1, Concat, [1]] # cat backbone P4- [-1, 3, C2f_Star_CAA, [512]] # 12- [-1, 1, nn.Upsample, [None, 2, 'nearest']]- [[-1, 4], 1, Concat, [1]] # cat backbone P3- [-1, 3, C2f_Star_CAA, [256]] # 15 (P3/8-small)- [-1, 1, Conv, [256, 3, 2]]- [[-1, 12], 1, Concat, [1]] # cat head P4- [-1, 3, C2f_Star_CAA, [512]] # 18 (P4/16-medium)- [-1, 1, Conv, [512, 3, 2]]- [[-1, 9], 1, Concat, [1]] # cat head P5- [-1, 3, C2f_Star_CAA, [1024]] # 21 (P5/32-large)- [[15, 18, 21], 1, Segment, [nc, 32, 256]] # Segment(P3, P4, P5)
温馨提示:因为本文只是对yolov8基础上添加模块,如果要对yolov8n/l/m/x进行添加则只需要指定对应的depth_multiple 和 width_multiple。不明白的同学可以看这篇文章: yolov8yaml文件解读——点击即可跳转
python"># YOLOv8n
depth_multiple: 0.33 # model depth multiple
width_multiple: 0.25 # layer channel multiple
max_channels: 1024 # max_channels# YOLOv8s
depth_multiple: 0.33 # model depth multiple
width_multiple: 0.50 # layer channel multiple
max_channels: 1024 # max_channels# YOLOv8l
depth_multiple: 1.0 # model depth multiple
width_multiple: 1.0 # layer channel multiple
max_channels: 512 # max_channels# YOLOv8m
depth_multiple: 0.67 # model depth multiple
width_multiple: 0.75 # layer channel multiple
max_channels: 768 # max_channels# YOLOv8x
depth_multiple: 1.33 # model depth multiple
width_multiple: 1.25 # layer channel multiple
max_channels: 512 # max_channels
2.5 注册模块
关键步骤四:在task.py的parse_model函数中注册
2.6 执行程序
在train.py中,将model的参数路径设置为yolov8_C2f_Star_CAA.yaml的路径
建议大家写绝对路径,确保一定能找到
python">from ultralytics import YOLO
import warnings
warnings.filterwarnings('ignore')
from pathlib import Pathif __name__ == '__main__':# 加载模型model = YOLO("ultralytics/cfg/v8/yolov8.yaml") # 你要选择的模型yaml文件地址# Use the modelresults = model.train(data=r"你的数据集的yaml文件地址",epochs=100, batch=16, imgsz=640, workers=4, name=Path(model.cfg).stem) # 训练模型
🚀运行程序,如果出现下面的内容则说明添加成功🚀
python"> from n params module arguments0 -1 1 464 ultralytics.nn.modules.conv.Conv [3, 16, 3, 2]1 -1 1 4672 ultralytics.nn.modules.conv.Conv [16, 32, 3, 2]2 -1 1 12688 ultralytics.nn.modules.block.C2f_Star_CAA [32, 32, 1, True]3 -1 1 18560 ultralytics.nn.modules.conv.Conv [32, 64, 3, 2]4 -1 1 44320 ultralytics.nn.modules.block.C2f_Star_CAA [64, 64, 1, True]5 -1 1 73984 ultralytics.nn.modules.conv.Conv [64, 128, 3, 2]6 -1 1 164416 ultralytics.nn.modules.block.C2f_Star_CAA [128, 128, 1, True]7 -1 1 295424 ultralytics.nn.modules.conv.Conv [128, 256, 3, 2]8 -1 1 631936 ultralytics.nn.modules.block.C2f_Star_CAA [256, 256, 1, True]9 -1 1 164608 ultralytics.nn.modules.block.SPPF [256, 256, 5]10 -1 1 0 torch.nn.modules.upsampling.Upsample [None, 2, 'nearest']11 [-1, 6] 1 0 ultralytics.nn.modules.conv.Concat [1]12 -1 1 197184 ultralytics.nn.modules.block.C2f_Star_CAA [384, 128, 1]13 -1 1 0 torch.nn.modules.upsampling.Upsample [None, 2, 'nearest']14 [-1, 4] 1 0 ultralytics.nn.modules.conv.Concat [1]15 -1 1 52512 ultralytics.nn.modules.block.C2f_Star_CAA [192, 64, 1]16 -1 1 36992 ultralytics.nn.modules.conv.Conv [64, 64, 3, 2]17 [-1, 12] 1 0 ultralytics.nn.modules.conv.Concat [1]18 -1 1 172608 ultralytics.nn.modules.block.C2f_Star_CAA [192, 128, 1]19 -1 1 147712 ultralytics.nn.modules.conv.Conv [128, 128, 3, 2]20 [-1, 9] 1 0 ultralytics.nn.modules.conv.Concat [1]21 -1 1 664704 ultralytics.nn.modules.block.C2f_Star_CAA [384, 256, 1]22 [15, 18, 21] 1 897664 ultralytics.nn.modules.head.Detect [80, [64, 128, 256]]
YOLOv8_C2f_Star_CAA summary: 355 layers, 3580448 parameters, 3580432 gradients, 9.7 GFLOPs
3. 完整代码分享
python">https://pan.baidu.com/s/1NrH6ADhTqCPMVIEYEdkeZA?pwd=ygdt
提取码: ygdt
4. GFLOPs
关于GFLOPs的计算方式可以查看:百面算法工程师 | 卷积基础知识——Convolution
未改进的YOLOv8nGFLOPs
改进后的GFLOPs
5. 进阶
可以与其他的注意力机制或者损失函数等结合,进一步提升检测效果
6. 总结
StarNet通过引入一种称为星操作(Star Operation)的核心创新,实现了在紧凑网络中高效处理图像的目标。星操作通过两个线性变换后的特征进行元素级乘法,生成一个高维非线性特征空间,类似于多项式核函数的效果。StarNet采用一个四阶段的分层架构,每个阶段通过卷积层下采样分辨率并增加通道数,从而逐步抽象图像特征。每个网络块中使用深度卷积、批量归一化和ReLU6激活函数,简化设计以提高效率。通道扩展固定为4倍,网络宽度在每个阶段翻倍,以平衡计算负载和学习能力。通过标准的训练方法和推理时融合批量归一化层,StarNet在ImageNet-1K等基准测试中展示了其简单设计下的高效性能,表现出色。综上所述,StarNet通过巧妙的特征融合策略和高效的网络结构,在保持低计算复杂度的同时,实现了卓越的图像处理性能。