YOLOv5模块改进,适用于 YOLOv7、YOLOv5、YOLOv4、Scaled_YOLOv4、YOLOv3、YOLOR一系列YOLO算法的模块改进
一系列YOLO算法改进Trick组合!
很多Trick排列组合
助力论文
数据集涨点
创新点改进
具体看置顶博客
以下PicoDet的改进
使用YOLOv5算法作为演示,模块可以无缝插入到YOLOv7、YOLOv5、YOLOv4、Scaled_YOLOv4、YOLOv3、YOLOR等一系列YOLO算法中
增加以下xx.yaml文件
代码
# parameters
nc: 80 # number of classes
depth_multiple: 0.67 # model depth multiple
width_multiple: 1.00 # layer channel multiple
# anchors
anchors: 4 # auto-anchor 4 anchors per P output layer
# ESNet
backbone:
# [from, number, module, args]
[ [ -1, 1, CBH, [ 48, 3, 2 ] ], # 0-P2/4
[ -1, 1, ES_Bottleneck, [ 96, 2 ] ], # 1-P3/8
[ -1, 3, ES_Bottleneck, [ 96, 1 ] ], # 2
[ -1, 1, ES_Bottleneck, [ 192, 2 ] ], # 3-P5/16
[ -1, 7, ES_Bottleneck, [ 192, 1 ] ], # 4
[ -1, 1, ES_Bottleneck, [ 384, 2 ] ], # 5-P7/32
[ -1, 3, ES_Bottleneck, [ 384, 1 ] ], # 6
]
# CSP-PAN
head:
[ [ -1, 1, Conv, [ 192, 1, 1 ] ], # 7
[ [ -1, 6 ], 1, Concat, [ 1 ] ], # cat backbone P4
[ -1, 1, BottleneckCSP, [ 192, False ] ], # 9 (P3/8-small)
[ -1, 1, Conv, [ 192, 1, 1 ] ], # 10
[ -1, 1, nn.Upsample, [ None, 2, 'nearest' ] ],
[ [ -1, 4 ], 1, Concat, [ 1 ] ], # cat backbone P4
[ -1, 1, BottleneckCSP, [ 192, False ] ], # 13
[ -1, 1, Conv, [ 192, 1, 1 ] ], # 14
[ -1, 1, nn.Upsample, [ None, 2, 'nearest' ] ],
[ [ -1, 2 ], 1, Concat, [ 1 ] ], # cat backbone P3
[ -1, 1, BottleneckCSP, [ 192, False ] ], # 17 (P3/8-small)
[-1, 1, DWConvblock, [ 192, 5, 2 ]], # 18
[ [ -1, 14 ], 1, Concat, [ 1 ] ], # cat head P4
[ -1, 1, BottleneckCSP, [ 192, False ] ], # 20 (P4/16-medium)
[ -1, 1, DWConvblock, [ 192, 5, 2 ] ],
[ [ -1, 10 ], 1, Concat, [ 1 ] ], # cat head P5
[ -1, 1, BottleneckCSP, [ 192, False ] ], # 23 (P5/32-large)
[ [ -1, 7 ], 1, Concat, [ 1 ] ], # cat head P6
[ -1, 1, DWConvblock, [ 192, 5, 2 ] ], # 26 (P5/32-large)
[ [ 17, 20, 23, 25 ], 1, Detect, [ nc, anchors ] ], # Detect(P3, P4, P5, P6)
]
./models/common.py文件增加以下模块
代码
# PicoDet
class ES_SEModule(nn.Module):
def __init__(self, channel, reduction=4):
super().__init__()
self.avg_pool = nn.AdaptiveAvgPool2d(1)
self.conv1 = nn.Conv2d(
in_channels=channel,
out_channels=channel // reduction,
kernel_size=1,
stride=1,
padding=0)
self.relu = nn.ReLU()
self.conv2 = nn.Conv2d(
in_channels=channel // reduction,
out_channels=channel,
kernel_size=1,
stride=1,
padding=0)
self.hardsigmoid = nn.Hardsigmoid()
def forward(self, x):
identity = x
x = self.avg_pool(x)
x = self.conv1(x)
x = self.relu(x)
x = self.conv2(x)
x = self.hardsigmoid(x)
out = identity * x
return out
class ES_Bottleneck(nn.Module):
def __init__(self, inp, oup, stride):
super(ES_Bottleneck, self).__init__()
if not (1 <= stride <= 3):
raise ValueError('illegal stride value')
self.stride = stride
branch_features = oup // 2
# assert (self.stride != 1) or (inp == branch_features << 1)
if self.stride > 1:
self.branch1 = nn.Sequential(
self.depthwise_conv(inp, inp, kernel_size=3, stride=self.stride, padding=1),
nn.BatchNorm2d(inp),
nn.Conv2d(inp, branch_features, kernel_size=1, stride=1, padding=0, bias=False),
nn.BatchNorm2d(branch_features),
nn.Hardswish(inplace=True),
)
self.branch2 = nn.Sequential(
nn.Conv2d(inp if (self.stride > 1) else branch_features,
branch_features, kernel_size=1, stride=1, padding=0, bias=False),
nn.BatchNorm2d(branch_features),
nn.Hardswish(inplace=True),
self.depthwise_conv(branch_features, branch_features, kernel_size=3, stride=self.stride, padding=1),
nn.BatchNorm2d(branch_features),
ES_SEModule(branch_features),
nn.Conv2d(branch_features, branch_features, kernel_size=1, stride=1, padding=0, bias=False),
nn.BatchNorm2d(branch_features),
nn.Hardswish(inplace=True),
)
self.branch3 = nn.Sequential(
GhostConv(branch_features, branch_features, 3, 1),
ES_SEModule(branch_features),
nn.Conv2d(branch_features, branch_features, kernel_size=1, stride=1, padding=0, bias=False),
nn.BatchNorm2d(branch_features),
nn.Hardswish(inplace=True),
)
self.branch4 = nn.Sequential(
self.depthwise_conv(oup, oup, kernel_size=3, stride=1, padding=1),
nn.BatchNorm2d(oup),
nn.Conv2d(oup, oup, kernel_size=1, stride=1, padding=0, bias=False),
nn.BatchNorm2d(oup),
nn.Hardswish(inplace=True),
)
@staticmethod
def depthwise_conv(i, o, kernel_size=3, stride=1, padding=0, bias=False):
return nn.Conv2d(i, o, kernel_size, stride, padding, bias=bias, groups=i)
@staticmethod
def conv1x1(i, o, kernel_size=1, stride=1, padding=0, bias=False):
return nn.Conv2d(i, o, kernel_size, stride, padding, bias=bias)
def forward(self, x):
if self.stride == 1:
x1, x2 = x.chunk(2, dim=1)
x3 = torch.cat((x1, self.branch3(x2)), dim=1)
out = channel_shuffle(x3, 2)
elif self.stride == 2:
x1 = torch.cat((self.branch1(x), self.branch2(x)), dim=1)
out = self.branch4(x1)
return out
按以下图片展示添加ES_Bottleneck, ES_SEModule,
代码
ES_Bottleneck, ES_SEModule模块
示意图
![请添加图片描述](https://img-blog.csdnimg.cn/ece672fb4e53470fba91cf2b5b745b8c.png
python train.py --cfg xx.yaml
``