深度學習:十大拍案叫絕的卷積設計操作
卷積的十大拍案叫絕的操作
一、卷積只能在同一組進行嗎?– Group convolution
Group convolution 分組卷積,最早在AlexNet中出現,由於當時的硬體資源有限,訓練AlexNet時卷積操作不能全部放在同一個GPU處理,因此作者把feature maps分給多個GPU分別進行處理,最後把多個GPU的結果進行融合。
AlexNet
分組卷積的思想影響比較深遠,當前一些輕量級的SOTA(State Of The Art)網路,都用到了分組卷積的操作,以節省計算量。但題主有個疑問是,如果分組卷積是分在不同GPU上的話,每個GPU的計算量就降低到 1/groups,但如果依然在同一個GPU上計算,最終整體的計算量是否不變?找了pytorch上有關組卷積操作的介紹,望讀者解答我的疑問。
pytroch github
EDIT:
關於這個問題,知乎使用者朋友 @蔡冠羽 提出了他的見解:
我感覺group conv本身應該就大大減少了引數,比如當input channel為256,output channel也為256,kernel size為3*3,不做group conv引數為256*3*3*256,若group為8,每個group的input channel和output channel均為32,引數為8*32*3*3*32,是原來的八分之一。這是我的理解。
我的理解是分組卷積最後每一組輸出的feature maps應該是以concatenate的方式組合,而不是element-wise add,所以每組輸出的channel是 input channels / #groups,這樣引數量就大大減少了。
二、卷積核一定越大越好?– 3×3卷積核
AlexNet中用到了一些非常大的卷積核,比如11×11、5×5卷積核,之前人們的觀念是,卷積核越大,receptive field(感受野)越大,看到的圖片資訊越多,因此獲得的特徵越好。雖說如此,但是大的卷積核會導致計算量的暴增,不利於模型深度的增加,計算效能也會降低。於是在VGG(最早使用)、Inception網路中,利用2個3×3卷積核的組合比1個5×5卷積核的效果更佳,同時引數量(3×3×2+1 VS 5×5×1+1)被降低,因此後來3×3卷積核被廣泛應用在各種模型中。
傳統的層疊式網路,基本上都是一個個卷積層的堆疊,每層只用一個尺寸的卷積核,例如VGG結構中使用了大量的3×3卷積層。事實上,同一層feature map可以分別使用多個不同尺寸的卷積核,以獲得不同尺度的特徵,再把這些特徵結合起來,得到的特徵往往比使用單一卷積核的要好,谷歌的GoogLeNet,或者說Inception系列的網路,就使用了多個卷積核的結構:
最初版本的Inception結構
如上圖所示,一個輸入的feature map分別同時經過1×1、3×3、5×5的卷積核的處理,得出的特徵再組合起來,獲得更佳的特徵。但這個結構會存在一個嚴重的問題:引數量比單個卷積核要多很多,如此龐大的計算量會使得模型效率低下。這就引出了一個新的結構:
四、怎樣才能減少卷積層引數量?– Bottleneck
發明GoogleNet的團隊發現,如果僅僅引入多個尺寸的卷積核,會帶來大量的額外的引數,受到Network In Network中1×1卷積核的啟發,為了解決這個問題,他們往Inception結構中加入了一些1×1的卷積核,如圖所示:
加入1×1卷積核的Inception結構
根據上圖,我們來做個對比計算,假設輸入feature map的維度為256維,要求輸出維度也是256維。有以下兩種操作:
256維的輸入直接經過一個3×3×256的卷積層,輸出一個256維的feature map,那麼引數量為:256×3×3×256 = 589,824
256維的輸入先經過一個1×1×64的卷積層,再經過一個3×3×64的卷積層,最後經過一個1×1×256的卷積層,輸出256維,引數量為:256×1×1×64 + 64×3×3×64 + 64×1×1×256 = 69,632。足足把第一種操作的引數量降低到九分之一!
1×1卷積核也被認為是影響深遠的操作,往後大型的網路為了降低引數量都會應用上1×1卷積核。
五、越深的網路就越難訓練嗎?– Resnet殘差網路
ResNet skip connection
傳統的卷積層層疊網路會遇到一個問題,當層數加深時,網路的表現越來越差,很大程度上的原因是因為當層數加深時,梯度消散得越來越嚴重,以至於反向傳播很難訓練到淺層的網路。為了解決這個問題,何凱明大神想出了一個“殘差網路”,使得梯度更容易地流動到淺層的網路當中去,而且這種“skip connection”能帶來更多的好處,這裡可以參考一個PPT:極深網路(ResNet/DenseNet): Skip Connection為何有效及其它 ,以及我的一篇文章:為什麼ResNet和DenseNet可以這麼深?一文詳解殘差塊為何能解決梯度彌散問題。 大家可以結合下面的評論進行思考。
六、卷積操作時必須同時考慮通道和區域嗎?– DepthWise操作
標準的卷積過程可以看上圖,一個2×2的卷積核在卷積時,對應影象區域中的所有通道均被同時考慮,問題在於,為什麼一定要同時考慮影象區域和通道?我們為什麼不能把通道和空間區域分開考慮?
Xception網路就是基於以上的問題發明而來。我們首先對每一個通道進行各自的卷積操作,有多少個通道就有多少個過濾器。得到新的通道feature maps之後,這時再對這批新的通道feature maps進行標準的1×1跨通道卷積操作。這種操作被稱為 “DepthWise convolution” ,縮寫“DW”。
這種操作是相當有效的,在imagenet 1000類分類任務中已經超過了InceptionV3的表現,而且也同時減少了大量的引數,我們來算一算,假設輸入通道數為3,要求輸出通道數為256,兩種做法:
1.直接接一個3×3×256的卷積核,引數量為:3×3×3×256 = 6,912
2.DW操作,分兩步完成,引數量為:3×3×3 + 3×1×1×256 = 795,又把引數量降低到九分之一!
因此,一個depthwise操作比標準的卷積操作降低不少的引數量,同時論文中指出這個模型得到了更好的分類效果。
EDIT:2017.08.25
本文在發出12小時後,一位知乎使用者私信了我,向我介紹了Depthwise和Pointwise的歷史工作,而Xception和Mobilenet也引用了他們16年的工作,就是Min Wang et al 的Factorized Convolutional Neural Networks,這篇論文的Depthwise中,每一通道輸出的feature map(稱為“基層”)可以不止一個,而Xception中的Depthwise separable Convolution, 正是這篇工作中“單一基層”的情況。推薦有興趣的讀者關注下他們的工作,這裡有篇介紹博文:【深度學習】卷積層提速Factorized Convolutional Neural Networks。而最早關於separable convolution的介紹,Xception作者提到,應該追溯到Lau- rent Sifre 2014年的工作 Rigid-Motion Scattering For Image Classification 6.2章節。
七、分組卷積能否對通道進行隨機分組?– ShuffleNet
在AlexNet的Group Convolution當中,特徵的通道被平均分到不同組裡面,最後再通過兩個全連線層來融合特徵,這樣一來,就只能在最後時刻才融合不同組之間的特徵,對模型的泛化性是相當不利的。為了解決這個問題,ShuffleNet在每一次層疊這種Group conv層前,都進行一次channel shuffle,shuffle過的通道被分配到不同組當中。進行完一次group conv之後,再一次channel shuffle,然後分到下一層組卷積當中,以此迴圈。
來自ShuffleNet論文
經過channel shuffle之後,Group conv輸出的特徵能考慮到更多通道,輸出的特徵自然代表性就更高。另外,AlexNet的分組卷積,實際上是標準卷積操作,而在ShuffleNet裡面的分組卷積操作是depthwise卷積,因此結合了通道洗牌和分組depthwise卷積的ShuffleNet,能得到超少量的引數以及超越mobilenet、媲美AlexNet的準確率!
另外值得一提的是,微軟亞洲研究院MSRA最近也有類似的工作,他們提出了一個IGC單元(Interleaved Group Convolution),即通用卷積神經網路交錯組卷積,形式上類似進行了兩次組卷積,Xception 模組可以看作交錯組卷積的一個特例,特別推薦看看這篇文章:王井東詳解ICCV 2017入選論文:通用卷積神經網路交錯組卷積
要注意的是,Group conv是一種channel分組的方式,Depthwise +Pointwise是卷積的方式,只是ShuffleNet裡面把兩者應用起來了。因此Group conv和Depthwise +Pointwise並不能劃等號。
八、通道間的特徵都是平等的嗎? — SEnet
無論是在Inception、DenseNet或者ShuffleNet裡面,我們對所有通道產生的特徵都是不分權重直接結合的,那為什麼要認為所有通道的特徵對模型的作用就是相等的呢? 這是一個好問題,於是,ImageNet2017 冠軍SEnet就出來了。
SEnet 結構
一組特徵在上一層被輸出,這時候分兩條路線,第一條直接通過,第二條首先進行Squeeze操作(Global Average Pooling),把每個通道2維的特徵壓縮成一個1維,從而得到一個特徵通道向量(每個數字代表對應通道的特徵)。然後進行Excitation操作,把這一列特徵通道向量輸入兩個全連線層和sigmoid,建模出特徵通道間的相關性,得到的輸出其實就是每個通道對應的權重,把這些權重通過Scale乘法通道加權到原來的特徵上(第一條路),這樣就完成了特徵通道的權重分配。作者詳細解釋可以看這篇文章:專欄 | Momenta詳解ImageNet 2017奪冠架構SENet
九、能否讓固定大小的卷積核看到更大範圍的區域?– Dilated convolution
標準的3×3卷積核只能看到對應區域3×3的大小,但是為了能讓卷積核看到更大的範圍,dilated conv使其成為了可能。dilated conv原論文中的結構如圖所示:
上圖b可以理解為卷積核大小依然是3×3,但是每個卷積點之間有1個空洞,也就是在綠色7×7區域裡面,只有9個紅色點位置作了卷積處理,其餘點權重為0。這樣即使卷積核大小不變,但它看到的區域變得更大了。詳細解釋可以看這個回答:如何理解空洞卷積(dilated convolution)?
十、卷積核形狀一定是矩形嗎?– Deformable convolution 可變形卷積核
圖來自微軟亞洲研究院公眾號
傳統的卷積核一般都是長方形或正方形,但MSRA提出了一個相當反直覺的見解,認為卷積核的形狀可以是變化的,變形的卷積核能讓它只看感興趣的影象區域 ,這樣識別出來的特徵更佳。
圖來自微軟亞洲研究院公眾號。要做到這個操作,可以直接在原來的過濾器前面再加一層過濾器,這層過濾器學習的是下一層卷積核的位置偏移量(offset),這樣只是增加了一層過濾器,或者直接把原網路中的某一層過濾器當成學習offset的過濾器,這樣實際增加的計算量是相當少的,但能實現可變形卷積核,識別特徵的效果更好。詳細MSRA的解讀可以看這個連結:可變形卷積網路:計算機新“視”界。
啟發與思考
現在越來越多的CNN模型從巨型網路到輕量化網路一步步演變,模型準確率也越來越高。現在工業界追求的重點已經不是準確率的提升(因為都已經很高了),都聚焦於速度與準確率的trade off,都希望模型又快又準。因此從原來AlexNet、VGGnet,到體積小一點的Inception、Resnet系列,到目前能移植到移動端的mobilenet、ShuffleNet(體積能降低到0.5mb!),我們可以看到這樣一些趨勢:
卷積核方面:
大卷積核用多個小卷積核代替;
單一尺寸卷積核用多尺寸卷積核代替;
固定形狀卷積核趨於使用可變形卷積核;
使用1×1卷積核(bottleneck結構)。
卷積層通道方面:
標準卷積用depthwise卷積代替;
使用分組卷積;
分組卷積前使用channel shuffle;
通道加權計算。
卷積層連線方面:
使用skip connection,讓模型更深;
densely connection,使每一層都融合上其它層的特徵輸出(DenseNet)
啟發
類比到通道加權操作,卷積層跨層連線能否也進行加權處理?bottleneck + Group conv + channel shuffle + depthwise的結合會不會成為以後降低引數量的標準配置?
卷積的十大拍案叫絕的操作
一、卷積只能在同一組進行嗎?– Group convolution
Group convolution 分組卷積,最早在AlexNet中出現,由於當時的硬體資源有限,訓練AlexNet時卷積操作不能全部放在同一個GPU處理,因此作者把feature maps分給多個GPU分別進行處理,最後把多個GPU的結果進行融合。
AlexNet
分組卷積的思想影響比較深遠,當前一些輕量級的SOTA(State Of The Art)網路,都用到了分組卷積的操作,以節省計算量。但題主有個疑問是,如果分組卷積是分在不同GPU上的話,每個GPU的計算量就降低到 1/groups,但如果依然在同一個GPU上計算,最終整體的計算量是否不變?找了pytorch上有關組卷積操作的介紹,望讀者解答我的疑問。
pytroch github
EDIT:
關於這個問題,知乎使用者朋友 @蔡冠羽 提出了他的見解:
我感覺group conv本身應該就大大減少了引數,比如當input channel為256,output channel也為256,kernel size為3*3,不做group conv引數為256*3*3*256,若group為8,每個group的input channel和output channel均為32,引數為8*32*3*3*32,是原來的八分之一。這是我的理解。
我的理解是分組卷積最後每一組輸出的feature maps應該是以concatenate的方式組合,而不是element-wise add,所以每組輸出的channel是 input channels / #groups,這樣引數量就大大減少了。
二、卷積核一定越大越好?– 3×3卷積核
AlexNet中用到了一些非常大的卷積核,比如11×11、5×5卷積核,之前人們的觀念是,卷積核越大,receptive field(感受野)越大,看到的圖片資訊越多,因此獲得的特徵越好。雖說如此,但是大的卷積核會導致計算量的暴增,不利於模型深度的增加,計算效能也會降低。於是在VGG(最早使用)、Inception網路中,利用2個3×3卷積核的組合比1個5×5卷積核的效果更佳,同時引數量(3×3×2+1 VS 5×5×1+1)被降低,因此後來3×3卷積核被廣泛應用在各種模型中。
傳統的層疊式網路,基本上都是一個個卷積層的堆疊,每層只用一個尺寸的卷積核,例如VGG結構中使用了大量的3×3卷積層。事實上,同一層feature map可以分別使用多個不同尺寸的卷積核,以獲得不同尺度的特徵,再把這些特徵結合起來,得到的特徵往往比使用單一卷積核的要好,谷歌的GoogLeNet,或者說Inception系列的網路,就使用了多個卷積核的結構:
最初版本的Inception結構
如上圖所示,一個輸入的feature map分別同時經過1×1、3×3、5×5的卷積核的處理,得出的特徵再組合起來,獲得更佳的特徵。但這個結構會存在一個嚴重的問題:引數量比單個卷積核要多很多,如此龐大的計算量會使得模型效率低下。這就引出了一個新的結構:
四、怎樣才能減少卷積層引數量?– Bottleneck
發明GoogleNet的團隊發現,如果僅僅引入多個尺寸的卷積核,會帶來大量的額外的引數,受到Network In Network中1×1卷積核的啟發,為了解決這個問題,他們往Inception結構中加入了一些1×1的卷積核,如圖所示:
加入1×1卷積核的Inception結構
根據上圖,我們來做個對比計算,假設輸入feature map的維度為256維,要求輸出維度也是256維。有以下兩種操作:
256維的輸入直接經過一個3×3×256的卷積層,輸出一個256維的feature map,那麼引數量為:256×3×3×256 = 589,824
256維的輸入先經過一個1×1×64的卷積層,再經過一個3×3×64的卷積層,最後經過一個1×1×256的卷積層,輸出256維,引數量為:256×1×1×64 + 64×3×3×64 + 64×1×1×256 = 69,632。足足把第一種操作的引數量降低到九分之一!
1×1卷積核也被認為是影響深遠的操作,往後大型的網路為了降低引數量都會應用上1×1卷積核。
五、越深的網路就越難訓練嗎?– Resnet殘差網路
ResNet skip connection
傳統的卷積層層疊網路會遇到一個問題,當層數加深時,網路的表現越來越差,很大程度上的原因是因為當層數加深時,梯度消散得越來越嚴重,以至於反向傳播很難訓練到淺層的網路。為了解決這個問題,何凱明大神想出了一個“殘差網路”,使得梯度更容易地流動到淺層的網路當中去,而且這種“skip connection”能帶來更多的好處,這裡可以參考一個PPT:極深網路(ResNet/DenseNet): Skip Connection為何有效及其它 ,以及我的一篇文章:為什麼ResNet和DenseNet可以這麼深?一文詳解殘差塊為何能解決梯度彌散問題。 大家可以結合下面的評論進行思考。
六、卷積操作時必須同時考慮通道和區域嗎?– DepthWise操作
標準的卷積過程可以看上圖,一個2×2的卷積核在卷積時,對應影象區域中的所有通道均被同時考慮,問題在於,為什麼一定要同時考慮影象區域和通道?我們為什麼不能把通道和空間區域分開考慮?
Xception網路就是基於以上的問題發明而來。我們首先對每一個通道進行各自的卷積操作,有多少個通道就有多少個過濾器。得到新的通道feature maps之後,這時再對這批新的通道feature maps進行標準的1×1跨通道卷積操作。這種操作被稱為 “DepthWise convolution” ,縮寫“DW”。
這種操作是相當有效的,在imagenet 1000類分類任務中已經超過了InceptionV3的表現,而且也同時減少了大量的引數,我們來算一算,假設輸入通道數為3,要求輸出通道數為256,兩種做法:
1.直接接一個3×3×256的卷積核,引數量為:3×3×3×256 = 6,912
2.DW操作,分兩步完成,引數量為:3×3×3 + 3×1×1×256 = 795,又把引數量降低到九分之一!
因此,一個depthwise操作比標準的卷積操作降低不少的引數量,同時論文中指出這個模型得到了更好的分類效果。
EDIT:2017.08.25
本文在發出12小時後,一位知乎使用者私信了我,向我介紹了Depthwise和Pointwise的歷史工作,而Xception和Mobilenet也引用了他們16年的工作,就是Min Wang et al 的Factorized Convolutional Neural Networks,這篇論文的Depthwise中,每一通道輸出的feature map(稱為“基層”)可以不止一個,而Xception中的Depthwise separable Convolution, 正是這篇工作中“單一基層”的情況。推薦有興趣的讀者關注下他們的工作,這裡有篇介紹博文:【深度學習】卷積層提速Factorized Convolutional Neural Networks。而最早關於separable convolution的介紹,Xception作者提到,應該追溯到Lau- rent Sifre 2014年的工作 Rigid-Motion Scattering For Image Classification 6.2章節。
七、分組卷積能否對通道進行隨機分組?– ShuffleNet
在AlexNet的Group Convolution當中,特徵的通道被平均分到不同組裡面,最後再通過兩個全連線層來融合特徵,這樣一來,就只能在最後時刻才融合不同組之間的特徵,對模型的泛化性是相當不利的。為了解決這個問題,ShuffleNet在每一次層疊這種Group conv層前,都進行一次channel shuffle,shuffle過的通道被分配到不同組當中。進行完一次group conv之後,再一次channel shuffle,然後分到下一層組卷積當中,以此迴圈。
來自ShuffleNet論文
經過channel shuffle之後,Group conv輸出的特徵能考慮到更多通道,輸出的特徵自然代表性就更高。另外,AlexNet的分組卷積,實際上是標準卷積操作,而在ShuffleNet裡面的分組卷積操作是depthwise卷積,因此結合了通道洗牌和分組depthwise卷積的ShuffleNet,能得到超少量的引數以及超越mobilenet、媲美AlexNet的準確率!
另外值得一提的是,微軟亞洲研究院MSRA最近也有類似的工作,他們提出了一個IGC單元(Interleaved Group Convolution),即通用卷積神經網路交錯組卷積,形式上類似進行了兩次組卷積,Xception 模組可以看作交錯組卷積的一個特例,特別推薦看看這篇文章:王井東詳解ICCV 2017入選論文:通用卷積神經網路交錯組卷積
要注意的是,Group conv是一種channel分組的方式,Depthwise +Pointwise是卷積的方式,只是ShuffleNet裡面把兩者應用起來了。因此Group conv和Depthwise +Pointwise並不能劃等號。
八、通道間的特徵都是平等的嗎? — SEnet
無論是在Inception、DenseNet或者ShuffleNet裡面,我們對所有通道產生的特徵都是不分權重直接結合的,那為什麼要認為所有通道的特徵對模型的作用就是相等的呢? 這是一個好問題,於是,ImageNet2017 冠軍SEnet就出來了。
SEnet 結構
一組特徵在上一層被輸出,這時候分兩條路線,第一條直接通過,第二條首先進行Squeeze操作(Global Average Pooling),把每個通道2維的特徵壓縮成一個1維,從而得到一個特徵通道向量(每個數字代表對應通道的特徵)。然後進行Excitation操作,把這一列特徵通道向量輸入兩個全連線層和sigmoid,建模出特徵通道間的相關性,得到的輸出其實就是每個通道對應的權重,把這些權重通過Scale乘法通道加權到原來的特徵上(第一條路),這樣就完成了特徵通道的權重分配。作者詳細解釋可以看這篇文章:專欄 | Momenta詳解ImageNet 2017奪冠架構SENet
九、能否讓固定大小的卷積核看到更大範圍的區域?– Dilated convolution
標準的3×3卷積核只能看到對應區域3×3的大小,但是為了能讓卷積核看到更大的範圍,dilated conv使其成為了可能。dilated conv原論文中的結構如圖所示:
上圖b可以理解為卷積核大小依然是3×3,但是每個卷積點之間有1個空洞,也就是在綠色7×7區域裡面,只有9個紅色點位置作了卷積處理,其餘點權重為0。這樣即使卷積核大小不變,但它看到的區域變得更大了。詳細解釋可以看這個回答:如何理解空洞卷積(dilated convolution)?
十、卷積核形狀一定是矩形嗎?– Deformable convolution 可變形卷積核
圖來自微軟亞洲研究院公眾號
傳統的卷積核一般都是長方形或正方形,但MSRA提出了一個相當反直覺的見解,認為卷積核的形狀可以是變化的,變形的卷積核能讓它只看感興趣的影象區域 ,這樣識別出來的特徵更佳。
圖來自微軟亞洲研究院公眾號。要做到這個操作,可以直接在原來的過濾器前面再加一層過濾器,這層過濾器學習的是下一層卷積核的位置偏移量(offset),這樣只是增加了一層過濾器,或者直接把原網路中的某一層過濾器當成學習offset的過濾器,這樣實際增加的計算量是相當少的,但能實現可變形卷積核,識別特徵的效果更好。詳細MSRA的解讀可以看這個連結:可變形卷積網路:計算機新“視”界。
啟發與思考
現在越來越多的CNN模型從巨型網路到輕量化網路一步步演變,模型準確率也越來越高。現在工業界追求的重點已經不是準確率的提升(因為都已經很高了),都聚焦於速度與準確率的trade off,都希望模型又快又準。因此從原來AlexNet、VGGnet,到體積小一點的Inception、Resnet系列,到目前能移植到移動端的mobilenet、ShuffleNet(體積能降低到0.5mb!),我們可以看到這樣一些趨勢:
卷積核方面:
大卷積核用多個小卷積核代替;
單一尺寸卷積核用多尺寸卷積核代替;
固定形狀卷積核趨於使用可變形卷積核;
使用1×1卷積核(bottleneck結構)。
卷積層通道方面:
標準卷積用depthwise卷積代替;
使用分組卷積;
分組卷積前使用channel shuffle;
通道加權計算。
卷積層連線方面:
使用skip connection,讓模型更深;
densely connection,使每一層都融合上其它層的特徵輸出(DenseNet)
啟發
類比到通道加權操作,卷積層跨層連線能否也進行加權處理?bottleneck + Group conv + channel shuffle + depthwise的結合會不會成為以後降低引數量的標準配置?