CNN模型-ResNet、MobileNet、DenseNet、ShuffleNet、EfficientNet

Cinnamon AI Taiwan
13 min readJul 5, 2019

--

相信各位讀者在看完之前的文章後都對CNN有了一定的認識,今天帶大家來認識幾個經典與近期推出的CNN骨架

CNN演進

下圖為我們了展示了2018前常用CNN模型大小與Accuracy的比較,網路上不乏介紹CNN演進的文章[LeNet/AlexNet/Vgg/Inception/ResNet],寫的也都很好。今天我們為各位讀者介紹幾個最新的CNN模型,如何搭建以及他們的優勢在哪裡。

CNN模型比較[Source]

CNN經典架構

要了解最新模型的優勢,有一些架構的基本觀念還是得先認識,下面就讓我們來看看:Inception殘差網路Depthwise separable convolution的觀念

Inception

Inception的架構最早由Google在2014年提出,其目的在於結合不同特徵接受域(Receptive Field)的Kernel[對CNN不熟的讀者們可以先參考這篇:入門],而我們要怎麼做到這一點呢?大家可以先看看下圖:

Inception架構[Source]

圖中展示了經典的Inception架構,接在Feature Maps後一共有四條分支,其中三條先經過1*1 kernel的壓縮這樣做的意義主要是為了控制輸出Channels的深度,並同時能增加模型的非線性性,一條則是先通過3*3 kernel,而為了確保輸出Feature Map在長寬上擁有一樣尺寸,我們就要借用Padding技巧,1*1 kernel輸出大小與輸入相同,而3*3、5*5 kernel則分別設定補邊值為1、2,當然在tensorflow、Keras中最快的方式就是設定padding=same,就能在步伐為1時確保輸出尺寸維持相同。對1*1 convolution運用方式有興趣的讀者們可以參考吳恩達的影片:1x1 Convolutions,講解得相當清楚。具體實現代碼如下:

殘差網路

殘差結構[Source]

上圖為經典的殘差結構,將輸入的input與經過2–3層的F(x)跨接並相加,使輸出表示為y=F(x)+x,這樣的好處在於反向傳播時能保至少會有一個1存在,降低梯度消失(vanishing gradient)發生的可能性,什麼意思呢?舉個例子來說,如果上方function中y(輸出)對x偏微分,有一項是x自己對自己微分(得到1),在鏈鎖率中每一項都保有一個1,比較不容易梯度消失,因此可以搭建更深的網路。

Resnet-Backpropagation[Source]

下方利用tensorflow實現殘差結構。

Depthwise separable convolution

Depthwise+Pointwise[Source]

上圖為 Depthwise separable convolution的架構,有別於一般的卷積,其主要可以分為兩個步驟,第一個步驟先將輸入Feature Maps與k*k 、深度與input 相同的kernel卷積(Depthwise),並且每一個Feature Map與Kernel的卷積是獨立的。第二步再用1*1 、深度與輸出深度相同的kernel卷積(Pointwise),這樣的好處是可以節省大量的參數,下方我們試著算算看參數量差別:

藉由上方程式可以看出,同樣輸出是300*300*64,separable convolution的參數量大概是一般Convolution的1/6,達到輕量化模型的目的。如果只想執行Depthwise convolution可以參考下方程式碼:

CNN模型

ResNetV2

(a) ResnetV1 (e) ResnetV2 以及其他變形[Source]

ResnetV2同樣由Kaiming He團隊提出,承襲ResnetV1的殘差概念,但在Identity branch(左線)與 Residual branch(右線)上做了一些更改。

拿掉Residual Block後的ReLU

作者認為,ReLU接在每個Residual block後面會導致Forward propagation陷入單調遞增,降低表達能力。

拿掉Identity branch後的BN

而如果使用圖B的做法,BN層會改變Identity branch的訊息分佈,造成收斂速度下降。論文中還有用到一個小技巧,先用1*1 kernel壓縮深度,最後再用1*1 kernel回放深度,藉此降低運算。

有了 Residual_Block,大家就可以依照論文給的參數去重建ResnetV2模型,論文中還有一些變化,像是多種變形的Residual_Block,有興趣的讀者們可以再深入去瞭解。想要快速搭建的讀者們可以參考:Keras Application

Inception-ResNet

InceptionResnet-A block[Source]

Inception-ResNet也是目前時常會用到的model,像是Inception-ResNetV2、InceptionV4等模型,我們上面有了Inception以及Residual Block的觀念其實就很容易理解Inception-ResNet。模型核心就是把Residual Block中的Residual branch修改成Inception架構,文獻中提出了三種不一樣的組合,我們在這裡實現InceptionResnet-A block,想要快速搭建的讀者們一樣可以參考:Keras Application

DenseNet

Densenet架構[Source]

DenseNet為輕量模型的代表之一,其導入跨接於Feature Map之中(類似殘差概念)。下方代碼實現Dense_Stage_Block(這邊同時導入Depthwise separable convolution來進一步節省參數,加快模型速度,原文為一般卷積層):

ShuffleNetV2

談到輕量級模型,『ShuffleNet』應該是目前常見模型中的翹楚。輕量級模型主要有兩個分支,分別為 UC Berkeley and Stanford University推出的『SqueezeNet』以及Google推出的 『MobileNet』,Depthwise separable convolution就是源於MobileNet,而SqueezeNet的原理與Inception非常類似在這就先不多加贅述。

