学习资源站

YOLOv11改进-主干_Backbone篇-添加最新的LSKNet遥感目标检测网络主干(可根据yolov11版本自行放缩通道数独家创新)

一、本文介绍

本文给大家带来的改进内容是 LSKNet (Large Kernel Selection, LK Selection),其是一种专为遥感目标检测设计的 网络架构 ,其核心思想是动态调整其大的空间感受野,以更好地捕捉遥感场景中不同对象的范围上下文。实验部分我在一个包含三十多个类别的数据集上进行实验,其中包含大目标检测和小目标检测, mAP的平均涨点幅度在0.04-0.1之间(也有极个别的情况没有涨点), 同时官方的版本只提供了一个大版本,我在其基础上提供一个轻量化版本给大家选择,本文会先给大家对比试验的结果,供大家参考。

(本文内容可根据yolov11的N、S、M、L、X进行二次缩放,轻量化更上一层)。


二、LSKNet原理

论文地址: 官方论文地址

代码地址: 官方代码地址


2.1  LSKNet的基本原理

LSKNet(Large Selective Kernel Network) 是一种专为遥感目标检测设计的网络架构,其 核心优势在于能够动态调整其大的空间感受野 ,以更好地捕捉遥感场景中不同对象的范围上下文。这是第一次在遥感目标检测领域探索大型和选择性核机制。

LSKNet(大型选择性核网络)的 基本原理 包括以下关键组成部分:

1. 大型核选择(LK Selection)子块: 这个子块能够动态地调整网络的感受野,以便根据需要捕获不同尺度的上下文信息。这使得网络能够根据 遥感图像 中对象的不同尺寸和复杂性调整其处理能力。

2. 前馈网络(FFN)子块: 该子块用于通道混合和特征精炼。它由一个完全连接的层、一个深度卷积、一个GELU激活 函数 以及第二个完全连接的层组成。这些组件一起工作,提高了特征的质量并为分类和检测提供了必要的信息。

这两个子块 共同构成LSKNet块 ,能够提供大范围的上下文信息,同时保持对细节的敏感度,这对于遥感目标检测尤其重要。

下面我将为大家展示四种不同的选择性机制模块的架构比较:

对于LSK模块:

1. 有一个 分解 步骤,似乎是用来处理大尺寸的卷积核(Large K)。
2. 接着是一个 空间选择 *步骤,可能用于选择或优化空间信息的特定部分。

这与其他三种 模型 的架构相比较,显示了 LSK模块在处理空间信息方面可能有其独特的方法 。具体来说,LSK模块似乎强调了在大尺寸卷积核上进行操作,这可能有助于捕获遥感图像中较大范围的上下文信息,这对于检测图像中的对象特别有用。空间选择步骤可能进一步增强了模型对于输入空间特征的选择能力,从而使其能够更加有效地聚焦于图像的重要部分。


2.2 大型核选择(LK Selection)子块

LSKNet的 大型核选择(Large Kernel Selection, LK Selection)子块 是其架构的核心组成部分之一。这个子块的功能是 根据需要动态调整网络的感受野大小 通过这种方式,LSKNet能够根据遥感图像中不同对象的大小和上下文范围,调整处理这些对象所需的空间信息范围。

大型核选择子块与 前馈网络(Feed-forward Network, FFN)子块 一起工作。FFN子块用于通道混合和特征细化,它包括一个序列,这个序列由一个全连接层、一个深度卷积、一个GELU激活函数以及第二个全连接层组成。这种设计允许LSKNet块进行特征深度融合和增强,进一步提升了遥感目标检测的性能

下面我将通过LSK(Large Selective Kernel)模块的概念性插图,展示LSKNet如何 通过大型核选择子块和空间选择机制来处理遥感数据 ,从而使网络能够适应不同对象的长范围上下文需求。

1. Large Kernel Decomposition: 原始输入 X ​经过大核分解,使用两种不同的大型卷积核(Large K)进行处理,以捕获不同尺度的空间信息。

