当前位置:   article > 正文

YOLOv9改进策略 | Conv篇 | 模拟人类视觉系统依赖上下文信息的下采样方法ContextGuided(包含二次创新RepNCSPELAN)

YOLOv9改进策略 | Conv篇 | 模拟人类视觉系统依赖上下文信息的下采样方法ContextGuided(包含二次创新RepNCSPELAN)

 一、本文介绍

本文给大家带来的是改进机制是一种替换Conv的模块Context Guided Block (CG block) ,其是在CGNet论文中提出的一种模块,其基本原理是模拟人类视觉系统依赖上下文信息来理解场景。CG block 用于捕获局部特征、周围上下文和全局上下文,并将这些信息融合起来以提高准确性,同时本文的修改方法和之前的普通卷积模块也有所不同,大家需要注意看章节四进行修改。同时欢迎大家订阅本专栏,本专栏每周更新3-5篇最新机制,更有包含我所有改进的文件和交流群提供给大家。同时本专栏目前改进基于yolov9.yaml文件,后期如果官方放出轻量化版本,专栏内所有改进也会同步更新,请大家放心。

专栏地址:YOLOv9有效涨点专栏-持续复现各种顶会内容-有效涨点-全网改进最全的专栏 

目录

 一、本文介绍

二、ContextGuidedBlock_Down模块原理

2.1  ContextGuidedBlock_Down的基本原理

2.2  局部特征提取器

2.3  周围上下文提取器

2.4  联合特征提取器

2.5  全局上下文提取器

三、ContextGuided的核心代码

四、 手把手教你添加ContextGuided(注意看此处)

4.1 ContextGuided添加步骤

4.1.1 修改一

4.1.2 修改二

4.1.3 修改三 

4.1.4 修改四

4.2 ContextGuided的yaml文件和训练截图

4.2.1 ContextGuided的yaml版本一(推荐)

4.2.2 ContextGuided的yaml版本二

4.3 ContextGuided的训练过程截图 

五、本文总结


二、ContextGuidedBlock_Down模块原理

论文地址:官方论文地址

代码地址:官方代码地址


2.1  ContextGuidedBlock_Down的基本原理

Context Guided Block (CG block) 在CGNet中的基本原理是模拟人类视觉系统依赖上下文信息来理解场景。CG block 用于捕获局部特征、周围上下文和全局上下文,并将这些信息融合起来以提高语义分割的准确性。这一模块包含以下部分:

1. 局部特征提取器(floc): 使用标准卷积层学习局部特征。
2. 周围上下文提取器(fsur): 使用空洞/膨胀卷积层来学习更大接收野的周围上下文。
3. 联合特征提取器(fjoi): 通过连接层和批量归一化(BN)以及参数化ReLU(PReLU)操作来融合局部特征和周围上下文的输出,获取联合特征。
4. 全局上下文提取器(fglo):使用全局平均池化层聚合全局上下文,并通过多层感知器来进一步提取全局上下文。然后,使用缩放层以提取的全局上下文对联合特征进行加权,以强调有用的组件并抑制无用的组件。

这个过程是自适应的,因为提取的全局上下文是基于输入图像生成的。CG block 的设计允许CGNet能够有效地从底层到顶层聚合上下文信息,并在语义层面(来自深层)空间层面(来自浅层)捕获上下文信息,这对于语义分割至关重要。

下面就为大家展示了三种用于语义分割的不同架构:

(a) FCN-shape(全卷积网络形状): 此模型遵循图像分类的设计原则,忽略了上下文信息。它可能使用一系列卷积和池化层来处理输入图像,并生成输出,但没有显式地对各个层次的特征周围上下文进行建模。

(b) FCN-CM(全卷积网络-上下文模块): 此模型只在编码阶段后捕获上下文信息,通过执行一个上下文模块来从语义层次提取上下文信息。

(c) 我们提出的CGNet(上下文引导网络): 捕获所有阶段的上下文特征,从语义层次和空间层次两方面进行。

 总结:CGB_Down的设计旨在充分利用局部特征、周围上下文和全局上下文,通过这种结构设计,CGNet能够在局部和全局上下文之间建立联系,这对于准确分类图像中的每个像素至关重要。此外,CGB_Down还采用了残差学习来帮助学习复杂特征并在训练期间改善梯度的反向传播。


2.2  局部特征提取器

局部特征提取器(记为floc(*))是上下文引导块(CG block)的一个组成部分,专门用于学习输入数据中的局部特征。在CGNet的设计中,这个局部特征提取器通过标准的3×3卷积层实现,其目的是从图像中的局部区域提取特征。这些局部特征随后与周围上下文特征结合,形成了网络对各个区域的全面理解,这对于语义分割尤为重要。

CGNet使用的局部特征提取器与周围上下文提取器(fsur(*)一起工作,确保模型不仅能够理解每个像素或局部区域的信息,而且还能理解这些区域在整体上下文中的关系。这种提取器能够捕捉到的细节和局部变化信息对于精确地分类图像中的每个像素至关重要,特别是在需要细粒度预测的任务中,如在复杂场景中区分不同的物体和表面。

CGNet的结构设计还包括减少参数数量,其中局部特征提取器和周围上下文提取器采用了通道卷积(channel-wise convolutions),以减少跨通道的计算成本并大幅节约内存。这种设计允许CGNet即使在资源受限的环境中(如移动设备)也能有效运行,同时保持高准确率和实时性。


2.3  周围上下文提取器

周围上下文提取器f_{sur}(*))在CGNet架构中的作用和原理包括:

1. 提取更广泛的上下文信息:周围上下文提取器使用扩展卷积(例如空洞卷积)来增加感受野的大小,从而捕获更宽广的上下文信息。这允许模型观察到更大区域的特征,而不仅仅是局部的细节。

2. 辅助局部特征理解:通过结合局部特征和周围上下文,f_{sur}(*)能够提供额外的信息,帮助模型更好地理解复杂的场景。例如,在辨识一个物体时,除了物体本身的特征外,它的周围环境也提供了重要的线索。

3. 改进语义分割的准确性:研究表明,周围上下文的信息对于提高语义分割的准确性非常有益。在不同的架构实验中,引入f_{sur}(*)都能显著提升分割的准确率。

4. 在网络的所有块中使用:为了充分利用周围上下文的优势,f_{sur}(*)在CGNet的所有块中都有应用,以保证整个网络都能受益于周围上下文信息的提取。

5. 空间金字塔池化:在一些变体中,f_{sur}(*)可能会采用空间金字塔池化来聚合不同尺度的上下文信息,这有助于模型捕捉从最小的细节到整体布局的不同层面的信息。

总结:通过这些设计,周围上下文提取器加强了CGNet处理各种尺度信息的能力,这在处理高分辨率图像和复杂场景的语义分割任务中尤其重要。 


2.4  联合特征提取器

联合特征提取器f_{joi}(*))在CGNet中的作用是整合由局部特征提取器和周围上下文提取器提取的特征。这些特征分别捕捉到了输入数据的细节(局部特征)和更广阔区域内的信息(周围上下文)。联合特征提取器的设计目的是为了使得网络能够同时考虑局部和上下文信息,从而提高语义分割的准确性。下面是它的一些关键点:

1. 特征融合:联合特征提取器通过连接(concatenation)操作将局部特征和周围上下文特征结合起来,形成一个综合的特征表示。

2. 增强特征表示:联合后的特征通过批量归一化(Batch Normalization, BN)和参数化的线性单元(Parametric ReLU, PReLU)等操作进行进一步的加工,以增强特征表示的能力。

3. 全局上下文的整合:在某些设计中,联合特征还会与全局上下文特征(f_{glo}(*))结合,以利用整个输入图像的信息来进一步优化特征。

联合特征提取器是上下文引导网络实现其高效语义分割能力的关键连接点,它允许网络在局部精细度和全局上下文间达到平衡.

下图为大家展示了上下文引导网络(Context Guided Network, CGNet)的架构。这个网络通过以下阶段处理输入图像来生成预测:

1. Stage 1:包含连续的3x3卷积层,这些层负责提取输入图像的初步特征。

2. Stage 2:由多个CG块组成,数量用"M"表示。每个CG块都结合了局部特征提取器和周围上下文提取器,它们一起工作以捕获更复杂的局部和上下文信息。

3. Stage 3:包含更多的CG块,数量用"N"表示,这一阶段进一步提炼特征,以捕捉更高层次的上下文信息。

4. 1x1 Conv:一个1x1的卷积层用于将特征映射到目标类别的数量,为最终的上采样和分类做准备。

5. 上采样(Upsample):使用上采样或逆卷积操作将特征图尺寸扩大回输入图像的尺寸。

6. 预测(Prediction):最终的预测图,其中每个像素被分配了一个类别标签,展示了对输入图像进行语义分割的结果。

总结:CGNet的设计旨在实现高效的语义分割,通过在网络的不同阶段利用局部和全局上下文信息来提高准确率,同时保持模型的轻量级特性。这使CGNet特别适合于资源受限的设备,如移动设备或嵌入式系统。在图中的预测示例中,可以看到网络已经将不同的交通参与者和背景要素成功地分割出来,用不同的颜色标记不同的类别。


2.5  全局上下文提取器

全局上下文提取器f_{glo}(*))在CGNet中的作用是捕获并利用整个输入图像的全局信息,以增强联合特征提取器学习到的特征。以下是它的基本原理

1. 全局特征汇总:全局上下文提取器通过全局平均池化(Global Average Pooling, GAP)来聚合整个特征图的全局信息。这个步骤产生一个全局特征向量,它捕获了输入图像中每个通道的平均响应。

2. 多层感知机处理:全局特征向量随后通过一个多层感知机(Multilayer Perceptron, MLP)进一步处理。MLP能够学习特征间的复杂非线性关系,进一步细化全局上下文特征。

3. 特征重标定:提取的全局上下文通过缩放层(scale layer)与联合特征结合。这个操作相当于将全局上下文信息作为权重,通道级别地重新标定联合特征,强调有用的特征部分,抑制不重要的特征部分。

4. 自适应性:全局上下文提取器的操作是自适应的,因为提取的全局上下文是根据输入图像生成的,使得网络能够针对不同的图像生成定制化的全局上下文。

5. 提高分割准确性:在消融研究中,使用全局上下文提取器可以提高分割的准确性。这证明了全局上下文在提升模型性能方面的价值。

提供了上下文引导块(Context Guided block)的概览。在图中的全局上下文提取器f_{glo}(*)部分,展示了使用全局平均池化(GAP)来提取全图的上下文信息,然后通过两个全连接层(FC)对这些信息进行进一步的处理。这有助于网络理解整个图像的全局信息,这对于分类图像中的局部区域特别重要,尤其是在这些局部区域的类别可能依赖于全局上下文的情况下。

这些组件共同工作,提高了网络对复杂场景中各种尺度的特征的理解能力,使得CGNet能够更准确地进行语义分割。通过这样的设计,CGNet能够在局部和全局上下文之间建立联系,这对于准确分类图像中的每个像素至关重要。


三、ContextGuided的核心代码

