目錄
1. Res2Net介紹
1.1 Res2Net的背景和動(dòng)機(jī)
1.2 Res2Net的基本概念
2. YOLOV5添加Res2Net模塊
?文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-695250.html
Res2Net(Residual Resolution Network)是一種用于圖像處理和計(jì)算機(jī)視覺(jué)任務(wù)的深度卷積神經(jīng)網(wǎng)絡(luò)架構(gòu)。它旨在解決傳統(tǒng)的ResNet(Residual Network)存在的問(wèn)題,如對(duì)不同尺度和分辨率特征的建模不足以及網(wǎng)絡(luò)深度受限的問(wèn)題。Res2Net通過(guò)引入多分支的結(jié)構(gòu)和逐級(jí)增加的分辨率來(lái)提高網(wǎng)絡(luò)的表達(dá)能力,從而在各種視覺(jué)任務(wù)中取得了顯著的性能提升。
1. Res2Net介紹
1.1 Res2Net的背景和動(dòng)機(jī)
ResNet是一種非常成功的深度卷積神經(jīng)網(wǎng)絡(luò),但它存在一些問(wèn)題。其中最重要的問(wèn)題之一是對(duì)不同尺度和分辨率特征的建模不足。傳統(tǒng)的ResNet塊只使用單一的殘差連接來(lái)傳遞信息,這意味著網(wǎng)絡(luò)可能無(wú)法有效地捕獲不同層次的特征。
Res2Net的動(dòng)機(jī)是通過(guò)引入多分支結(jié)構(gòu)和逐級(jí)增加的分辨率來(lái)提高網(wǎng)絡(luò)的表達(dá)能力。這使得網(wǎng)絡(luò)能夠更好地處理多尺度和多分辨率的特征,從而提高了其在各種計(jì)算機(jī)視覺(jué)任務(wù)中的性能。
1.2 Res2Net的基本概念
ResNet中的基本構(gòu)建塊,即殘差塊(Residual Block)。一個(gè)典型的殘差塊包含兩個(gè)主要分支:一個(gè)跳躍連接(Identity Shortcut)和一個(gè)經(jīng)過(guò)多個(gè)卷積層的主路徑。跳躍連接用于繞過(guò)一些卷積層,以確保梯度能夠順暢地傳播。
Res2Net的核心思想是將多個(gè)分支的信息融合在一個(gè)殘差塊中,以提高網(wǎng)絡(luò)對(duì)不同分辨率的特征的表達(dá)能力。具體來(lái)說(shuō),Res2Net引入了多尺度子網(wǎng)絡(luò)(Multi-Scale Sub-Networks)來(lái)處理不同分辨率的特征,然后將它們的輸出級(jí)聯(lián)在一起。這種級(jí)聯(lián)結(jié)構(gòu)允許網(wǎng)絡(luò)同時(shí)學(xué)習(xí)低分辨率和高分辨率的特征表示,從而提高了網(wǎng)絡(luò)的感知能力。
Res2Net的核心結(jié)構(gòu)是一個(gè)多分支的殘差塊,每個(gè)分支都有自己的卷積層,負(fù)責(zé)處理不同分辨率的特征。這些分支的輸出級(jí)聯(lián)在一起,以獲得最終的塊輸出。多個(gè)這樣的塊可以構(gòu)建成深層網(wǎng)絡(luò),以處理更復(fù)雜的任務(wù)。
Res2Net的工作原理在前向傳播過(guò)程中如下:
- 輸入特征首先經(jīng)過(guò)一個(gè)初始卷積層,用于提取低級(jí)別的特征表示。
- 接下來(lái),輸入特征被送入多個(gè)Res2Net塊。每個(gè)塊都包含多個(gè)分支,每個(gè)分支處理不同分辨率的特征。
- 每個(gè)分支內(nèi)部包含卷積層、激活函數(shù)和規(guī)范化層等,用于提取和調(diào)整特征。
- 分支的輸出級(jí)聯(lián)在一起,形成塊的最終輸出。
- 這個(gè)塊的輸出可以傳遞到下一個(gè)塊,也可以連接到網(wǎng)絡(luò)的其他部分。
如下圖:
2. YOLOV5添加Res2Net模塊
在models/common.py文件中增加以下模塊:
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)
print(out.shape)
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)))
在models/yolo.py文件下里的parse_model函數(shù)將類名加入進(jìn)去,如下圖:
創(chuàng)建添加Res2Net模塊的YOLOv5的yaml配置文件?
# Parameters
nc: 80 # number of classes
depth_multiple: 0.33 # model depth multiple
width_multiple: 0.50 # layer channel multiple
anchors:
- [10,13, 16,30, 33,23] # P3/8
- [30,61, 62,45, 59,119] # P4/16
- [116,90, 156,198, 373,326] # P5/32
# YOLOv5 v6.0 backbone
backbone:
# [from, number, module, args]
[[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2
[-1, 1, Conv, [128, 3, 2]], # 1-P2/4
[-1, 3, C3_Res2Block, [128]],
[-1, 1, Conv, [256, 3, 2]], # 3-P3/8
[-1, 6, C3_Res2Block, [256]],
[-1, 1, Conv, [512, 3, 2]], # 5-P4/16
[-1, 9, C3_Res2Block, [512]],
[-1, 1, Conv, [1024, 3, 2]], # 7-P5/32
[-1, 3, C3_Res2Block, [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_Res2Block, [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_Res2Block, [256, False]], # 17 (P3/8-small)
[-1, 1, Conv, [256, 3, 2]],
[[-1, 14], 1, Concat, [1]], # cat head P4
[-1, 3, C3_Res2Block, [512, False]], # 20 (P4/16-medium)
[-1, 1, Conv, [512, 3, 2]],
[[-1, 10], 1, Concat, [1]], # cat head P5
[-1, 3, C3_Res2Block, [1024, False]], # 23 (P5/32-large)
[[17, 20, 23], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5)
]
?文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-695250.html
?
到了這里,關(guān)于Yolov5改進(jìn)算法之添加Res2Net模塊的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!