当前位置:   article > 正文

YOLOV8改进-C2f添加Deformable Conv V2_deformable conv v2 yolov8

deformable conv v2 yolov8

目录

1 Deformable Conv V2介绍

2 YOLOV8添加Deformable Conv V2

2.1 代码添加到Blocks

2.1.1 C2f_DCN代码

2.1.2 加入_all_导入

2.1.3 加入modules导入

2.2 添加至运行模块tasks

2.2.1 导入包

2.2.2 解析参数添加

2.3 在_init_中增加名称

2.4 模型配置文件yaml替换

1 Deformable Conv V2介绍

论文地址:https://arxiv.org/abs/1811.11168https://arxiv.org/abs/1811.11168

        DCN v1根据输入特征学习到的偏移量,改变了卷积的采样位置,使得其具有更强的适应物体几何变化的能力,其采样位置更接近物体的真实结构,但有部分采样点超出了感兴趣区域,导致提取的特征受到无关图像内容的影响。而V2堆叠更多可变形卷积层,引入调制机制,提出了一种特征模拟方案,指导网络训练。

2 YOLOV8添加Deformable Conv V2

2.1 代码添加到Blocks.py

        Deformable Conv V2添加到C2f中,形成C2f_DCN。

2.1.1 C2f_DCN代码

        C2f_DCN代码复制到block路径下与C2F路径一致,在ultralytics/nn/modules/block.py,其中包括DCNv2,Bottleneck_DCN,C2f_DCN。

  1. import math
  2. import torch
  3. import torch.nn as nn
  4. class DCNv2(nn.Module):
  5. def __init__(self, in_channels, out_channels, kernel_size, stride=1,
  6. padding=1, dilation=1, groups=1, deformable_groups=1):
  7. super(DCNv2, self).__init__()
  8. self.in_channels = in_channels
  9. self.out_channels = out_channels
  10. self.kernel_size = (kernel_size, kernel_size)
  11. self.stride = (stride, stride)
  12. self.padding = (padding, padding)
  13. self.dilation = (dilation, dilation)
  14. self.groups = groups
  15. self.deformable_groups = deformable_groups
  16. self.weight = nn.Parameter(
  17. torch.empty(out_channels, in_channels, *self.kernel_size)
  18. )
  19. self.bias = nn.Parameter(torch.empty(out_channels))
  20. out_channels_offset_mask = (self.deformable_groups * 3 *
  21. self.kernel_size[0] * self.kernel_size[1])
  22. self.conv_offset_mask = nn.Conv2d(
  23. self.in_channels,
  24. out_channels_offset_mask,
  25. kernel_size=self.kernel_size,
  26. stride=self.stride,
  27. padding=self.padding,
  28. bias=True,
  29. )
  30. self.bn = nn.BatchNorm2d(out_channels)
  31. self.act = Conv.default_act
  32. self.reset_parameters()
  33. def forward(self, x):
  34. offset_mask = self.conv_offset_mask(x)
  35. o1, o2, mask = torch.chunk(offset_mask, 3, dim=1)
  36. offset = torch.cat((o1, o2), dim=1)
  37. mask = torch.sigmoid(mask)
  38. x = torch.ops.torchvision.deform_conv2d(
  39. x,
  40. self.weight,
  41. offset,
  42. mask,
  43. self.bias,
  44. self.stride[0], self.stride[1],
  45. self.padding[0], self.padding[1],
  46. self.dilation[0], self.dilation[1],
  47. self.groups,
  48. self.deformable_groups,
  49. True
  50. )
  51. x = self.bn(x)
  52. x = self.act(x)
  53. return x
  54. def reset_parameters(self):
  55. n = self.in_channels
  56. for k in self.kernel_size:
  57. n *= k
  58. std = 1. / math.sqrt(n)
  59. self.weight.data.uniform_(-std, std)
  60. self.bias.data.zero_()
  61. self.conv_offset_mask.weight.data.zero_()
  62. self.conv_offset_mask.bias.data.zero_()
  63. class Bottleneck_DCN(nn.Module):
  64. # Standard bottleneck with DCN
  65. def __init__(self, c1, c2, shortcut=True, g=1, k=(3, 3), e=0.5): # ch_in, ch_out, shortcut, groups, kernels, expand
  66. super().__init__()
  67. c_ = int(c2 * e) # hidden channels
  68. if k[0] == 3:
  69. self.cv1 = DCNv2(c1, c_, k[0], 1)
  70. else:
  71. self.cv1 = Conv(c1, c_, k[0], 1)
  72. if k[1] == 3:
  73. self.cv2 = DCNv2(c_, c2, k[1], 1, groups=g)
  74. else:
  75. self.cv2 = Conv(c_, c2, k[1], 1, g=g)
  76. self.add = shortcut and c1 == c2
  77. def forward(self, x):
  78. return x + self.cv2(self.cv1(x)) if self.add else self.cv2(self.cv1(x))
  79. class C2f_DCN(nn.Module):
  80. # CSP Bottleneck with 2 convolutions
  81. def __init__(self, c1, c2, n=1, shortcut=False, g=1, e=0.5): # ch_in, ch_out, number, shortcut, groups, expansion
  82. super().__init__()
  83. self.c = int(c2 * e) # hidden channels
  84. self.cv1 = Conv(c1, 2 * self.c, 1, 1)
  85. self.cv2 = Conv((2 + n) * self.c, c2, 1) # optional act=FReLU(c2)
  86. self.m = nn.ModuleList(Bottleneck_DCN(self.c, self.c, shortcut, g, k=(3, 3), e=1.0) for _ in range(n))
  87. def forward(self, x):
  88. y = list(self.cv1(x).split((self.c, self.c), 1))
  89. y.extend(m(y[-1]) for m in self.m)
  90. return self.cv2(torch.cat(y, 1))

