focus模組在v5中是進入backbone前,對進行切片操作,具體操作是在一張中每隔乙個畫素拿到乙個值,類似於鄰近下取樣,這樣就拿到了四張,四張互補,長的差不多,但是沒有資訊丟失,這樣一來,將w、h資訊就集中到了通道空間,輸入通道擴充了4倍,即拼接起來的相對於原先的rgb三通道模式變成了12個通道,最後將得到的新再經過卷積操作,最終得到了沒有資訊丟失情況下的二倍下取樣特徵圖。
以yolov5s為例,原始的640 × 640 × 3的影象輸入focus結構,採用切片操作,先變成320 × 320 × 12的特徵圖,再經過一次卷積操作,最終變成320 × 320 × 32的特徵圖。切片操作如下:
具體**實現:
class
focus
(nn.module)
:# focus wh information into c-space
def__init__
(self, c1, c2, k=
1, s=
1, p=
none
, g=
1, act=
true):
# ch_in, ch_out, kernel, stride, padding, groups
super
(focus, self)
.__init__(
) self.conv = conv(c1 *
4, c2, k, s, p, g, act)
# 這裡輸入通道變成了4倍
defforward
(self, x)
:# x(b,c,w,h) -> y(b,4c,w/2,h/2)
return self.conv(torch.cat(
[x[...
,::2
,::2
], x[..
.,1:
:2,:
:2], x[..
.,::
2,1:
:2], x[..
.,1:
:2,1
::2]
],1)
)
在討論focus的作用之前,先了解兩個概念:
引數數量(params):關係到模型大小,單位通常是m,通常引數用float32表示,所以模型大小是引數數量的4倍。
計算量(flops):即浮點運算數,可以用來衡量演算法/模型的複雜度,這關係到演算法速度,大模型的單位通常為g,小模型單位通常為m;通常只考慮乘加操作的數量,而且只考慮conv和fc等引數層的計算量,忽略bn和prelu等,一般情況下,conv和fc層也會忽略僅純加操作的計算量,如bias偏置加和shoutcut殘差加等,目前技術有bn和cnn可以不加bias。
params計算公式:
kh × kw × cin × cout
flops計算公式:
kh × kw × cin × cout × h × w = 即(當前層filter × 輸出的feature map)= params × h × w
在yolov5s的網路結構中,可以看到,focus模組的卷積核是3 × 3,輸出通道是32:
那麼做個對比:
普通下取樣:即將一張640 × 640 × 3的輸入3 × 3的卷積中,步長為2,輸出通道32,下取樣後得到320 × 320 × 32的特徵圖,那麼普通卷積下取樣理論的計算量為:
flops(conv) = 3 × 3 × 3 × 32 × 320 × 320 = 88473600(不考慮bias情況下)
params參數量(conv) = 3 × 3 × 3 × 32 +32 +32 = 928(後面兩個32分別為bias和bn層引數)
focus:將640 × 640 × 3的影象輸入focus結構,採用切片操作,先變成320 × 320 × 12的特徵圖,再經過3 × 3的卷積操作,輸出通道32,最終變成320 × 320 × 32的特徵圖,那麼focus理論的計算量為:
flops(focus) = 3 × 3 × 12 × 32 × 320 × 320 = 353894400(不考慮bias情況下)
params參數量(focus)= 3 × 3 × 12 × 32 +32 +32 =3520(為了呼應上圖輸出的參數量,將後面兩個32分別為bias和bn層的引數考慮進去,通常這兩個佔比比較小可以忽略)
可以明顯的看到,focus的計算量和參數量要比普通卷積要多一些,是普通卷積的4倍,但是下取樣時沒有資訊的丟失。(結論已修改,請看後續更新)
綜上所述,其實就可以得出結論,focus的作用無非是使在下取樣的過程中,不帶來資訊丟失的情況下,將w、h的資訊集中到通道上,再使用3 × 3的卷積對其進行特徵提取,使得特徵提取得更加的充分。雖然增加了一點點的計算量,但是為後續的特徵提取保留了更完整的下取樣資訊。
2021-08-16更新:作者終於在issues上做了具體的解答,和之前分析的思路一樣,都是從計算量和參數量出發,不同的是,在作者解答之前我們並不知道作者改進的出發點是什麼,也就是不清楚他在何結構上進行的改進,文中我理解為只是對一層普通下取樣卷積做的改進,實際上有三層,所以經過改進後參數量其實還是變少了的,也確實達到了提速的效果,具體內容可以結合本文分析過程和作者給的issues結合起來看。
千呼萬喚始出來的結論,終於解開了我這麼長時間的疑惑,雖然之前文中的結論和作者實際的結論是相反的;主要原因還是因為不知道作者改進的出發點在**,所以分析過程雖然是對的,但是結論卻是反著了;知道了改進的出發點後,再把過程重新梳理一下,就很好理解了。最後也感謝大家的討論
用opencv的dnn模組做yolov5目標檢測
在yolov5之前的yolov3和yolov4的官方 都是基於darknet框架的實現的,因此opencv的dnn模組做目標檢測時,讀取的是.cfg和.weight檔案,那時候編寫程式很順暢,沒有遇到bug。但是yolov5的官方 是基於pytorch框架實現的,但是opencv的dnn模組不支援讀...
YOLOV5模型架構
模型架構是按照配置檔案yaml進行搭建的。不同的版本的yaml在model資料夾中,每一版本的模型分為兩個部分backbone和head。每一行代表了乙個運算單元,這裡按照yolov5結構圖可以方便理解。每一行有四個引數,引數1 代表輸入從運算單元獲得,1代表從上乙個單元獲得。引數2 代表該運算單元...
yolov3 yolov4與yolov5效能對比
yolov5s網路最小,速度最少,ap精度也最低。但如果檢測的以大目標為主,追求速度,倒也是個不錯的選擇。其他的三種網路,在此基礎上,不斷加深加寬網路,ap精度也不斷提公升,但速度的消耗也在不斷增加。目前使用下來,yolov5s的模型十幾m大小,速度很快,線上生產效果可觀,嵌入式裝置可以使用。在相同...