yolov5中的Focus模組的理解

2021-10-16 03:37:16 字數 3131 閱讀 4507

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大小,速度很快,線上生產效果可觀,嵌入式裝置可以使用。在相同...