經典分類CNN模型系列其八:ResNeXt
介紹
越來越喜歡Facebook的東西了,雖然很久以來我一直是個Google產品及技術的忠實粉絲。但最近在AI框架上一直頻繁去翻弄Pytorch/Caffe2,感覺其API及核心模組設計結構比Tensorflow更加清晰、易懂。
同時看到Facebook出的像ResNext這種分類網路比Google一直在捧的Inception v4/Inception Resnet v2等網路也要更為簡單而高效。
本來始終都不能從Inception v4/Inception Resnet系列網路的複雜噩夢中解脫,但看過ResNeXt後,終於如釋重負,恢復了自己一直以來的哲學信仰。這個世界的很多高深、有效的道理其實都可以有簡單的方式去表達。
ResNeXt可以說是基於Resnet與Inception 'Split + Transfrom + Concat'而搞出的產物,結構簡單、易懂又足夠強大。在行業標誌性的Imagenet 1k資料集上它取得了比Resnet/Inception/Inception-Resnet系列更佳的效果。
以下為構成ResNeXt網路的基本block單元。

ResNeXt與Resnet基本模組對比
乍看上去它與Inception Resnet中所有的基本單元極為相似,可實際上它block當中的每個sub branch都是相同的,這是它與IR網路結構的本質區別,而正是基於這區別,我們可以使用Group convolution來對其進行良好實現。
ResNeXt
ResNeXt網路的整體結構
正如ResNet是由基本的Residual模組一個個累積起來的一樣,ResNeXt網路也是由上圖中所描述的模組一個個累積起來的。下面表格當中,我們能看到ResNeXt與ResNet網路的整體結構。

ResNext-50與ResNext-50的整體網路結構對比
在這裡它Follow了之前VGG/ResNet等網路中的一貫做法:一是如果一個block輸出同樣大小的chnnel size,那麼blocks輸入、輸出有著相同的hyper-parameters(即width和filter sizes);二是若其輸出與輸入有著不同的大小(如downsampling操作),那麼就需要相應地擴大filters的數目。
從上面表格裡,亦能看出ResNeXt與ResNet一樣都follow這樣兩條準則以保證每個block的計算量類似,所傳遞的資訊也不會因層數遞增而有太多丟失。
ResNeXt網路模組的變形
下面圖中顯示了三種ResNeXt網路模組的變形。它們在數學計算上是完全等價的,而第三種包含有Group convolution操作的正是最終ResNeXt網路所採用的操作。

ResNeXt網路模組的三種等價形式
ResNeXt網路的Capacity
一般增強一個CNN的表達能力有三種手段:一是增加網路層次即加深網路(目前CNN已經由最初Alexnet的不到十層增加到了成百上千層,而實際實驗結果表明由層次提升而帶來的邊際準確率增加已是越來越少);二是增加網路模組寬度(可見我們之前有介紹過的Wide residual network,可寬度的增加必然會帶來指數級的引數規模提升,因此它並非為主流CNN設計所認可。);
三是改善CNN網路結構設計(當然在不增加模型複雜度的情況下通過改良模型設計以來提升模型效能是最理想的做法,不過其門檻則實在是太高,不然Google/Facebook/Microsoft的那些埋頭設計網路/調參的哥們兒就沒辦法拿那麼高工資了。:))。
ResNeXt的做法可歸為上面三種方法的第三種。它引入了新的用於構建CNN網路的模組,而此模組又非像過去看到的Inception module那麼複雜,它更是提出了一個cardinatity的概念,用於作為模型複雜度的另外一個度量。Cardinatity指的是一個block中所具有的相同分支的數目。
作者進行了一系列對比實驗,有力證明在保證相似計算複雜度及模型引數大小的前提下,提升cardinatity比提升height或width可取得更好的模型表達能力。
下圖為反映Cardinatity增加對模型效能提升的實驗結果。

Cardinatity增加對模型效能提升的影響
實驗結果
ImageNet-1K
首先在標準的ImageNet-1K上進行了實驗,並與其它state-of-art的模型進行了對比。

