赞
踩
目录
论文地址:https://arxiv.org/abs/1811.11168https://arxiv.org/abs/1811.11168
DCN v1根据输入特征学习到的偏移量,改变了卷积的采样位置,使得其具有更强的适应物体几何变化的能力,其采样位置更接近物体的真实结构,但有部分采样点超出了感兴趣区域,导致提取的特征受到无关图像内容的影响。而V2堆叠更多可变形卷积层,引入调制机制,提出了一种特征模拟方案,指导网络训练。
Deformable Conv V2添加到C2f中,形成C2f_DCN。
C2f_DCN代码复制到block路径下与C2F路径一致,在ultralytics/nn/modules/block.py,其中包括DCNv2,Bottleneck_DCN,C2f_DCN。
- import math
- import torch
- import torch.nn as nn
- class DCNv2(nn.Module):
- def __init__(self, in_channels, out_channels, kernel_size, stride=1,
- padding=1, dilation=1, groups=1, deformable_groups=1):
- super(DCNv2, self).__init__()
-
- self.in_channels = in_channels
- self.out_channels = out_channels
- self.kernel_size = (kernel_size, kernel_size)
- self.stride = (stride, stride)
- self.padding = (padding, padding)
- self.dilation = (dilation, dilation)
- self.groups = groups
- self.deformable_groups = deformable_groups
-
- self.weight = nn.Parameter(
- torch.empty(out_channels, in_channels, *self.kernel_size)
- )
- self.bias = nn.Parameter(torch.empty(out_channels))
-
- out_channels_offset_mask = (self.deformable_groups * 3 *
- self.kernel_size[0] * self.kernel_size[1])
- self.conv_offset_mask = nn.Conv2d(
- self.in_channels,
- out_channels_offset_mask,
- kernel_size=self.kernel_size,
- stride=self.stride,
- padding=self.padding,
- bias=True,
- )
- self.bn = nn.BatchNorm2d(out_channels)
- self.act = Conv.default_act
- self.reset_parameters()
-
- def forward(self, x):
- offset_mask = self.conv_offset_mask(x)
- o1, o2, mask = torch.chunk(offset_mask, 3, dim=1)
- offset = torch.cat((o1, o2), dim=1)
- mask = torch.sigmoid(mask)
- x = torch.ops.torchvision.deform_conv2d(
- x,
- self.weight,
- offset,
- mask,
- self.bias,
- self.stride[0], self.stride[1],
- self.padding[0], self.padding[1],
- self.dilation[0], self.dilation[1],
- self.groups,
- self.deformable_groups,
- True
- )
- x = self.bn(x)
- x = self.act(x)
- return x
-
- def reset_parameters(self):
- n = self.in_channels
- for k in self.kernel_size:
- n *= k
- std = 1. / math.sqrt(n)
- self.weight.data.uniform_(-std, std)
- self.bias.data.zero_()
- self.conv_offset_mask.weight.data.zero_()
- self.conv_offset_mask.bias.data.zero_()
-
- class Bottleneck_DCN(nn.Module):
- # Standard bottleneck with DCN
- def __init__(self, c1, c2, shortcut=True, g=1, k=(3, 3), e=0.5): # ch_in, ch_out, shortcut, groups, kernels, expand
- super().__init__()
- c_ = int(c2 * e) # hidden channels
- if k[0] == 3:
- self.cv1 = DCNv2(c1, c_, k[0], 1)
- else:
- self.cv1 = Conv(c1, c_, k[0], 1)
- if k[1] == 3:
- self.cv2 = DCNv2(c_, c2, k[1], 1, groups=g)
- else:
- self.cv2 = Conv(c_, c2, k[1], 1, g=g)
- self.add = shortcut and c1 == c2
-
- def forward(self, x):
- return x + self.cv2(self.cv1(x)) if self.add else self.cv2(self.cv1(x))
-
- class C2f_DCN(nn.Module):
- # CSP Bottleneck with 2 convolutions
- def __init__(self, c1, c2, n=1, shortcut=False, g=1, e=0.5): # ch_in, ch_out, number, shortcut, groups, expansion
- super().__init__()
- self.c = int(c2 * e) # hidden channels
- self.cv1 = Conv(c1, 2 * self.c, 1, 1)
- self.cv2 = Conv((2 + n) * self.c, c2, 1) # optional act=FReLU(c2)
- self.m = nn.ModuleList(Bottleneck_DCN(self.c, self.c, shortcut, g, k=(3, 3), e=1.0) for _ in range(n))
-
- def forward(self, x):
- y = list(self.cv1(x).split((self.c, self.c), 1))
- y.extend(m(y[-1]) for m in self.m)
- return self.cv2(torch.cat(y, 1))
还是在block.py路径下,添加C2f_DCN
- __all__ = [
- 'DFL', 'HGBlock', 'HGStem', 'SPP', 'SPPF', 'C1', 'C2', 'C3', 'C2f', 'C3x', 'C3TR', 'C3Ghost', 'GhostBottleneck',
- 'Bottleneck', 'BottleneckCSP', 'Proto', 'RepC3',
- 'C2f_DCN','C2f_DSConv']
路径D:\learn\sdxx\mbjc\ultralytics\ultralytics\nn\modules\__init__.py导入C2f_DCN。
- from .block import (C1, C2, C3, C3TR, DFL, SPP, SPPF, Bottleneck, BottleneckCSP, C2f, C3Ghost, C3x, GhostBottleneck,
- HGBlock, HGStem, Proto, RepC3,
- C2f_DCN)#自己加的
- __all__ = [
- 'Conv', 'LightConv', 'RepConv', 'DWConv', 'DWConvTranspose2d', 'ConvTranspose', 'Focus', 'GhostConv',
- 'ChannelAttention', 'SpatialAttention', 'CBAM', 'Concat', 'TransformerLayer', 'TransformerBlock', 'MLPBlock',
- 'LayerNorm2d', 'DFL', 'HGBlock', 'HGStem', 'SPP', 'SPPF', 'C1', 'C2', 'C3', 'C2f', 'C3x', 'C3TR', 'C3Ghost',
- 'GhostBottleneck', 'Bottleneck', 'BottleneckCSP', 'Proto', 'Detect', 'Segment', 'Pose', 'Classify',
- 'TransformerEncoderLayer', 'RepC3', 'RTDETRDecoder', 'AIFI', 'DeformableTransformerDecoder',
- 'DeformableTransformerDecoderLayer', 'MSDeformAttn', 'MLP','deattn',
- 'C2f_DCN']
将模块名称加入到tasks.py中,路径在ultralytics/nn/tasks.py。
- from ultralytics.nn.modules import (AIFI, C1, C2, C3, C3TR, SPP, SPPF, Bottleneck, BottleneckCSP, C2f, C3Ghost, C3x,
- Classify, Concat, Conv, ConvTranspose, Detect, DWConv, DWConvTranspose2d, Focus,
- GhostBottleneck, GhostConv, HGBlock, HGStem, Pose, RepC3, RepConv, RTDETRDecoder,
- Segment,CBAM,C2f_DCN)
在task.py下面def parse_model中加入C2f_DCN。这两个代码中加入C2f_DCN。 这代码是传入模块的通道数。
- if m in (Classify, Conv, ConvTranspose, GhostConv, Bottleneck, GhostBottleneck, SPP, SPPF, DWConv, Focus,
- 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):
C2f_DCN是block中的一个,在ultralytics/nn/modules/__init__.py路径下,增加导入包,以及增加名称。
- from .block import (C1, C2, C3, C3TR, DFL, SPP, SPPF, Bottleneck, BottleneckCSP, C2f, C3Ghost, C3x, GhostBottleneck,
- HGBlock, HGStem, Proto, RepC3,C2f_DCN)
- __all__ = [
- 'Conv', 'LightConv', 'RepConv', 'DWConv', 'DWConvTranspose2d', 'ConvTranspose', 'Focus', 'GhostConv',
- 'ChannelAttention', 'SpatialAttention', 'CBAM', 'Concat', 'TransformerLayer', 'TransformerBlock', 'MLPBlock',
- 'LayerNorm2d', 'DFL', 'HGBlock', 'HGStem', 'SPP', 'SPPF', 'C1', 'C2', 'C3', 'C2f', 'C3x', 'C3TR', 'C3Ghost',
- 'GhostBottleneck', 'Bottleneck', 'BottleneckCSP', 'Proto', 'Detect', 'Segment', 'Pose', 'Classify',
- 'TransformerEncoderLayer', 'RepC3', 'RTDETRDecoder', 'AIFI', 'DeformableTransformerDecoder',
- 'DeformableTransformerDecoderLayer', 'MSDeformAttn', 'MLP','deattn','C2f_DCN']
在ultralytics/models/v8中yaml配置文件中,将任意的C2f改为C2f_DCN,通道多参数就多。
- # Ultralytics YOLO 声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/698046推荐阅读
相关标签
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。