2. Channel Concatenation: 两个不同的卷积输出 U_1 ​和 U_2 ​通过通道拼接组合在一起,这样可以在后续步骤中同时利用不同的空间特征。

3. Mixed Pooling: 拼接后的特征图经过平均池化和最大池化的组合操作,然后与自注意力(SA)机制一起使用,以进一步强化特征图的关键区域。

4. Convolution and Spatial Selection: 通过卷积操作和自注意力(SA)生成新的特征图,然后通过空间选择机制进一步增强对目标区域的关注。

5. Element Product and Sigmoid: 使用Sigmoid函数生成一个掩码 S ​,然后将这个掩码与特征图 F ​进行元素乘积操作,得到最终的输出特征图 Y ​。这一步骤用于加权特征图中更重要的区域,以增强网络对遥感图像中特定对象的检测能力。

整个LSK模块的设计强调了 对遥感图像中不同空间尺度和上下文信息的有效捕获 ,这对于在复杂背景下准确检测小型或密集排布的目标至关重要。通过上述步骤的复合操作,LSK模块能够提升遥感目标检测的性能。


2.3 前馈网络(FFN)子块

LSKNet的 前馈网络(Feed-forward Network, FFN) 子块用于通道混合和特征精炼。该子块包含以下组成部分:

1. 全连接层: 用于特征变换,提供网络额外的学习能力。
2. 深度卷积(depth-wise convolution): 用于在通道间独立地应用空间滤波,减少参数量的同时保持效果。
3. GELU激活函数: 一种高斯误差线性单元,用于引入非线性,提高模型的表达能力。
4. 第二个全连接层: 进一步变换和精炼特征。

这个FFN子块紧随LK Selection子块之后,作用是在 保持特征空间信息 的同时, 增强网络在特征通道上的表示能力 。通过这种设计,FFN子块有效地对输入特征进行了深度加工,提升了最终特征的质量,从而有助于提高整个网络在遥感目标检测任务中的性能。


三、LSKNet核心代码

