Yolov5优化:新型backbone网络Res2Net,超越ResNet,多尺度结构,提升物体检测立竿见影

2023-11-30 16:39:00 浏览数 (1)

1. Res2Net介绍

论文:https://arxiv.org/pdf/1904.01169.pdf

Res2Net是在ResNet模型基础上提出的一种新的模块,它的核心思想是将ResNet中的卷积分解成多个子模块,每个子模块可以利用更多的特征信息,从而增强了网络的表达能力。

与ResNet相比,Res2Net的主要优势在于它能够更好地捕捉不同尺度的特征信息。在ResNet中,每个卷积层都只能捕捉一定范围内的特征,而Res2Net通过将卷积分解成多个子模块,并且将这些子模块连接起来,可以有效地扩展感受野的范围,从而捕捉到更丰富的特征信息。此外,Res2Net还可以在不增加网络深度的情况下提高网络性能,因此在一些计算资源有限的任务中,也具有一定的优势。

总之,Res2Net是在ResNet基础上的一种改进,可以更好地捕捉不同尺度的特征信息,提高网络性能。

2. Res2Net加入到Yolov5

2.1 C3_Res2Block,C2f_Res2Block加入common.py

代码语言:javascript复制
###################### Res2Net  ####     START   by  AI&CV  ###############################

class Bottle2neck(nn.Module):
    expansion = 1

    def __init__(self, inplanes, planes, shortcut, baseWidth=26, scale=4):
        """ Constructor
        Args:
            inplanes: input channel dimensionality
            planes: output channel dimensionality
            baseWidth: basic width of conv3x3
            scale: number of scale.
        """
        super(Bottle2neck, self).__init__()

        width = int(math.floor(planes * (baseWidth / 64.0)))
        self.conv1 = Conv(inplanes, width * scale, k=1)

        if scale == 1:
            self.nums = 1
        else:
            self.nums = scale - 1
        convs = []
        for i in range(self.nums):
            convs.append(Conv(width, width, k=3))
        self.convs = nn.ModuleList(convs)

        self.conv3 = Conv(width * scale, planes * self.expansion, k=1, act=False)

        self.silu = nn.SiLU(inplace=True)
        self.scale = scale
        self.width = width
        self.shortcut = shortcut

    def forward(self, x):

        if self.shortcut:
            residual = x
        out = self.conv1(x)
        spx = torch.split(out, self.width, 1)
        for i in range(self.nums):
            if i == 0:
                sp = spx[i]
            else:
                sp = sp   spx[i]
            sp = self.convs[i](sp)
            if i == 0:
                out = sp
            else:
                out = torch.cat((out, sp), 1)
        if self.scale != 1:
            out = torch.cat((out, spx[self.nums]), 1)

        out = self.conv3(out)
        if self.shortcut:
            out  = residual
        out = self.silu(out)
        return out


class C3_Res2Block(C3):
    # 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__(c1, c2, n, shortcut, g, e)
        c_ = int(c2 * e)  # hidden channels
        self.m = nn.Sequential(*(Bottle2neck(c_, c_, shortcut) for _ in range(n)))

class C2f_Res2Block(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(Bottle2neck(self.c, self.c, shortcut) 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))

###################### Res2Net  ####     END   by  AI&CV  ###############################

2.2 C3_Res2Block,C2f_Res2Block yaml展示

代码语言:javascript复制
# YOLOv5 


	

0 人点赞