重點在於groups參數的理解
1、groups參數是如何影響卷積計算的
conv = nn.Conv2d(in_channels=6, out_channels=6, kernel_size=1, groups=3) conv.weight.data.size()
輸出:
torch.Size([6, 2, 1, 1])
(此時轉置參數Transposed默認爲False,源碼如下)
當group=1時,該卷積層需要6*6*1*1=36個參數,即需要6個6*1*1的卷積核
計算時就是6*H_in*W_in的輸入整個乘以一個6*1*1的卷積核,得到輸出的一個channel的值,即1*H_out*W_out。這樣經過6次與6個卷積覈計算就能夠得到6*H_out*W_out的結果了
如果將group=3時,卷積核大小爲torch.Size([6, 2, 1, 1]),即6個2*1*1的卷積核,只需要需要6*2*1*1=12個參數
那麼每組計算就只被in_channels/groups=2個channels的卷積覈計算,當然這也會將輸入分爲三份大小爲2*H_in*W_in的小輸入,分別與2*1*1大小的卷積核進行三次運算,然後將得到的3個2*H_out*W_out的小輸出concat起來得到最後的6*H_out*W_out輸出
在實際實驗中,同樣的網絡結構下,這種分組的卷積效果是好於未分組的卷積的效果的。
2、爲什麼要設置groups參數,有什麼優點?
爲了在GPU上並行計算:
標準卷積的計算如下圖:
舉個例子,假設有一個3×3大小的卷積層,其輸入通道爲16、輸出通道爲32。
那麼一般的操作就是用32個3×3的卷積核來分別同輸入數據卷積,這樣每個卷積核需要3×3×16個參數,得到的輸出是隻有一個通道的數據。之所以會得到一通道的數據,是因爲剛開始3×3×16的卷積核的每個通道會在輸入數據的每個對應通道上做卷積,然後疊加每一個通道對應位置的值,使之變成了單通道,那麼32個卷積核一共需要(3×3×16)×32 =4068個參數。
分組卷積的計算:
卷積的幾種常見操作可以參見:
https://blog.csdn.net/chenyuping333/article/details/82531047?utm_source=blogxgwz6
另外標準卷積的詳細計算圖可表示爲: