一、spd-conv是什么?
SPD-Conv(Symmetric Positive Definite Convolution)是一種新穎的卷積操作,它主要應用于處理對稱正定矩陣(SPD)數據。在傳統的卷積神經網絡(CNN)中,卷積操作通常用于處理圖像數據,而SPD-Conv的引入則將卷積擴展到了處理更加復雜的數據結構,例如在計算機視覺、醫學影像分析和材料科學等領域中廣泛存在的對稱正定矩陣數據。
????????1.SPD矩陣的特點
對稱正定矩陣是一類特殊的矩陣,具有嚴格的數學定義,通常表示為X∈Rn×nX∈Rn×n,其中 XX 是對稱正定矩陣,滿足 XT=XXT=X 和對于任意非零向量 vv,有 vTXv>0vTXv>0。這種矩陣廣泛應用于協方差矩陣、距離度量、流形學習等領域,并且在一些任務中,數據被表示為SPD矩陣,例如醫學圖像的核磁共振(MRI)圖像。
????????2.SPD-Conv的引入
- SPD-Conv是針對SPD數據設計的卷積操作。與傳統的卷積操作不同,SPD-Conv考慮了SPD矩陣的特殊結構和性質。它在對SPD數據進行卷積時,保持了輸入和輸出的對稱正定性,確保了卷積結果仍然是對稱正定矩陣。這種特性使得SPD-Conv適用于處理一些需要保持數據結構特性的任務,例如在醫學影像中保持圖像的對稱性和正定性。
- SPD-Conv是一種新的構建塊,用于替代現有的CNN體系結構中的步長卷積和池化層。它由一個空間到深度(SPD)層和一個非步長卷積(Conv)層組成。
- 空間到深度(SPD)層的作用是將輸入特征圖的每個空間維度降低到通道維度,同時保留通道內的信息。這可以通過將輸入特征圖的每個像素或特征映射到一個通道來實現。在這個過程中,空間維度的大小會減小,而通道維度的大小會增加。
- 非步長卷積(Conv)層是一種標準的卷積操作,它在SPD層之后進行。與步長卷積不同,非步長卷積不會在特征圖上移動,而是對每個像素或特征映射進行卷積操作。這有助于減少在SPD層中可能出現的過度下采樣問題,并保留更多的細粒度信息。
- SPD-Conv的組合方式是將SPD層和Conv層串聯起來。具體來說,輸入特征圖首先通過SPD層進行轉換,然后輸出結果再通過Conv層進行卷積操作。這種組合方式可以在不丟失信息的情況下減少空間維度的尺寸,同時保留通道內的信息,有助于提高CNN對低分辨率圖像和小型物體的檢測性能。
總結起來,SPD-Conv是一種新的構建塊,旨在解決現有CNN體系結構中步長卷積和池化層的問題。它由一個空間到深度(SPD)層和一個非步長卷積(Conv)層組成,能夠提高模型對低分辨率圖像和小型物體的檢測性能,并降低對“良好質量"輸入的依賴。
二、使用步驟
1.第一步:先在models/common.py加上
class space_to_depth(nn.Module):# Changing the dimension of the Tensordef __init__(self, dimension=1):super().__init__()self.d = dimensiondef forward(self, x):return torch.cat([x[..., ::2, ::2], x[..., 1::2, ::2], x[..., ::2, 1::2], x[..., 1::2, 1::2]], 1)
2.第二步:models/yolo.py加上
elif m is space_to_depth:c2 = 4 * ch[f]
同時在769行里面加入space to death
3.第三步:修改yolov7的yaml文件
# parameters
nc: 80 # number of classes
depth_multiple: 1.0 # model depth multiple
width_multiple: 1.0 # layer channel multiple# anchors
anchors:- [12,16, 19,36, 40,28] # P3/8- [36,75, 76,55, 72,146] # P4/16- [142,110, 192,243, 459,401] # P5/32# yolov7 backbone
backbone:# [from, number, module, args][[-1, 1, Conv, [32, 3, 1]], # 0[-1, 1, Conv, [64, 3, 2]], # 1-P1/2[-1, 1, Conv, [64, 3, 1]],[-1, 1, Conv, [128, 3, 2]], # 3-P2/4[-1, 1, Conv, [64, 1, 1]],[-2, 1, Conv, [64, 1, 1]],[-1, 1, Conv, [64, 3, 1]],[-1, 1, Conv, [64, 3, 1]],[-1, 1, Conv, [64, 3, 1]],[-1, 1, Conv, [64, 3, 1]],[[-1, -3, -5, -6], 1, Concat, [1]],[-1, 1, Conv, [256, 1, 1]], # 11[-1, 1, MP, []],[-1, 1, Conv, [128, 1, 1]],[-3, 1, Conv, [128, 1, 1]],[-1, 1, Conv, [128, 3, 2]],[[-1, -3], 1, Concat, [1]], # 16-P3/8[-1, 1, Conv, [128, 1, 1]],[-2, 1, Conv, [128, 1, 1]],[-1, 1, Conv, [128, 3, 1]],[-1, 1, Conv, [128, 3, 1]],[-1, 1, Conv, [128, 3, 1]],[-1, 1, Conv, [128, 3, 1]],[[-1, -3, -5, -6], 1, Concat, [1]],[-1, 1, Conv, [512, 1, 1]], # 24[-1, 1, MP, []],[-1, 1, Conv, [256, 1, 1]],[-3, 1, Conv, [256, 1, 1]],[-1, 1, Conv, [256, 3, 2]],[[-1, -3], 1, Concat, [1]], # 29-P4/16[-1, 1, Conv, [256, 1, 1]],[-2, 1, Conv, [256, 1, 1]],[-1, 1, Conv, [256, 3, 1]],[-1, 1, Conv, [256, 3, 1]],[-1, 1, Conv, [256, 3, 1]],[-1, 1, Conv, [256, 3, 1]],[[-1, -3, -5, -6], 1, Concat, [1]],[-1, 1, Conv, [1024, 1, 1]], # 37[-1, 1, MP, []],[-1, 1, Conv, [512, 1, 1]],[-3, 1, Conv, [512, 1, 1]],[-1, 1, Conv, [512, 3, 2]],[[-1, -3], 1, Concat, [1]], # 42-P5/32[-1, 1, Conv, [256, 1, 1]],[-2, 1, Conv, [256, 1, 1]],[-1, 1, Conv, [256, 3, 1]],[-1, 1, Conv, [256, 3, 1]],[-1, 1, Conv, [256, 3, 1]],[-1, 1, Conv, [256, 3, 1]],[[-1, -3, -5, -6], 1, Concat, [1]],[-1, 1, Conv, [1024, 1, 1]], # 50]# yolov7 head
head:[[-1, 1, SPPCSPC, [512]], # 51[-1, 1, Conv, [256, 1, 1]],[-1, 1, nn.Upsample, [None, 2, 'nearest']],[37, 1, Conv, [256, 1, 1]], # route backbone P4[[-1, -2], 1, Concat, [1]],[-1, 1, Conv, [256, 1, 1]],[-2, 1, Conv, [256, 1, 1]],[-1, 1, Conv, [128, 3, 1]],[-1, 1, Conv, [128, 3, 1]],[-1, 1, Conv, [128, 3, 1]],[-1, 1, Conv, [128, 3, 1]],[[-1, -2, -3, -4, -5, -6], 1, Concat, [1]],[-1, 1, Conv, [256, 1, 1]], # 63[-1, 1, Conv, [128, 1, 1]],[-1, 1, nn.Upsample, [None, 2, 'nearest']],[24, 1, Conv, [128, 1, 1]], # route backbone P3[[-1, -2], 1, Concat, [1]],[-1, 1, Conv, [128, 1, 1]],[-2, 1, Conv, [128, 1, 1]],[-1, 1, Conv, [64, 3, 1]],[-1, 1, Conv, [64, 3, 1]],[-1, 1, Conv, [64, 3, 1]],[-1, 1, Conv, [64, 3, 1]],[[-1, -2, -3, -4, -5, -6], 1, Concat, [1]],[-1, 1, Conv, [128, 1, 1]], # 75[-1, 1, MP, []],[-1, 1, Conv, [128, 1, 1]],[-3, 1, Conv, [128, 1, 1]],[-1, 1, Conv, [128, 3, 2]],[[-1, -3, 63], 1, Concat, [1]],[-1, 1, Conv, [256, 1, 1]],[-2, 1, Conv, [256, 1, 1]],[-1, 1, Conv, [128, 3, 1]],[-1, 1, Conv, [128, 3, 1]],[-1, 1, Conv, [128, 3, 1]],[-1, 1, Conv, [128, 3, 1]],[[-1, -2, -3, -4, -5, -6], 1, Concat, [1]],[-1, 1, Conv, [256, 1, 1]], # 88[-1, 1, MP, []],[-1, 1, Conv, [256, 1, 1]],[-3, 1, Conv, [256, 1, 1]],[-1, 1, Conv, [256, 3, 2]],[[-1, -3, 51], 1, Concat, [1]],[-1, 1, Conv, [512, 1, 1]],[-2, 1, Conv, [512, 1, 1]],[-1, 1, Conv, [256, 3, 1]],[-1, 1, Conv, [256, 3, 1]],[-1, 1, Conv, [256, 3, 1]],[-1, 1, Conv, [256, 3, 1]],[[-1, -2, -3, -4, -5, -6], 1, Concat, [1]],[-1, 1, Conv, [512, 1, 1]], # 101[-1,1,space_to_depth,[1]], # 2 -P2/4[-1, 1, Conv, [512, 1, 1]], # 103[75, 1, RepConv, [256, 3, 1]],[88, 1, RepConv, [512, 3, 1]],[103, 1, RepConv, [1024, 3, 1]],[[104,105,106], 1, IDetect, [nc, anchors]], # Detect(P3, P4, P5)]
總結
以上只是·簡單添加了一層spd,需要添加多層spd-con可以直接修改yolov7的yaml配置文件,不需要修改其他。
備注:
spd添加層數地方只可以在512層的網絡中修改,其他的層數修改會報錯,圖像張量不匹配,128.256以及1024經過變換之后張量改變對不上。