将此代码复制粘贴到''ultralytics/nn/modules''目录下新建一个py文件我这里起名字为LSKNet.py,然后把代码复制粘贴进去即可,使用教程看章节四。

  1. import torch
  2. import torch.nn as nn
  3. from torch.nn.modules.utils import _pair as to_2tuple
  4. from timm.models.layers import DropPath, to_2tuple
  5. from functools import partial
  6. import warnings
  7. __all__ = [
  8. "LSKNET_Tiny", "LSKNET_Large"
  9. ]
  10. class Mlp(nn.Module):
  11. def __init__(self, in_features, hidden_features=None, out_features=None, act_layer=nn.GELU, drop=0.):
  12. super().__init__()
  13. out_features = out_features or in_features
  14. hidden_features = hidden_features or in_features
  15. self.fc1 = nn.Conv2d(in_features, hidden_features, 1)
  16. self.dwconv = DWConv(hidden_features)
  17. self.act = act_layer()
  18. self.fc2 = nn.Conv2d(hidden_features, out_features, 1)
  19. self.drop = nn.Dropout(drop)
  20. def forward(self, x):
  21. x = self.fc1(x)
  22. x = self.dwconv(x)
  23. x = self.act(x)
  24. x = self.drop(x)
  25. x = self.fc2(x)
  26. x = self.drop(x)
  27. return x
  28. class LSKblock(nn.Module):
  29. def __init__(self, dim):
  30. super().__init__()
  31. self.conv0 = nn.Conv2d(dim, dim, 5, padding=2, groups=dim)
  32. self.conv_spatial = nn.Conv2d(dim, dim, 7, stride=1, padding=9, groups=dim, dilation=3)
  33. self.conv1 = nn.Conv2d(dim, dim // 2, 1)
  34. self.conv2 = nn.Conv2d(dim, dim // 2, 1)
  35. self.conv_squeeze = nn.Conv2d(2, 2, 7, padding=3)
  36. self.conv = nn.Conv2d(dim // 2, dim, 1)
  37. def forward(self, x):
  38. attn1 = self.conv0(x)
  39. attn2 = self.conv_spatial(attn1)
  40. attn1 = self.conv1(attn1)
  41. attn2 = self.conv2(attn2)
  42. attn = torch.cat([attn1, attn2], dim=1)
  43. avg_attn = torch.mean(attn, dim=1, keepdim=True)
  44. max_attn, _ = torch.max(attn, dim=1, keepdim=True)
  45. agg = torch.cat([avg_attn, max_attn], dim=1)
  46. sig = self.conv_squeeze(agg).sigmoid()
  47. attn = attn1 * sig[:, 0, :, :].unsqueeze(1) + attn2 * sig[:, 1, :, :].unsqueeze(1)
  48. attn = self.conv(attn)
  49. return x * attn
  50. class Attention(nn.Module):
  51. def __init__(self, d_model):
  52. super().__init__()
  53. self.proj_1 = nn.Conv2d(d_model, d_model, 1)
  54. self.activation = nn.GELU()
  55. self.spatial_gating_unit = LSKblock(d_model)
  56. self.proj_2 = nn.Conv2d(d_model, d_model, 1)
  57. def forward(self, x):
  58. shorcut = x.clone()
  59. x = self.proj_1(x)
  60. x = self.activation(x)
  61. x = self.spatial_gating_unit(x)
  62. x = self.proj_2(x)
  63. x = x + shorcut
  64. return x
  65. class Block(nn.Module):
  66. def __init__(self, dim, mlp_ratio=4., drop=0., drop_path=0., act_layer=nn.GELU, norm_cfg=None):
  67. super().__init__()
  68. if norm_cfg:
  69. self.norm1 = nn.BatchNorm2d(norm_cfg, dim)
  70. self.norm2 = nn.BatchNorm2d(norm_cfg, dim)
  71. else:
  72. self.norm1 = nn.BatchNorm2d(dim)
  73. self.norm2 = nn.BatchNorm2d(dim)
  74. self.attn = Attention(dim)
  75. self.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity()
  76. mlp_hidden_dim = int(dim * mlp_ratio)
  77. self.mlp = Mlp(in_features=dim, hidden_features=mlp_hidden_dim, act_layer=act_layer, drop=drop)
  78. layer_scale_init_value = 1e-2
  79. self.layer_scale_1 = nn.Parameter(
  80. layer_scale_init_value * torch.ones((dim)), requires_grad=True)
  81. self.layer_scale_2 = nn.Parameter(
  82. layer_scale_init_value * torch.ones((dim)), requires_grad=True)
  83. def forward(self, x):
  84. x = x + self.drop_path(self.layer_scale_1.unsqueeze(-1).unsqueeze(-1) * self.attn(self.norm1(x)))
  85. x = x + self.drop_path(self.layer_scale_2.unsqueeze(-1).unsqueeze(-1) * self.mlp(self.norm2(x)))
  86. return x
  87. class OverlapPatchEmbed(nn.Module):
  88. """ Image to Patch Embedding
  89. """
  90. def __init__(self, img_size=224, patch_size=7, stride=4, in_chans=3, embed_dim=768, norm_cfg=None):
  91. super().__init__()
  92. patch_size = to_2tuple(patch_size)
  93. self.proj = nn.Conv2d(in_chans, embed_dim, kernel_size=patch_size, stride=stride,
  94. padding=(patch_size[0] // 2, patch_size[1] // 2))
  95. if norm_cfg:
  96. self.norm = nn.BatchNorm2d(norm_cfg, embed_dim)
  97. else:
  98. self.norm = nn.BatchNorm2d(embed_dim)
  99. def forward(self, x):
  100. x = self.proj(x)
  101. _, _, H, W = x.shape
  102. x = self.norm(x)
  103. return x, H, W
  104. class LSKNet(nn.Module):
  105. def __init__(self, factor=0.5, img_size=224, in_chans=3, dim=None, embed_dims=[64, 128, 256, 512],
  106. mlp_ratios=[8, 8, 4, 4], drop_rate=0., drop_path_rate=0., norm_layer=partial(nn.LayerNorm, eps=1e-6),
  107. depths=[3, 4, 6, 3], num_stages=4,
  108. pretrained=None,
  109. init_cfg=None,
  110. norm_cfg=None):
  111. super().__init__()
  112. assert not (init_cfg and pretrained), \
  113. 'init_cfg and pretrained cannot be set at the same time'
  114. if isinstance(pretrained, str):
  115. warnings.warn('DeprecationWarning: pretrained is deprecated, '
  116. 'please use "init_cfg" instead')
  117. self.init_cfg = dict(type='Pretrained', checkpoint=pretrained)
  118. elif pretrained is not None:
  119. raise TypeError('pretrained must be a str or None')
  120. self.depths = depths
  121. self.num_stages = num_stages
  122. embed_dims = [int(dim * factor) for dim in embed_dims]
  123. dpr = [x.item() for x in torch.linspace(0, drop_path_rate, sum(depths))] # stochastic depth decay rule
  124. cur = 0
  125. for i in range(num_stages):
  126. patch_embed = OverlapPatchEmbed(img_size=img_size if i == 0 else img_size // (2 ** (i + 1)),
  127. patch_size=7 if i == 0 else 3,
  128. stride=4 if i == 0 else 2,
  129. in_chans=in_chans if i == 0 else embed_dims[i - 1],
  130. embed_dim=embed_dims[i], norm_cfg=norm_cfg)
  131. block = nn.ModuleList([Block(
  132. dim=embed_dims[i], mlp_ratio=mlp_ratios[i], drop=drop_rate, drop_path=dpr[cur + j], norm_cfg=norm_cfg)
  133. for j in range(depths[i])])
  134. norm = norm_layer(embed_dims[i])
  135. cur += depths[i]
  136. setattr(self, f"patch_embed{i + 1}", patch_embed)
  137. setattr(self, f"block{i + 1}", block)
  138. setattr(self, f"norm{i + 1}", norm)
  139. self.width_list = [i.size(1) for i in self.forward(torch.randn(1, 3, 640, 640))]
  140. def freeze_patch_emb(self):
  141. self.patch_embed1.requires_grad = False
  142. @torch.jit.ignore
  143. def no_weight_decay(self):
  144. return {'pos_embed1', 'pos_embed2', 'pos_embed3', 'pos_embed4', 'cls_token'} # has pos_embed may be better
  145. def get_classifier(self):
  146. return self.head
  147. def reset_classifier(self, num_classes, global_pool=''):
  148. self.num_classes = num_classes
  149. self.head = nn.Linear(self.embed_dim, num_classes) if num_classes > 0 else nn.Identity()
  150. def forward_features(self, x):
  151. B = x.shape[0]
  152. outs = []
  153. for i in range(self.num_stages):
  154. patch_embed = getattr(self, f"patch_embed{i + 1}")
  155. block = getattr(self, f"block{i + 1}")
  156. norm = getattr(self, f"norm{i + 1}")
  157. x, H, W = patch_embed(x)
  158. for blk in block:
  159. x = blk(x)
  160. x = x.flatten(2).transpose(1, 2)
  161. x = norm(x)
  162. x = x.reshape(B, H, W, -1).permute(0, 3, 1, 2).contiguous()
  163. outs.append(x)
  164. return outs
  165. def forward(self, x):
  166. x = self.forward_features(x)
  167. # x = self.head(x)
  168. return x
  169. class DWConv(nn.Module):
  170. def __init__(self, dim=768):
  171. super(DWConv, self).__init__()
  172. self.dwconv = nn.Conv2d(dim, dim, 3, 1, 1, bias=True, groups=dim)
  173. def forward(self, x):
  174. x = self.dwconv(x)
  175. return x
  176. def _conv_filter(state_dict, patch_size=16):
  177. """ convert patch embedding weight from manual patchify + linear proj to conv"""
  178. out_dict = {}
  179. for k, v in state_dict.items():
  180. if 'patch_embed.proj.weight' in k:
  181. v = v.reshape((v.shape[0], 3, patch_size, patch_size))
  182. out_dict[k] = v
  183. return out_dict
  184. def LSKNET_Tiny(factor):
  185. model = LSKNet(factor=factor, depths = [2, 2, 2, 2])
  186. return model
  187. def LSKNET_Large(factor):
  188. model = LSKNet(factor=factor, depths=[3, 4, 6, 3])
  189. return model
  190. if __name__ == '__main__':
  191. model = LSKNET_Large(factor=0.5)
  192. inputs = torch.randn((1, 3, 640, 640))
  193. for i in model(inputs):
  194. print(i.size())


四、手把手教你添加LSKNet

4.1 修改一

第一步还是建立文件,我们找到如下ultralytics/nn文件夹下建立一个目录名字呢就是'Addmodules'文件夹( 用群内的文件的话已经有了无需新建) !然后在其内部建立一个新的py文件将核心代码复制粘贴进去即可


4.2 修改二

第二步我们在该目录下创建一个新的py文件名字为'__init__.py'( 用群内的文件的话已经有了无需新建) ,然后在其内部导入我们的检测头如下图所示。


4.3 修改三

第三步我门中到如下文件'ultralytics/nn/tasks.py'进行导入和注册我们的模块( 用群内的文件的话已经有了无需重新导入直接开始第四步即可)

从今天开始以后的教程就都统一成这个样子了,因为我默认大家用了我群内的文件来进行修改!!


4.4 修改四

添加如下两行代码!!!


4.5 修改五

找到七百多行大概把具体看图片,按照图片来修改就行,添加红框内的部分,注意没有()只是函数名。

  1. elif m in {自行添加对应的模型即可,下面都是一样的}:
  2. m = m(*args)
  3. c2 = m.width_list # 返回通道列表
  4. backbone = True


4.6 修改六

下面的两个红框内都是需要改动的。

  1. if isinstance(c2, list):
  2. m_ = m
  3. m_.backbone = True
  4. else:
  5. m_ = nn.Sequential(*(m(*args) for _ in range(n))) if n > 1 else m(*args) # module
  6. t = str(m)[8:-2].replace('__main__.', '') # module type
  7. m.np = sum(x.numel() for x in m_.parameters()) # number params
  8. m_.i, m_.f, m_.type = i + 4 if backbone else i, f, t # attach index, 'from' index, type


4.7 修改七

如下的也需要修改,全部按照我的来。

代码如下把原先的代码替换了即可。

  1. if verbose:
  2. LOGGER.info(f'{i:>3}{str(f):>20}{n_:>3}{m.np:10.0f} {t:<45}{str(args):<30}') # print
  3. save.extend(x % (i + 4 if backbone else i) for x in ([f] if isinstance(f, int) else f) if x != -1) # append to savelist
  4. layers.append(m_)
  5. if i == 0:
  6. ch = []
  7. if isinstance(c2, list):
  8. ch.extend(c2)
  9. if len(c2) != 5:
  10. ch.insert(0, 0)
  11. else:
  12. ch.append(c2)


4.8 修改八

修改八和前面的都不太一样,需要修改前向传播中的一个部分, 已经离开了parse_model方法了。

可以在图片中开代码行数,没有离开task.py文件都是同一个文件。 同时这个部分有好几个前向传播都很相似,大家不要看错了, 是70多行左右的!!!,同时我后面提供了代码,大家直接复制粘贴即可,有时间我针对这里会出一个视频。

​​

代码如下->

  1. def _predict_once(self, x, profile=False, visualize=False, embed=None):
  2. """
  3. Perform a forward pass through the network.
  4. Args:
  5. x (torch.Tensor): The input tensor to the model.
  6. profile (bool): Print the computation time of each layer if True, defaults to False.
  7. visualize (bool): Save the feature maps of the model if True, defaults to False.
  8. embed (list, optional): A list of feature vectors/embeddings to return.
  9. Returns:
  10. (torch.Tensor): The last output of the model.
  11. """
  12. y, dt, embeddings = [], [], [] # outputs
  13. for m in self.model:
  14. if m.f != -1: # if not from previous layer
  15. x = y[m.f] if isinstance(m.f, int) else [x if j == -1 else y[j] for j in m.f] # from earlier layers
  16. if profile:
  17. self._profile_one_layer(m, x, dt)
  18. if hasattr(m, 'backbone'):
  19. x = m(x)
  20. if len(x) != 5: # 0 - 5
  21. x.insert(0, None)
  22. for index, i in enumerate(x):
  23. if index in self.save:
  24. y.append(i)
  25. else:
  26. y.append(None)
  27. x = x[-1] # 最后一个输出传给下一层
  28. else:
  29. x = m(x) # run
  30. y.append(x if m.i in self.save else None) # save output
  31. if visualize:
  32. feature_visualization(x, m.type, m.i, save_dir=visualize)
  33. if embed and m.i in embed:
  34. embeddings.append(nn.functional.adaptive_avg_pool2d(x, (1, 1)).squeeze(-1).squeeze(-1)) # flatten
  35. if m.i == max(embed):
  36. return torch.unbind(torch.cat(embeddings, 1), dim=0)
  37. return x

到这里就完成了修改部分,但是这里面细节很多,大家千万要注意不要替换多余的代码,导致报错,也不要拉下任何一部,都会导致运行失败,而且报错很难排查!!!很难排查!!!


注意!!! 额外的修改!

关注我的其实都知道,我大部分的修改都是一样的,这个网络需要额外的修改一步,就是s一个参数,将下面的s改为640!!!即可完美运行!!


打印计算量问题解决方案

我们找到如下文件'ultralytics/utils/torch_utils.py'按照如下的图片进行修改,否则容易打印不出来计算量。


注意事项!!!

如果大家在验证的时候报错形状不匹配的错误可以固定 验证集 的图片尺寸,方法如下 ->

找到下面这个文件ultralytics/ models /yolo/detect/train.py然后其中有一个类是DetectionTrainer class中的build_dataset函数中的一个参数rect=mode == 'val'改为rect=False


五、LSKNet的yaml文件

复制如下yaml文件进行运行!!!


5.1 LSKNet的yaml文件版本1

此版本训练信息:YOLO11-LSKNet summary: 405 layers, 2,225,071 parameters, 2,225,055 gradients, 5.9 GFLOPs

使用说明:# 下面 [-1, 1, LSKNet, [0.25]] 参数位置的0.25是通道放缩的系数, YOLOv11N是0.25 YOLOv11S是0.5 YOLOv11M是1. YOLOv11l是1 YOLOv11是1.5大家根据自己训练的YOLO版本设定即可.
# 本文支持版本有  LSKNET_Tiny, LSKNET_Large

  1. # Ultralytics YOLO 🚀, AGPL-3.0 license
  2. # YOLO11 object detection model with P3-P5 outputs. For Usage examples see https://docs.ultralytics.com/tasks/detect
  3. # Parameters
  4. nc: 80 # number of classes
  5. scales: # model compound scaling constants, i.e. 'model=yolo11n.yaml' will call yolo11.yaml with scale 'n'
  6. # [depth, width, max_channels]
  7. n: [0.50, 0.25, 1024] # summary: 319 layers, 2624080 parameters, 2624064 gradients, 6.6 GFLOPs
  8. s: [0.50, 0.50, 1024] # summary: 319 layers, 9458752 parameters, 9458736 gradients, 21.7 GFLOPs
  9. m: [0.50, 1.00, 512] # summary: 409 layers, 20114688 parameters, 20114672 gradients, 68.5 GFLOPs
  10. l: [1.00, 1.00, 512] # summary: 631 layers, 25372160 parameters, 25372144 gradients, 87.6 GFLOPs
  11. x: [1.00, 1.50, 512] # summary: 631 layers, 56966176 parameters, 56966160 gradients, 196.0 GFLOPs
  12. # 下面 [-1, 1, LSKNet, [0.25]] 参数位置的0.25是通道放缩的系数, YOLOv11N是0.25 YOLOv11S是0.5 YOLOv11M是1. YOLOv11l是1 YOLOv111.5大家根据自己训练的YOLO版本设定即可.
  13. # 本文支持版本有 LSKNET_Tiny, LSKNET_Large
  14. # YOLO11n backbone
  15. backbone:
  16. # [from, repeats, module, args]
  17. - [-1, 1, LSKNET_Tiny, [0.25]] # 0-4 P1/2 这里是四层大家不要被yaml文件限制住了思维,不会画图进群看视频.
  18. - [-1, 1, SPPF, [1024, 5]] # 5
  19. - [-1, 2, C2PSA, [1024]] # 6
  20. # YOLO11n head
  21. head:
  22. - [-1, 1, nn.Upsample, [None, 2, "nearest"]]
  23. - [[-1, 3], 1, Concat, [1]] # cat backbone P4
  24. - [-1, 2, C3k2, [512, False]] # 9
  25. - [-1, 1, nn.Upsample, [None, 2, "nearest"]]
  26. - [[-1, 2], 1, Concat, [1]] # cat backbone P3
  27. - [-1, 2, C3k2, [256, False]] # 12 (P3/8-small)
  28. - [-1, 1, Conv, [256, 3, 2]]
  29. - [[-1, 9], 1, Concat, [1]] # cat head P4
  30. - [-1, 2, C3k2, [512, False]] # 15 (P4/16-medium)
  31. - [-1, 1, Conv, [512, 3, 2]]
  32. - [[-1, 6], 1, Concat, [1]] # cat head P5
  33. - [-1, 2, C3k2, [1024, True]] # 18 (P5/32-large)
  34. - [[12, 15, 18], 1, Detect, [nc]] # Detect(P3, P4, P5)


5.2 训练文件

  1. import warnings
  2. warnings.filterwarnings('ignore')
  3. from ultralytics import YOLO
  4. if __name__ == '__main__':
  5. model = YOLO('ultralytics/cfg/models/v8/yolov8-C2f-FasterBlock.yaml')
  6. # model.load('yolov8n.pt') # loading pretrain weights
  7. model.train(data=r'替换数据集yaml文件地址',
  8. # 如果大家任务是其它的'ultralytics/cfg/default.yaml'找到这里修改task可以改成detect, segment, classify, pose
  9. cache=False,
  10. imgsz=640,
  11. epochs=150,
  12. single_cls=False, # 是否是单类别检测
  13. batch=4,
  14. close_mosaic=10,
  15. workers=0,
  16. device='0',
  17. optimizer='SGD', # using SGD
  18. # resume='', # 如过想续训就设置last.pt的地址
  19. amp=False, # 如果出现训练损失为Nan可以关闭amp
  20. project='runs/train',
  21. name='exp',
  22. )


六、成功运行记录

下面是成功运行的截图,已经完成了有1个epochs的训练,图片太大截不全第2个epochs,这里改完之后打印出了点问题,但是不影响任何功能,后期我找时间修复一下这个问题。

​​


七、本文总结

到此本文的正式分享内容就结束了,在这里给大家推荐我的YOLOv11改进有效涨点专栏,本专栏目前为新开的平均质量分98分,后期我会根据各种最新的前沿顶会进行论文复现,也会对一些老的改进机制进行补充, 目前本专栏免费阅读(暂时,大家尽早关注不迷路~) 如果大家觉得本文帮助到你了,订阅本专栏,关注后续更多的更新~

​​