2.1.2 在_all_导入

        还是在block.py路径下,添加C2f_DCN

  1. __all__ = [
  2. 'DFL', 'HGBlock', 'HGStem', 'SPP', 'SPPF', 'C1', 'C2', 'C3', 'C2f', 'C3x', 'C3TR', 'C3Ghost', 'GhostBottleneck',
  3. 'Bottleneck', 'BottleneckCSP', 'Proto', 'RepC3',
  4. 'C2f_DCN','C2f_DSConv']

2.1.3 在modules.py导入

        路径D:\learn\sdxx\mbjc\ultralytics\ultralytics\nn\modules\__init__.py导入C2f_DCN。

  1. from .block import (C1, C2, C3, C3TR, DFL, SPP, SPPF, Bottleneck, BottleneckCSP, C2f, C3Ghost, C3x, GhostBottleneck,
  2. HGBlock, HGStem, Proto, RepC3,
  3. C2f_DCN)#自己加的
  1. __all__ = [
  2. 'Conv', 'LightConv', 'RepConv', 'DWConv', 'DWConvTranspose2d', 'ConvTranspose', 'Focus', 'GhostConv',
  3. 'ChannelAttention', 'SpatialAttention', 'CBAM', 'Concat', 'TransformerLayer', 'TransformerBlock', 'MLPBlock',
  4. 'LayerNorm2d', 'DFL', 'HGBlock', 'HGStem', 'SPP', 'SPPF', 'C1', 'C2', 'C3', 'C2f', 'C3x', 'C3TR', 'C3Ghost',
  5. 'GhostBottleneck', 'Bottleneck', 'BottleneckCSP', 'Proto', 'Detect', 'Segment', 'Pose', 'Classify',
  6. 'TransformerEncoderLayer', 'RepC3', 'RTDETRDecoder', 'AIFI', 'DeformableTransformerDecoder',
  7. 'DeformableTransformerDecoderLayer', 'MSDeformAttn', 'MLP','deattn',
  8. 'C2f_DCN']

2.2 添加至运行模块tasks.py

        将模块名称加入到tasks.py中,路径在ultralytics/nn/tasks.py。

2.2.1 导入包

  1. from ultralytics.nn.modules import (AIFI, C1, C2, C3, C3TR, SPP, SPPF, Bottleneck, BottleneckCSP, C2f, C3Ghost, C3x,
  2. Classify, Concat, Conv, ConvTranspose, Detect, DWConv, DWConvTranspose2d, Focus,
  3. GhostBottleneck, GhostConv, HGBlock, HGStem, Pose, RepC3, RepConv, RTDETRDecoder,
  4. Segment,CBAM,C2f_DCN)

2.2.2 解析参数

        在task.py下面def parse_model中加入C2f_DCN。这两个代码中加入C2f_DCN。
这代码是传入模块的通道数。
  1. if m in (Classify, Conv, ConvTranspose, GhostConv, Bottleneck, GhostBottleneck, SPP, SPPF, DWConv, Focus,
  2. BottleneckCSP, C1, C2, C2f, C3, C3TR, C3Ghost, nn.ConvTranspose2d, DWConvTranspose2d, C3x, RepC3,BasicRFB_a,C2f_DCN):

这个代码模块进行多次使用

if m in (BottleneckCSP, C1, C2, C2f, C3, C3TR, C3Ghost, C3x, RepC3,C2f_DCN):

2.3 在_init_中增加名称

        C2f_DCN是block中的一个,在ultralytics/nn/modules/__init__.py路径下,增加导入包,以及增加名称。
  1. from .block import (C1, C2, C3, C3TR, DFL, SPP, SPPF, Bottleneck, BottleneckCSP, C2f, C3Ghost, C3x, GhostBottleneck,
  2. HGBlock, HGStem, Proto, RepC3,C2f_DCN)
  1. __all__ = [
  2. 'Conv', 'LightConv', 'RepConv', 'DWConv', 'DWConvTranspose2d', 'ConvTranspose', 'Focus', 'GhostConv',
  3. 'ChannelAttention', 'SpatialAttention', 'CBAM', 'Concat', 'TransformerLayer', 'TransformerBlock', 'MLPBlock',
  4. 'LayerNorm2d', 'DFL', 'HGBlock', 'HGStem', 'SPP', 'SPPF', 'C1', 'C2', 'C3', 'C2f', 'C3x', 'C3TR', 'C3Ghost',
  5. 'GhostBottleneck', 'Bottleneck', 'BottleneckCSP', 'Proto', 'Detect', 'Segment', 'Pose', 'Classify',
  6. 'TransformerEncoderLayer', 'RepC3', 'RTDETRDecoder', 'AIFI', 'DeformableTransformerDecoder',
  7. 'DeformableTransformerDecoderLayer', 'MSDeformAttn', 'MLP','deattn','C2f_DCN']

2.4 模型配置文件yaml替换

        在ultralytics/models/v8中yaml配置文件中,将任意的C2f改为C2f_DCN,通道多参数就多。

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