分組卷積和深度可分離卷積

一、分組卷積

(1) ALexNet網絡

分組卷積(Group Convolution),最早見於AlexNet網絡,它被用來切分網絡,使其在2個GPU上並行運行,AlexNet網絡結構如下:

圖1

AlexNet將網絡分成了兩部分,最後輸出的時候再進行合併,該網絡好處有以下幾點:
1.總的參數量減少了,提高了網絡的計算效率(後面會詳細介紹參數量減少的原因)
2.AlexNet首次採用最大值池化,避免了平均池化層的模糊化的效果,並且步長比池化的核的尺寸小,這樣池化層的輸出之間有重疊,提升了特徵的豐富性.
3.AlexNet使用ReLU代替了Sigmoid,其能更快的訓練,同時解決sigmoid在訓練較深的網絡中出現的梯度消失,或者說梯度彌散的問題.
4. 全連接中使用dropout方法防止過擬合
5. 提出了LRN層局部響應歸一化,對局部神經元創建了競爭的機制,使得其中響應小打的值變得更大,並抑制反饋較小的.
注意:LRN全稱爲Local Response Normalization,即局部響應歸一化層,LRN函數類似Dropout,是一種防止過擬合的方法。這個函數很少使用,基本上被類似Dropout這樣的方法取代。

圖二

(二) 標準卷積網絡參數的計算

如左圖:如果輸入featuer map 尺寸爲C * H * W ,卷積核有N 個,輸出feature map 與卷積核的數量相同爲N ,每個卷積核的尺寸爲C * K * K, N個卷積核的總參數量爲NCK*K.

(三) 分組卷積網絡參數的計算

如右圖:如果輸入feature map 尺寸爲C * H * W ,輸出feature map 數量爲N 個,如果設定要分成G 個組, 則每組的輸入數量C / G, 每組的輸出feature map 數量爲N/G,每個卷積核的尺寸爲C/G * K * K ,卷積核的總數仍爲N個,每組卷積核的數量爲N/G ,卷積核只與其同組的輸入map進行卷積,卷積核的總參數量爲N * C/G * K *K ,可見總參數量減少爲原來的1/G.

二、深度可分離卷積

當分組數量等於輸入map數量,輸出map數量也等於輸入map數量,即G = N = C , N 個卷積核每個尺寸爲1 * K * K時,分組卷積就變成了深度卷積。(用深度卷積主要進行像素的融合)
如下圖所示:深度可分離卷積的操作過程。
在這裏插入圖片描述
深度可分離的卷積包括兩個步驟:深度卷積和1x1卷積。
利用3x3的深度卷積做像素級別的融合,1x1的逐點卷積作通道融合,分離說的是像素融合和通道融合分開進行,以便於減少參數量。
在這裏插入圖片描述

(四) 三種卷積網絡參數計算

# 用torch實現標準卷積網絡和分組卷積網絡,並對參數進行計算。
import torch.nn as nn
# 輸入通道* 卷積核尺寸 * 輸出通道 + 偏置個數   4 * 3 * 3 * 8 + 8 = 298
conv1 = nn.Conv2d(4, 8, 3, 1)
conv2 = nn.Conv2d(4, 8, 3, 1, groups=2) # 這裏必須注意,分組的組數必須是輸入通道和輸出通道的倍數。
conv3 = nn.Conv2d(4,8,3,1,groups=4) # 深度卷積,輸入通道數等於分組通道數
params1 = conv1.parameters()
params2 = conv2.parameters()
params3 = conv3.parameters()
# e.numel() 表示元素e的個數
print("標準卷積參數個數: %s " % sum([e.numel() for e in list(params1)])) # 296
# 分組後的參數是標準網絡參數的1/G , 因爲標準網絡的參數是288 + 8  所以 分組後的參數就是288/2 + 8=80  
print("分組卷積參數個數: %s"% sum([e.numel() for e in list(params2)])) # 152
print("深度卷積參數個數 %s"% sum([e.numel() for e in list(params3)])) # 288 /4 +8 =80
# 所以可以看到分組後參數減少了,這也是分組卷積神經網絡的一個重要應用。

注意

  1. nn.Conv2d(3, 6, 3, 1, groups=3) # 這裏必須注意,分組的組數必須是輸入通道和輸出通道的倍數。
  2. 分組後參數的個數減少成了標準卷積網絡的 1/G 倍,G 爲分組的組數
  3. 深度可分離卷積的參數量最少。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章