0
点赞
收藏
分享

微信扫一扫

Yolov5-v6.0模型详解

高子歌 2022-02-01 阅读 200
p2plinqgnu

Yolov5-v6.0模型详解

# YOLOv5 v6.0 backbone

backbone:

  # [from, number, module, args]

  [[-1, 1, Conv, [64[l1] , 6[l2] , 2[l3] , 2[l4] ]],  # 0-P1/2   

#  来自上层,含瓶颈层数,本层类型,【输出通道,核大小,滑动,?分组】

#含瓶颈层数只对c3有效,其他层均为1

   [-1, 1, Conv, [128, 3, 2]],  # 1-P2/4

   [-1, 3[l5] , C3, [128]],

   [-1, 1, Conv, [256, 3, 2]],  # 3-P3/8

   [-1, 6, C3, [256]],

   [-1, 1, Conv, [512, 3, 2]],  # 5-P4/16

   [-1, 9, C3, [512]],

   [-1, 1, Conv, [1024, 3, 2]],  # 7-P5/32

   [-1, 3, C3, [1024]],

   [-1, 1, SPPF, [1024, 5]],  # 9

  ]

# YOLOv5 v6.0 head

head:

  [[-1, 1, Conv, [512, 1, 1]],

   [-1, 1, nn.Upsample, [None, 2, 'nearest']],

   [[-1, 6], 1, Concat, [1]],  # cat backbone P4

   [-1, 3, C3, [512, False]],  # 13

   [-1, 1, Conv, [256, 1, 1]],

   [-1, 1, nn.Upsample, [None, 2, 'nearest']],

   [[-1, 4], 1, Concat, [1]],  # cat backbone P3

   [-1, 3, C3, [256, False]],  # 17 (P3/8-small)

   [-1, 1, Conv, [256, 3, 2]],

   [[-1, 14], 1, Concat, [1]],  # cat head P4

   [-1, 3, C3, [512, False]],  # 20 (P4/16-medium)

   [-1, 1, Conv, [512, 3, 2]],

   [[-1, 10], 1, Concat, [1]],  # cat head P5

   [-1, 3, C3, [1024, False]],  # 23 (P5/32-large)

   [[17, 20, 23], 1, Detect[l6] , [nc, anchors]],  # Detect(P3, P4, P5)

  ]

class Conv(nn.Module):

    # Standard convolution

    def __init__(self, c1, c2, k=1, s=1, p=None, g=1, act=True):  # ch_in, ch_out, kernel, stride, padding, groups

        super().__init__()

        self.conv = nn.Conv2d(c1, c2, k, s, autopad(k, p), groups=g, bias=False)

        self.bn = nn.BatchNorm2d(c2)

        self.act = nn.SiLU() if act is True else (act if isinstance(act, nn.Module) else nn.Identity())

    def forward(self, x):

        return self.act(self.bn(self.conv(x)))

    def forward_fuse(self, x):

        return self.act(self.conv(x))

class Bottleneck(nn.Module):

    # Standard bottleneck

    def __init__(self, c1, c2, shortcut=True, g=1, e=0.5):  # ch_in, ch_out, shortcut, groups, expansion

        super().__init__()

        c_ = int(c2 * e)  # hidden channels  可以增加通道数,扩充网络宽度

        self.cv1 = Conv(c1, c_, 1, 1)

        self.cv2 = Conv(c_, c2, 3, 1, g=g)  #核是3

        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 C3(nn.Module):

    # CSP Bottleneck with 3 convolutions

    def __init__(self, c1, c2, n=1, shortcut=True, g=1, e=0.5):  # ch_in, ch_out, number, shortcut, groups, expansion

        super().__init__()

        c_ = int(c2 * e)  # hidden channels  可以扩充网络宽度

        self.cv1 = Conv(c1, c_, 1, 1)

        self.cv2 = Conv(c1, c_, 1, 1)

        self.cv3 = Conv(2 * c_, c2, 1)  # act=FReLU(c2)  concatconv输入通道要是2 * c_

        self.m = nn.Sequential(*(Bottleneck(c_, c_, shortcut, g, e=1.0) for _ in range(n)))

#通道数不会变化都是c_

        # self.m = nn.Sequential(*[CrossConv(c_, c_, 3, 1, g, 1.0, shortcut) for _ in range(n)])

    def forward(self, x):

        return self.cv3(torch.cat((self.m(self.cv1(x)), self.cv2(x)), dim=1))

  class SPPF(nn.Module):   # SPPF 输入通道c1,输出通道c2,大小不变

    # Spatial Pyramid Pooling - Fast (SPPF) layer for YOLOv5 by Glenn Jocher

    def __init__(self, c1, c2, k=5):  # equivalent to SPP(k=(5, 9, 13))  

        super().__init__()

        c_ = c1 // 2  # hidden channels

        self.cv1 = Conv(c1, c_, 1, 1)  #1,滑动1

        self.cv2 = Conv(c_ * 4, c2, 1, 1) #

        self.m = nn.MaxPool2d(kernel_size=k, stride=1, padding=k // 2)  #最大池化,滑动1,此处大小不变

    def forward(self, x):

        x = self.cv1(x)

        with warnings.catch_warnings():

            warnings.simplefilter('ignore')  # suppress torch 1.9.0 max_pool2d() warning

            y1 = self.m(x)

            y2 = self.m(y1)

            return self.cv2(torch.cat([x, y1, y2, self.m(y2)], 1))


 [l1]输出通道

 [l2]核大小

 [l3]滑动步长

 [l4]可能是分组

 [l5]C3中残差模块个数

其他层都为1

 [l6]3层预测结果0~1,转为真实的结果输出

举报

相关推荐

0 条评论