使用方法看第四章,大家需要仔细看章节四的内容。

  1. import torch
  2. import torch.nn as nn
  3. __all__ = ['ContextGuidedBlock_Down', 'RepNCSPELAN4_ContextGuidedBlock']
  4. class ConvBNPReLU(nn.Module):
  5. def __init__(self, nIn, nOut, kSize, stride=1):
  6. """
  7. args:
  8. nIn: number of input channels
  9. nOut: number of output channels
  10. kSize: kernel size
  11. stride: stride rate for down-sampling. Default is 1
  12. """
  13. super().__init__()
  14. if isinstance(kSize, tuple):
  15. kSize = kSize[0]
  16. padding = int((kSize - 1) / 2)
  17. self.conv = nn.Conv2d(nIn, nOut, (kSize, kSize), stride=stride, padding=(padding, padding), bias=False)
  18. self.bn = nn.BatchNorm2d(nOut, eps=1e-03)
  19. self.act = nn.PReLU(nOut)
  20. def forward(self, input):
  21. """
  22. args:
  23. input: input feature map
  24. return: transformed feature map
  25. """
  26. output = self.conv(input)
  27. output = self.bn(output)
  28. output = self.act(output)
  29. return output
  30. class BNPReLU(nn.Module):
  31. def __init__(self, nOut):
  32. """
  33. args:
  34. nOut: channels of output feature maps
  35. """
  36. super().__init__()
  37. self.bn = nn.BatchNorm2d(nOut, eps=1e-03)
  38. self.act = nn.PReLU(nOut)
  39. def forward(self, input):
  40. """
  41. args:
  42. input: input feature map
  43. return: normalized and thresholded feature map
  44. """
  45. output = self.bn(input)
  46. output = self.act(output)
  47. return output
  48. class ConvBN(nn.Module):
  49. def __init__(self, nIn, nOut, kSize, stride=1):
  50. """
  51. args:
  52. nIn: number of input channels
  53. nOut: number of output channels
  54. kSize: kernel size
  55. stride: optinal stide for down-sampling
  56. """
  57. super().__init__()
  58. if isinstance(kSize, tuple):
  59. kSize = kSize[0]
  60. padding = int((kSize - 1) / 2)
  61. self.conv = nn.Conv2d(nIn, nOut, (kSize, kSize), stride=stride, padding=(padding, padding), bias=False)
  62. self.bn = nn.BatchNorm2d(nOut, eps=1e-03)
  63. def forward(self, input):
  64. """
  65. args:
  66. input: input feature map
  67. return: transformed feature map
  68. """
  69. output = self.conv(input)
  70. output = self.bn(output)
  71. return output
  72. class Conv(nn.Module):
  73. def __init__(self, nIn, nOut, kSize, stride=1):
  74. """
  75. args:
  76. nIn: number of input channels
  77. nOut: number of output channels
  78. kSize: kernel size
  79. stride: optional stride rate for down-sampling
  80. """
  81. super().__init__()
  82. if isinstance(kSize, tuple):
  83. kSize = kSize[0]
  84. padding = int((kSize - 1) / 2)
  85. self.conv = nn.Conv2d(nIn, nOut, (kSize, kSize), stride=stride, padding=(padding, padding), bias=False)
  86. def forward(self, input):
  87. """
  88. args:
  89. input: input feature map
  90. return: transformed feature map
  91. """
  92. output = self.conv(input)
  93. return output
  94. class ChannelWiseConv(nn.Module):
  95. def __init__(self, nIn, nOut, kSize, stride=1):
  96. """
  97. Args:
  98. nIn: number of input channels
  99. nOut: number of output channels, default (nIn == nOut)
  100. kSize: kernel size
  101. stride: optional stride rate for down-sampling
  102. """
  103. super().__init__()
  104. if isinstance(kSize, tuple):
  105. kSize = kSize[0]
  106. padding = int((kSize - 1) / 2)
  107. self.conv = nn.Conv2d(nIn, nOut, (kSize, kSize), stride=stride, padding=(padding, padding), groups=nIn,
  108. bias=False)
  109. def forward(self, input):
  110. """
  111. args:
  112. input: input feature map
  113. return: transformed feature map
  114. """
  115. output = self.conv(input)
  116. return output
  117. class DilatedConv(nn.Module):
  118. def __init__(self, nIn, nOut, kSize, stride=1, d=1):
  119. """
  120. args:
  121. nIn: number of input channels
  122. nOut: number of output channels
  123. kSize: kernel size
  124. stride: optional stride rate for down-sampling
  125. d: dilation rate
  126. """
  127. super().__init__()
  128. if isinstance(kSize, tuple):
  129. kSize = kSize[0]
  130. padding = int((kSize - 1) / 2) * d
  131. self.conv = nn.Conv2d(nIn, nOut, (kSize, kSize), stride=stride, padding=(padding, padding), bias=False,
  132. dilation=d)
  133. def forward(self, input):
  134. """
  135. args:
  136. input: input feature map
  137. return: transformed feature map
  138. """
  139. output = self.conv(input)
  140. return output
  141. class ChannelWiseDilatedConv(nn.Module):
  142. def __init__(self, nIn, nOut, kSize, stride=1, d=1):
  143. """
  144. args:
  145. nIn: number of input channels
  146. nOut: number of output channels, default (nIn == nOut)
  147. kSize: kernel size
  148. stride: optional stride rate for down-sampling
  149. d: dilation rate
  150. """
  151. super().__init__()
  152. if isinstance(kSize, tuple):
  153. kSize = kSize[0]
  154. padding = int((kSize - 1) / 2) * d
  155. self.conv = nn.Conv2d(nIn, nOut, (kSize, kSize), stride=stride, padding=(padding, padding), groups=nIn,
  156. bias=False, dilation=d)
  157. def forward(self, input):
  158. """
  159. args:
  160. input: input feature map
  161. return: transformed feature map
  162. """
  163. output = self.conv(input)
  164. return output
  165. class FGlo(nn.Module):
  166. """
  167. the FGlo class is employed to refine the joint feature of both local feature and surrounding context.
  168. """
  169. def __init__(self, channel, reduction=16):
  170. super(FGlo, self).__init__()
  171. self.avg_pool = nn.AdaptiveAvgPool2d(1)
  172. self.fc = nn.Sequential(
  173. nn.Linear(channel, channel // reduction),
  174. nn.ReLU(inplace=True),
  175. nn.Linear(channel // reduction, channel),
  176. nn.Sigmoid()
  177. )
  178. def forward(self, x):
  179. b, c, _, _ = x.size()
  180. y = self.avg_pool(x).view(b, c)
  181. y = self.fc(y).view(b, c, 1, 1)
  182. return x * y
  183. class ContextGuidedBlock_Down(nn.Module):
  184. """
  185. the size of feature map divided 2, (H,W,C)---->(H/2, W/2, 2C)
  186. """
  187. def __init__(self, nIn, dilation_rate=2, reduction=16):
  188. """
  189. args:
  190. nIn: the channel of input feature map
  191. nOut: the channel of output feature map, and nOut=2*nIn
  192. """
  193. super().__init__()
  194. nOut = nIn
  195. self.conv1x1 = ConvBNPReLU(nIn, nOut, 3, 2) # size/2, channel: nIn--->nOut
  196. self.F_loc = ChannelWiseConv(nOut, nOut, 3, 1)
  197. self.F_sur = ChannelWiseDilatedConv(nOut, nOut, 3, 1, dilation_rate)
  198. self.bn = nn.BatchNorm2d(2 * nOut, eps=1e-3)
  199. self.act = nn.PReLU(2 * nOut)
  200. self.reduce = Conv(2 * nOut, nOut, 1, 1) # reduce dimension: 2*nOut--->nOut
  201. self.F_glo = FGlo(nOut, reduction)
  202. def forward(self, input):
  203. output = self.conv1x1(input)
  204. loc = self.F_loc(output)
  205. sur = self.F_sur(output)
  206. joi_feat = torch.cat([loc, sur], 1) # the joint feature
  207. joi_feat = self.bn(joi_feat)
  208. joi_feat = self.act(joi_feat)
  209. joi_feat = self.reduce(joi_feat) # channel= nOut
  210. output = self.F_glo(joi_feat) # F_glo is employed to refine the joint feature
  211. return output
  212. class ContextGuidedBlock(nn.Module):
  213. def __init__(self, nIn, nOut, dilation_rate=2, reduction=16, add=True):
  214. """
  215. args:
  216. nIn: number of input channels
  217. nOut: number of output channels,
  218. add: if true, residual learning
  219. """
  220. super().__init__()
  221. n = int(nOut / 2)
  222. self.conv1x1 = ConvBNPReLU(nIn, n, 1, 1) # 1x1 Conv is employed to reduce the computation
  223. self.F_loc = ChannelWiseConv(n, n, 3, 1) # local feature
  224. self.F_sur = ChannelWiseDilatedConv(n, n, 3, 1, dilation_rate) # surrounding context
  225. self.bn_prelu = BNPReLU(nOut)
  226. self.add = add
  227. self.F_glo = FGlo(nOut, reduction)
  228. def forward(self, input):
  229. output = self.conv1x1(input)
  230. loc = self.F_loc(output)
  231. sur = self.F_sur(output)
  232. joi_feat = torch.cat([loc, sur], 1)
  233. joi_feat = self.bn_prelu(joi_feat)
  234. output = self.F_glo(joi_feat) # F_glo is employed to refine the joint feature
  235. # if residual version
  236. if self.add:
  237. output = input + output
  238. return output
  239. def autopad(k, p=None, d=1): # kernel, padding, dilation
  240. # Pad to 'same' shape outputs
  241. if d > 1:
  242. k = d * (k - 1) + 1 if isinstance(k, int) else [d * (x - 1) + 1 for x in k] # actual kernel-size
  243. if p is None:
  244. p = k // 2 if isinstance(k, int) else [x // 2 for x in k] # auto-pad
  245. return p
  246. class Conv(nn.Module):
  247. # Standard convolution with args(ch_in, ch_out, kernel, stride, padding, groups, dilation, activation)
  248. default_act = nn.SiLU() # default activation
  249. def __init__(self, c1, c2, k=1, s=1, p=None, g=1, d=1, act=True):
  250. super().__init__()
  251. self.conv = nn.Conv2d(c1, c2, k, s, autopad(k, p, d), groups=g, dilation=d, bias=False)
  252. self.bn = nn.BatchNorm2d(c2)
  253. self.act = self.default_act if act is True else act if isinstance(act, nn.Module) else nn.Identity()
  254. def forward(self, x):
  255. return self.act(self.bn(self.conv(x)))
  256. def forward_fuse(self, x):
  257. return self.act(self.conv(x))
  258. class RepNBottleneck(nn.Module):
  259. # Standard bottleneck
  260. def __init__(self, c1, c2, shortcut=True, g=1, k=(3, 3), e=0.5): # ch_in, ch_out, shortcut, kernels, groups, expand
  261. super().__init__()
  262. c_ = int(c2 * e) # hidden channels
  263. self.cv1 = ContextGuidedBlock(c1, c_)
  264. self.cv2 = Conv(c_, c2, k[1], 1, g=g)
  265. self.add = shortcut and c1 == c2
  266. def forward(self, x):
  267. return x + self.cv2(self.cv1(x)) if self.add else self.cv2(self.cv1(x))
  268. class RepNCSP(nn.Module):
  269. # CSP Bottleneck with 3 convolutions
  270. def __init__(self, c1, c2, n=1, shortcut=True, g=1, e=0.5): # ch_in, ch_out, number, shortcut, groups, expansion
  271. super().__init__()
  272. c_ = int(c2 * e) # hidden channels
  273. self.cv1 = Conv(c1, c_, 1, 1)
  274. self.cv2 = Conv(c1, c_, 1, 1)
  275. self.cv3 = Conv(2 * c_, c2, 1) # optional act=FReLU(c2)
  276. self.m = nn.Sequential(*(RepNBottleneck(c_, c_, shortcut, g, e=1.0) for _ in range(n)))
  277. def forward(self, x):
  278. return self.cv3(torch.cat((self.m(self.cv1(x)), self.cv2(x)), 1))
  279. class RepNCSPELAN4_ContextGuidedBlock(nn.Module):
  280. # csp-elan
  281. def __init__(self, c1, c2, c3, c4, c5=1): # ch_in, ch_out, number, shortcut, groups, expansion
  282. super().__init__()
  283. self.c = c3//2
  284. self.cv1 = Conv(c1, c3, 1, 1)
  285. self.cv2 = nn.Sequential(RepNCSP(c3//2, c4, c5), Conv(c4, c4, 3, 1))
  286. self.cv3 = nn.Sequential(RepNCSP(c4, c4, c5), Conv(c4, c4, 3, 1))
  287. self.cv4 = Conv(c3+(2*c4), c2, 1, 1)
  288. def forward(self, x):
  289. y = list(self.cv1(x).chunk(2, 1))
  290. y.extend((m(y[-1])) for m in [self.cv2, self.cv3])
  291. return self.cv4(torch.cat(y, 1))
  292. def forward_split(self, x):
  293. y = list(self.cv1(x).split((self.c, self.c), 1))
  294. y.extend(m(y[-1]) for m in [self.cv2, self.cv3])
  295. return self.cv4(torch.cat(y, 1))
  296. if __name__ == "__main__":
  297. # Generating Sample image
  298. image_size = (1, 64, 240, 240)
  299. image = torch.rand(*image_size)
  300. # Model
  301. mobilenet_v3 = RepNCSPELAN4_ContextGuidedBlock(64, 64, 32, 32, 1)
  302. out = mobilenet_v3(image)
  303. print(out.size())


四、 手把手教你添加ContextGuided(注意看此处)

4.1 ContextGuided添加步骤

4.1.1 修改一

首先我们找到如下的目录'yolov9-main/models',然后在这个目录下在创建一个新的目录然后这个就是存储改进的仓库,大家可以在这里新建所有的改进的py文件,对应改进的文件名字可以根据你自己的习惯起(不影响任何但是下面导入的时候记住改成你对应的即可),然后将ContextGuided的核心代码复制进去。


4.1.2 修改二

然后在新建的目录里面我们在新建一个__init__.py文件(此文件大家只需要建立一个即可),然后我们在里面添加导入我们模块的代码。注意标记一个'.'其作用是标记当前目录。


4.1.3 修改三 

然后我们找到如下文件''models/yolo.py''在开头的地方导入我们的模块按照如下修改->

(如果你看了我多个改进机制此处只需要添加一个即可,无需重复添加)

注意的添加位置要放在common的导入上面!!!!!

​​​​​


4.1.4 修改四

然后我们找到''models/yolo.py''文件中的parse_model方法,按照如下修改->

  1. elif m in {ContextGuidedBlock_Down}:
  2. c2 = ch[f]
  3. args = [c2, *args]

到此就修改完成了,复制下面的ymal文件即可运行。


4.2 ContextGuided的yaml文件和训练截图

下面推荐几个版本的yaml文件给大家,大家可以复制进行训练,但是组合用很多具体那种最有效果都不一定,针对不同的数据集效果也不一样,我不可能每一种都做实验,所以我下面推荐了几种我自己认为可能有效果的配合方式,你也可以自己进行组合。


4.2.1 ContextGuided的yaml版本一(推荐)

下面的添加ContextGuided是我实验结果的版本,

  1. # YOLOv9
  2. # parameters
  3. nc: 80 # number of classes
  4. depth_multiple: 1 # model depth multiple
  5. width_multiple: 1 # layer channel multiple
  6. #activation: nn.LeakyReLU(0.1)
  7. #activation: nn.ReLU()
  8. # anchors
  9. anchors: 3
  10. # YOLOv9 backbone
  11. backbone:
  12. [
  13. [-1, 1, Silence, []],
  14. # conv down
  15. [-1, 1, Conv, [64, 3, 2]], # 1-P1/2
  16. # conv down
  17. [-1, 1, ContextGuidedBlock_Down, []], # 2-P2/4
  18. # elan-1 block
  19. [-1, 1, RepNCSPELAN4, [256, 128, 64, 1]], # 3
  20. # conv down
  21. [-1, 1, ContextGuidedBlock_Down, []], # 4-P3/8
  22. # elan-2 block
  23. [-1, 1, RepNCSPELAN4, [512, 256, 128, 1]], # 5
  24. # conv down
  25. [-1, 1, ContextGuidedBlock_Down, []], # 6-P4/16
  26. # elan-2 block
  27. [-1, 1, RepNCSPELAN4, [512, 512, 256, 1]], # 7
  28. # conv down
  29. [-1, 1, ContextGuidedBlock_Down, []], # 8-P5/32
  30. # elan-2 block
  31. [-1, 1, RepNCSPELAN4, [512, 512, 256, 1]], # 9
  32. ]
  33. # YOLOv9 head
  34. head:
  35. [
  36. # elan-spp block
  37. [-1, 1, SPPELAN, [512, 256]], # 10
  38. # up-concat merge
  39. [-1, 1, nn.Upsample, [None, 2, 'nearest']],
  40. [[-1, 7], 1, Concat, [1]], # cat backbone P4
  41. # elan-2 block
  42. [-1, 1, RepNCSPELAN4, [512, 512, 256, 1]], # 13
  43. # up-concat merge
  44. [-1, 1, nn.Upsample, [None, 2, 'nearest']],
  45. [[-1, 5], 1, Concat, [1]], # cat backbone P3
  46. # elan-2 block
  47. [-1, 1, RepNCSPELAN4, [256, 256, 128, 1]], # 16 (P3/8-small)
  48. # conv-down merge
  49. [-1, 1, ContextGuidedBlock_Down, []],
  50. [[-1, 13], 1, Concat, [1]], # cat head P4
  51. # elan-2 block
  52. [-1, 1, RepNCSPELAN4, [512, 512, 256, 1]], # 19 (P4/16-medium)
  53. # conv-down merge
  54. [-1, 1, ContextGuidedBlock_Down, []],
  55. [[-1, 10], 1, Concat, [1]], # cat head P5
  56. # elan-2 block
  57. [-1, 1, RepNCSPELAN4, [512, 512, 256, 1]], # 22 (P5/32-large)
  58. # routing
  59. [5, 1, CBLinear, [[256]]], # 23
  60. [7, 1, CBLinear, [[256, 512]]], # 24
  61. [9, 1, CBLinear, [[256, 512, 512]]], # 25
  62. # conv down
  63. [0, 1, Conv, [64, 3, 2]], # 26-P1/2
  64. # conv down
  65. [-1, 1, ContextGuidedBlock_Down, []], # 27-P2/4
  66. # elan-1 block
  67. [-1, 1, RepNCSPELAN4, [256, 128, 64, 1]], # 28
  68. # conv down fuse
  69. [-1, 1, Conv, [256, 3, 2]], # 29-P3/8
  70. [[23, 24, 25, -1], 1, CBFuse, [[0, 0, 0]]], # 30
  71. # elan-2 block
  72. [-1, 1, RepNCSPELAN4, [512, 256, 128, 1]], # 31
  73. # conv down fuse
  74. [-1, 1, ContextGuidedBlock_Down, []], # 32-P4/16
  75. [[24, 25, -1], 1, CBFuse, [[1, 1]]], # 33
  76. # elan-2 block
  77. [-1, 1, RepNCSPELAN4, [512, 512, 256, 1]], # 34
  78. # conv down fuse
  79. [-1, 1, ContextGuidedBlock_Down, []], # 35-P5/32
  80. [[25, -1], 1, CBFuse, [[2]]], # 36
  81. # elan-2 block
  82. [-1, 1, RepNCSPELAN4, [512, 512, 256, 1]], # 37
  83. # detect
  84. [[31, 34, 37, 16, 19, 22], 1, DualDDetect, [nc]], # DualDDetect(A3, A4, A5, P3, P4, P5)
  85. ]


4.2.2 ContextGuided的yaml版本二

添加的版本二具体那种适合你需要大家自己多做实验来尝试。

  1. # YOLOv9
  2. # parameters
  3. nc: 80 # number of classes
  4. depth_multiple: 1 # model depth multiple
  5. width_multiple: 1 # layer channel multiple
  6. #activation: nn.LeakyReLU(0.1)
  7. #activation: nn.ReLU()
  8. # anchors
  9. anchors: 3
  10. # YOLOv9 backbone
  11. backbone:
  12. [
  13. [-1, 1, Silence, []],
  14. # conv down
  15. [-1, 1, Conv, [64, 3, 2]], # 1-P1/2
  16. # conv down
  17. [-1, 1, ContextGuidedBlock_Down, []], # 2-P2/4
  18. # elan-1 block
  19. [-1, 1, RepNCSPELAN4, [256, 128, 64, 1]], # 3
  20. # conv down
  21. [-1, 1, ContextGuidedBlock_Down, []], # 4-P3/8
  22. # elan-2 block
  23. [-1, 1, RepNCSPELAN4, [512, 256, 128, 1]], # 5
  24. # conv down
  25. [-1, 1, ContextGuidedBlock_Down, []], # 6-P4/16
  26. # elan-2 block
  27. [-1, 1, RepNCSPELAN4, [512, 512, 256, 1]], # 7
  28. # conv down
  29. [-1, 1, ContextGuidedBlock_Down, []], # 8-P5/32
  30. # elan-2 block
  31. [-1, 1, RepNCSPELAN4, [512, 512, 256, 1]], # 9
  32. ]
  33. # YOLOv9 head
  34. head:
  35. [
  36. # elan-spp block
  37. [-1, 1, SPPELAN, [512, 256]], # 10
  38. # up-concat merge
  39. [-1, 1, nn.Upsample, [None, 2, 'nearest']],
  40. [[-1, 7], 1, Concat, [1]], # cat backbone P4
  41. # elan-2 block
  42. [-1, 1, RepNCSPELAN4, [512, 512, 256, 1]], # 13
  43. # up-concat merge
  44. [-1, 1, nn.Upsample, [None, 2, 'nearest']],
  45. [[-1, 5], 1, Concat, [1]], # cat backbone P3
  46. # elan-2 block
  47. [-1, 1, RepNCSPELAN4, [256, 256, 128, 1]], # 16 (P3/8-small)
  48. # conv-down merge
  49. [-1, 1, ContextGuidedBlock_Down, []],
  50. [[-1, 13], 1, Concat, [1]], # cat head P4
  51. # elan-2 block
  52. [-1, 1, RepNCSPELAN4, [512, 512, 256, 1]], # 19 (P4/16-medium)
  53. # conv-down merge
  54. [-1, 1, ContextGuidedBlock_Down, []],
  55. [[-1, 10], 1, Concat, [1]], # cat head P5
  56. # elan-2 block
  57. [-1, 1, RepNCSPELAN4, [512, 512, 256, 1]], # 22 (P5/32-large)
  58. # routing
  59. [5, 1, CBLinear, [[256]]], # 23
  60. [7, 1, CBLinear, [[256, 512]]], # 24
  61. [9, 1, CBLinear, [[256, 512, 512]]], # 25
  62. # conv down
  63. [0, 1, Conv, [64, 3, 2]], # 26-P1/2
  64. # conv down
  65. [-1, 1, ContextGuidedBlock_Down, []], # 27-P2/4
  66. # elan-1 block
  67. [-1, 1, RepNCSPELAN4, [256, 128, 64, 1]], # 28
  68. # conv down fuse
  69. [-1, 1, Conv, [256, 3, 2]], # 29-P3/8
  70. [[23, 24, 25, -1], 1, CBFuse, [[0, 0, 0]]], # 30
  71. # elan-2 block
  72. [-1, 1, RepNCSPELAN4, [512, 256, 128, 1]], # 31
  73. # conv down fuse
  74. [-1, 1, ContextGuidedBlock_Down, []], # 32-P4/16
  75. [[24, 25, -1], 1, CBFuse, [[1, 1]]], # 33
  76. # elan-2 block
  77. [-1, 1, RepNCSPELAN4, [512, 512, 256, 1]], # 34
  78. # conv down fuse
  79. [-1, 1, ContextGuidedBlock_Down, []], # 35-P5/32
  80. [[25, -1], 1, CBFuse, [[2]]], # 36
  81. # elan-2 block
  82. [-1, 1, RepNCSPELAN4, [512, 512, 256, 1]], # 37
  83. # detect
  84. [[31, 34, 37, 16, 19, 22], 1, DualDDetect, [nc]], # DualDDetect(A3, A4, A5, P3, P4, P5)
  85. ]


4.3 ContextGuided的训练过程截图 

大家可以看下面的运行结果和添加的位置所以不存在我发的代码不全或者运行不了的问题大家有问题也可以在评论区评论我看到都会为大家解答(我知道的)。

​​​​​​


五、本文总结

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

希望大家阅读完以后可以给文章点点赞和评论支持一下这样购买专栏的人越多群内人越多大家交流的机会就更多了。  

专栏地址:YOLOv9有效涨点专栏-持续复现各种顶会内容-有效涨点-全网改进最全的专栏 

​​

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/480168
推荐阅读
相关标签
  

闽ICP备14008679号