專欄介紹:YOLOv9改進系列 | 包含深度學習最新創新,主力高效漲點!!!
一、文章摘要
????????卷積神經網絡(CNNs)在計算即使覺任務中如圖像分類和目標檢測等取得了顯著的成功。然而,當圖像分辨率較低或物體較小時,它們的性能會災難性下降。這是由于現有CNN常見的設計體系結構中有缺陷,即使用卷積步長和/或池化層,這導致了細粒度信息的丟失和較低效的特征表示的學習。為此,我們提出了一個名為SPD-Conv的新的CNN構建塊來代替每個卷積步長和每個池化層(因此完全消除了它們)。SPD-Conv由一個空間到深度(SPD)層和一個無卷積步長(Conv)層組成,可以應用于大多數CNN體系結構。我們從兩個最具代表性的計算即使覺任務:目標檢測和圖像分類來解釋這個新設計。然后,我們將SPD-Conv應用于YOLOv5和ResNet,創建了新的CNN架構,并通過經驗證明,我們的方法明顯優于最先進的深度學習模型,特別是在處理低分辨率圖像和小物體等更困難的任務時。
適用檢測目標:? ?通用下采樣模塊
二、SPD-Conv模塊詳解
????????論文地址:? ?https://arxiv.org/pdf/2208.03641v1.pdf
?2.1 模塊簡介
????????SPD-Conv的主要思想:? ?SPD- conv由一個空間到深度(SPD)層和一個非跨步卷積層組成。SPD組件推廣了一種(原始)圖像轉換技術來對CNN內部和整個CNN的特征映射進行下采樣。
?總結:?一種通過卷積與線性變化實現的新下采樣模塊。
?SPD- conv模塊的原理圖
三、SPD-Conv模塊使用教程
3.1 SPD-Conv模塊的代碼
class SPDConv(nn.Module):# Changing the dimension of the Tensordef __init__(self, inc, ouc, dimension=1):super().__init__()self.d = dimensionself.conv = Conv(inc * 4, ouc, k=3)def forward(self, x):x = torch.cat([x[..., ::2, ::2], x[..., 1::2, ::2], x[..., ::2, 1::2], x[..., 1::2, 1::2]], 1)x = self.conv(x)return x
3.2 在YOlO v9中的添加教程
閱讀YOLOv9添加模塊教程或使用下文操作
? ? ? ? 1.?將YOLOv9工程中models下common.py文件中增加模塊的代碼。
?????????2.?將YOLOv9工程中models下yolo.py文件中的第718行(可能因版本變化而變化)增加以下代碼。
elif m in (SPDConv,):args = [ch[f], ch[f]]
3.3 運行配置文件
# YOLOv9
# Powered bu https://blog.csdn.net/StopAndGoyyy# parameters
nc: 80 # number of classes
#depth_multiple: 0.33 # model depth multiple
depth_multiple: 1 # model depth multiple
#width_multiple: 0.25 # layer channel multiple
width_multiple: 1 # layer channel multiple
#activation: nn.LeakyReLU(0.1)
#activation: nn.ReLU()# anchors
anchors: 3# YOLOv9 backbone
backbone:[[-1, 1, Silence, []], # conv down[-1, 1, Conv, [64, 3, 2]], # 1-P1/2# conv down[-1, 1, Conv, [128, 3, 2]], # 2-P2/4# elan-1 block[-1, 1, RepNCSPELAN4, [256, 128, 64, 1]], # 3# avg-conv down[-1, 1, ADown, [256]], # 4-P3/8# elan-2 block[-1, 1, RepNCSPELAN4, [512, 256, 128, 1]], # 5# avg-conv down[-1, 1, ADown, [512]], # 6-P4/16# elan-2 block[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]], # 7# avg-conv down[-1, 1, SPDConv, []], # 8-P5/32# elan-2 block[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]], # 9]# YOLOv9 head
head:[# elan-spp block[-1, 1, SPPELAN, [512, 256]], # 10# up-concat merge[-1, 1, nn.Upsample, [None, 2, 'nearest']],[[-1, 7], 1, Concat, [1]], # cat backbone P4# elan-2 block[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]], # 13# up-concat merge[-1, 1, nn.Upsample, [None, 2, 'nearest']],[[-1, 5], 1, Concat, [1]], # cat backbone P3# elan-2 block[-1, 1, RepNCSPELAN4, [256, 256, 128, 1]], # 16 (P3/8-small)# avg-conv-down merge[-1, 1, ADown, [256]],[[-1, 13], 1, Concat, [1]], # cat head P4# elan-2 block[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]], # 19 (P4/16-medium)# avg-conv-down merge[-1, 1, ADown, [512]],[[-1, 10], 1, Concat, [1]], # cat head P5# elan-2 block[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]], # 22 (P5/32-large)# multi-level reversible auxiliary branch# routing[5, 1, CBLinear, [[256]]], # 23[7, 1, CBLinear, [[256, 512]]], # 24[9, 1, CBLinear, [[256, 512, 512]]], # 25# conv down[0, 1, Conv, [64, 3, 2]], # 26-P1/2# conv down[-1, 1, Conv, [128, 3, 2]], # 27-P2/4# elan-1 block[-1, 1, RepNCSPELAN4, [256, 128, 64, 1]], # 28# avg-conv down fuse[-1, 1, ADown, [256]], # 29-P3/8[[23, 24, 25, -1], 1, CBFuse, [[0, 0, 0]]], # 30 # elan-2 block[-1, 1, RepNCSPELAN4, [512, 256, 128, 1]], # 31# avg-conv down fuse[-1, 1, ADown, [512]], # 32-P4/16[[24, 25, -1], 1, CBFuse, [[1, 1]]], # 33 # elan-2 block[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]], # 34# avg-conv down fuse[-1, 1, ADown, [512]], # 35-P5/32[[25, -1], 1, CBFuse, [[2]]], # 36# elan-2 block[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]], # 37# detection head# detect[[31, 34, 37, 16, 19, 22], 1, DualDDetect, [nc]], # DualDDetect(A3, A4, A5, P3, P4, P5)]
3.4 訓練過程
歡迎關注!