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