ResNeXt與ResNet網路在ImageNet-1K資料集上的效能對比
可以看出ResNeXt網路相對於ResNet網路可在training accuracy/val accuracy上都取得提升,但training accuracy上的提升顯得更大。作者分析認為是因為ResNeXt的表達能力更強了,但此類結果改善卻並非是因為Regularization的因素導致的。
為了減少可能的overfitting以來有效利用ResNext的表達能力,作者還試著在更大的ImageNet-5K上進行了實驗。
下表為ResNeXt與更多CNN網路在ImageNet-1K上的結果比較。

ResNeXt與其它CNN網路在ImageNet-1K上的結果比較
ImageNet-5K
下面的圖與表格中反映了ResNeXt與ResNet相比在更大的ImageNet-5K資料集上的優勢。

ResNeXt與ResNet網路在ImageNet-5K上的結果比較
程式碼分析
原文的程式碼是基於Torch來完成的,因為此Framework已經不再維護,所以在這裡還是通過由Caffe所表達的結構來分析下此模型的組成。
下面是一個典型的ResNeXt網路模組,可以與之前的ResNet模組對比下,其主要的區別就是中間的3x3 conv transform層由direct conv變為了cardinatity為32的group conv。
layer { name: "stage1_unit2_conv1" type: "Convolution" bottom: "stage1_unit1_plus" top: "stage1_unit2_conv1" convolution_param { num_output: 128 kernel_size: 1 stride: 1 pad: 0 bias_term: false } } layer { name: "stage1_unit2_bn1" type: "BatchNorm" bottom: "stage1_unit2_conv1" top: "stage1_unit2_conv1" batch_norm_param { use_global_stats: true eps: 2e-5 } } layer { name: "scale_stage1_unit2_bn1" bottom: "stage1_unit2_conv1" top: "stage1_unit2_conv1" type: "Scale" scale_param { bias_term: true } } layer { name: "stage1_unit2_relu1" type: "ReLU" bottom: "stage1_unit2_conv1" top: "stage1_unit2_conv1" } layer { name: "stage1_unit2_conv2" type: "Convolution" bottom: "stage1_unit2_conv1" top: "stage1_unit2_conv2" convolution_param { num_output: 128 kernel_size: 3 stride: 1 group: 32 pad: 1 bias_term: false } } layer { name: "stage1_unit2_bn2" type: "BatchNorm" bottom: "stage1_unit2_conv2" top: "stage1_unit2_conv2" batch_norm_param { use_global_stats: true eps: 2e-5 } } layer { name: "scale_stage1_unit2_bn2" bottom: "stage1_unit2_conv2" top: "stage1_unit2_conv2" type: "Scale" scale_param { bias_term: true } } layer { name: "stage1_unit2_relu2" type: "ReLU" bottom: "stage1_unit2_conv2" top: "stage1_unit2_conv2" } layer { name: "stage1_unit2_conv3" type: "Convolution" bottom: "stage1_unit2_conv2" top: "stage1_unit2_conv3" convolution_param { num_output: 256 kernel_size: 1 stride: 1 pad: 0 bias_term: false } } layer { name: "stage1_unit2_bn3" type: "BatchNorm" bottom: "stage1_unit2_conv3" top: "stage1_unit2_conv3" batch_norm_param { use_global_stats: true eps: 2e-5 } } layer { name: "scale_stage1_unit2_bn3" bottom: "stage1_unit2_conv3" top: "stage1_unit2_conv3" type: "Scale" scale_param { bias_term: true } } layer { name: "stage1_unit2_plus" type: "Eltwise" bottom: "stage1_unit1_plus" bottom: "stage1_unit2_conv3" top: "stage1_unit2_plus" eltwise_param { operation: SUM } } layer { name: "stage1_unit2_relu" type: "ReLU" bottom: "stage1_unit2_plus" top: "stage1_unit2_plus" }
參考文獻
- Aggregated Residual Transformations for Deep Neural Networks, Saining-Xie, 2017
- ofollow,noindex">https://github.com/cypw/ResNeXt-1