ShuffleNet以SqueezeNet為基礎並做了一些改變,其原理與Depthwise separable convolution有幾分神似,Depthwise separable convolution是由Depthwise+Pointwise convolution組成,而之所以要運用Pointwise convolution是因爲Depthwise中Feature Maps通道不流通的問題,在Depthwise Convolution中每一個Kernel都只對一張Feature Map卷積,並不能看到全局的訊息。而在ShuffleNet中,Group Convolution一樣有通道不流通的問題(參考下圖,與Depthwise非常類似),然而不同於MobileNet 使用Pointwise convolution來解決,ShuffleNet使用的方法就是『Shuffle』,直接把不同Group的Feature Map洗牌,送到下一層,這樣一來又進一步節省了Pointwise convolution中的參數,達到『超輕量』級別。

Group Convolution[Source]

好,有了一些基本觀念,現在讓我們來看看ShuffleNetV2相較於V1做了哪些重要的改變:

1*1卷積

首先,V1使用大量的1*1卷積,會增加MAC(乘法加法操作),在Depthwise separable convolution中佔運算及參數大宗的就是Pointwise Convolution,因此在V2中先對進入Block的Feature Maps做Split。

輸出使用Concate

作者發現,Pixelwise的運算如相加與ReLU也是造成MAC上升的主因,因此V2中使用Concat取代V1的Add。

ShufflenetV1 以及 ShufflenetV2,(a) V1基本架構、(b) 帶有downsampling的V1架構、© V2基本架構、(d)帶有downsampling的V2架構[Source]

下方程式碼為大家示範如何搭建一個ShuffleNetV2的Block,其中比較要注意的是Shuffle_group要能被輸入Feature Map通道深度所整除。

EfficientNet

Efficientnet由 Google於2019年提出,透過Google AutoML的技術,搭建了八種高效的模型,分別為B0-B7,而如果我們將細節拆開來看,其實Bottleneck是由MobileNetV2所提出的 Inverted residual block加上Squeeze-and-Excitation Networks所組成,所以我們其實只要會搭建 MBConv block就能重現EfficientNet的架構,下方我們先來看看MobileNetV2 相較於V1與Resnet做了哪些重要改變。

EfficientnetB0架構[Source]

先擴張再壓縮

作者認為,當低通道數的Feature Map經過ReLU激活後,所有值都會大於等於零,造成大量訊息的流失,因此有別於Resnet先壓縮、V1直接做Depthwise separable convolution,MobileNetV2則是先透過Pointwise卷積擴張Feature Map深度。

跨接

相較於V1、V2採用ReseNet概念,對Feature Map進行跨接。

輸出改用線性激活

如上方提到的,作者認為低通道數的Feature Map不適合使用ReLU激活,因此將輸出層改用線性激活,如果想要使用ReLU的話,要確保輸出通道深度。

MobilenetV1 、MobilenetV2、Resnet 比較[Source]

來跟不同陣營的shuffleNet 架構比較一下,MobileNetV2推出時ShuffleNetV2還沒推出,所以圖中是與ShuffleNetV1比較。

Shufflenet、MobilenetV2比較[Source]

下方程式碼示範如何搭建MobileNetV2中的Residual_block

SENet(Squeeze-and-Excitation Networks)

SENET_Block[Source]

有了Inverted residual block,我們還缺Squeeze-and-Excitation Networks,SENet的核心思想在於通過網絡去學習特徵權重,使得有效的特徵圖權重大,無效或效果小的特徵圖權重小的方式訓練模型達到更好的結果[Source],我認為跟Attention有幾分神似。結合Residual後的架構如上,透過Global Average Pooling獲得全局訊息(Squeeze),利用FC層獲取語意訊息,先壓縮再擴張(Excitation),最後將各個Feature Map得到係數去乘回本來的Input(中間壓縮層運用ReLU感覺不太適合?),具體結合Inverted residual block,建構MBConv代碼如下。有了MBConv_Block,我們就可以重建EfficientNet,大家可以自己來搭搭看。

MobileNetV3

只能說大神們發論文的速度比我們看論文的速度還要快,MobilenetV3傳承V1 的 Depthwise separable convolution、V2的跨接與先放大再壓縮觀念,並加入了Squeeze-and-Excitation Networks,所以整個架構上與EfficientNet的MBConvBlock很相似,除此之外MobilenetV3在激勵函數上做了一些變動:

H-swish

部分Block中的ReLU使用H-swish取代,Sigmoid則使用H-sigmoid取代,H-swish是參考swish函數設計,主要是由於swish函數運算較慢,作者實驗證實,使用H-swish能提高準度。

H-swish激勵函數[Source]
激勵函數之間的差異[Source]

下圖為MobileNetV3 與 V2的比較圖,圖中可以發現相同Latency下,V3模型在Top-1 Accuracy上都較為勝出。

MobilenetV3 v.s MobilenetV2[Source]

下方代碼實現MobileNetV3的Bottleneck:

結論

今天為讀者們介紹了幾個最新CNN架構的核心技術,相信大家在看完後都有所收穫,往後在搭建模型時,也不會侷限在pretrained model,而是能依照自己的需求與想法打造最適合的Model。最後,如有任何問題也歡迎留言或來信討論!

--

--