改进YOLOv5系列:2.PicoDet结构的修改

YOLOv5模块改进,适用于 YOLOv7、YOLOv5、YOLOv4、Scaled_YOLOv4、YOLOv3、YOLOR一系列YOLO算法的模块改进


一系列YOLO算法改进Trick组合!
很多Trick排列组合
助力论文
数据集涨点
创新点改进

具体看置顶博客

以下PicoDet的改进

使用YOLOv5算法作为演示,模块可以无缝插入到YOLOv7、YOLOv5、YOLOv4、Scaled_YOLOv4、YOLOv3、YOLOR等一系列YOLO算法中

文章目录

    • YOLOv5的yaml配置文件
    • common.py配置
    • yolo.py配置
    • 训练xx.yaml模型

YOLOv5的yaml配置文件

增加以下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)
  ]

common.py配置

./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

yolo.py配置

按以下图片展示添加ES_Bottleneck, ES_SEModule,

代码
ES_Bottleneck, ES_SEModule模块

示意图
![请添加图片描述](https://img-blog.csdnimg.cn/ece672fb4e53470fba91cf2b5b745b8c.png改进YOLOv5系列:2.PicoDet结构的修改_第1张图片

训练xx.yaml模型

python train.py --cfg xx.yaml
``

你可能感兴趣的:(目标检测,目标检测,深度学习,计算机视觉,python,人工智能)