1. Abstract
目前神經(jīng)網(wǎng)絡(luò)大部分都是運(yùn)行在具有強(qiáng)大的浮點(diǎn)運(yùn)算能力的服務(wù)器上面椿浓。如此龐大的網(wǎng)絡(luò)是無(wú)法在普通PC上面運(yùn)行取胎,更不可能在移動(dòng)端上面運(yùn)行。但是由于業(yè)務(wù)需要和程序設(shè)計(jì)需要匪蟀,我們可能想把CNN網(wǎng)絡(luò)到移動(dòng)端上面運(yùn)行椎麦。面對(duì)龐大的網(wǎng)絡(luò)和浮點(diǎn)運(yùn)算能力比較弱的移動(dòng)端,一些公司為此想降低CNN的復(fù)雜度同時(shí)保留大部分的精度材彪。所以這里我想為大家介紹了一下我了解過(guò)的一些efficient and state-of-the-art CNN观挎。
2. MobileNet V1
在傳統(tǒng)的CNN,當(dāng)中一層CNN的FLOPs計(jì)算:w * h * d_k * d_k * c_1 * c_2段化,雖然w和h都在降低維度嘁捷,但是channel卻一直以指數(shù)形式增加,那么每一層FLOPs都是越來(lái)越大的显熏。MobileNet v1想把這個(gè)卷積操作的FLOPs降低雄嚣,于是就利用到了depthwise convolution和pointwise convolution。如下圖所示:
- depthwise convolution filter一共有m個(gè)d_k * d_k大小的filter喘蟆,其中m是input features map的channels數(shù)量缓升。每個(gè)d_k * d_k的convolution filter對(duì)應(yīng)每個(gè)input features map的channel做convolution。我們可以這樣看蕴轨,每個(gè)filter都僅僅foucs當(dāng)前channel與其他的channel沒(méi)有信息流通港谊。
-
pointwise convolution filter就是1 * 1 convolution filters,大小為1 * 1 * c_1 * c_2橙弱,其中c_1為輸入的channel數(shù)量歧寺,c_2為輸出的channel數(shù)量燥狰。這個(gè)操作已經(jīng)是經(jīng)常常見(jiàn)了,我就不再多講斜筐。pointwise convolution就是僅僅foucs on relationship of channels與同一層channel上的所有feature沒(méi)有信息流通碾局。
我們將兩者結(jié)合起來(lái),就近似表達(dá)成為一個(gè)d_k * d_k * c_1 * c_2的convolution filters:
Convolution Block
我們可以算一下這種操作的FLOPs:w * h * 9 * c_1 + w * h * c_1 * c_2奴艾。這種壓縮可以大量的浮點(diǎn)運(yùn)算量净当,但也有良好的準(zhǔn)確率。這種方法當(dāng)然還是具有大量的浮點(diǎn)數(shù)運(yùn)算蕴潦,對(duì)于一些算力很弱的移動(dòng)設(shè)備像啼,我們還需要壓縮模型。那么MobileNet V1為了我們提供了收縮因子:用于控制模型當(dāng)中channel的個(gè)數(shù)潭苞。
用不同大小的MobileNet忽冻,在ImageNet Top-1 的準(zhǔn)確率比較:
3. ShuffleNet V1
ShuffleNet v1與MobileNet v1一樣使用了depthwise和pointwise的convolution操作來(lái)降低運(yùn)算量。但是ShuffleNet v1發(fā)現(xiàn)其實(shí)這種操作大多的FLOPS(浮點(diǎn)運(yùn)算)都是集中在pointwise convolution此疹。我們這里計(jì)算一下pointwise convolution的FLOPS:w * h * c_{input} * c_{output}
僧诚,相對(duì)于depthwise的FLOPS:w * h * 3 * 3 * c_{input}
(depthwise的kernel size 為3)。pointwise convolution的浮點(diǎn)運(yùn)算量是depthwise的c_{output} / 9倍蝗碎。在CNN當(dāng)中湖笨,output channels都是不斷增加的,所以FLOPS就越來(lái)越大蹦骑〈仁。考慮這一點(diǎn),ShuffleNet v1采用AlexNet的group convolution方式來(lái)降低pointwise的FLOPS眠菇。
如上圖所示边败,我們將channels分開(kāi)若干個(gè)group,分別做pointwise convolution捎废。我們算一下這個(gè)操作的FLOPS:h * w * (c_{input} / g) * (c_{output} / g) * g = hwc_{input}c_{output} / g
笑窜。明顯group convolution將原來(lái)的pointwise convolution降低了g倍(a圖)。但進(jìn)行了這種操作以后登疗,不同group之間的channels的連接就基本上沒(méi)有了排截。因此shuffleNet v1增加了channel shuffle的操作,增加了不同group之間的channels的信息連接多樣性(b圖谜叹,c圖)匾寝。
上圖b,c為shuffleNet Units。a圖是最原始的設(shè)計(jì)荷腊,后來(lái)用group convolution代替當(dāng)中的pointwise艳悔。b圖為convolution stride = 1的Unit,c圖為convolution stride = 2的Unit女仰。
那么group設(shè)置為多少好呢猜年?論文中作了一些對(duì)比試驗(yàn)來(lái)看group設(shè)置多少好抡锈。
我們可以留意到在同樣的FLOPS復(fù)雜度的情況下乔外,scale越小的Networks使用越大的group越有利提高精度床三。在同一個(gè)FLOPS的復(fù)雜度下,group越大那么就允許越多的channels杨幼,越多的channels包含的信息量越多那么精度也能有所提高撇簿。此外,越小的網(wǎng)絡(luò)從channels增加得到精度增益越大差购。那么我們是不是越設(shè)置越大的group越好呢四瘫?剛剛說(shuō)的是同樣的FLOPS復(fù)雜度上,但是越大group使得group convolution趨向于depthwise convolution欲逃,那么channels之間的連接幾乎沒(méi)有找蜜,這是不利于網(wǎng)絡(luò)的。
4. MoblieNet v2
MoblieNet v2論文題目就說(shuō)明其兩個(gè)重要的keypoint诚纸。一個(gè)Inverted Residual,另外一個(gè)是Linear Bottlenecks裕菠。這篇論文的理論看得十分費(fèi)力咬清,到現(xiàn)在還是看得一般般懂。所以我這里就說(shuō)一下自己理解到的state of the art奴潘。
4.1 Inverted Residual
在moblieNet v1中,我們沒(méi)有看到residual的存在影钉,所以在v2當(dāng)中我們加入了residual画髓,但我們沒(méi)有直接照搬其內(nèi)容
這里的是Inverted residual block。為啥我們這樣操作呢平委?因?yàn)椴煌趓esidual block奈虾,depthwise convolution的計(jì)算量很低,所以我們可以適當(dāng)增加depthwise(增加t倍)計(jì)算的channels數(shù)量來(lái)提高模型精度廉赔。其實(shí)肉微,其認(rèn)為residual block這樣先降維(降低channels),使得下一層的信息有所一定的損失蜡塌,再加上depthwise碉纳,損失更大。那么我們采用升維的操作來(lái)增加depthwise convolution的信息量馏艾,這樣減少每層block當(dāng)中信息損失劳曹。
4.2 Linear Bottlenecks
這個(gè)Linear的操作是在Inverted Residual block的最后奴愉。我們想一下之前的Inverted Residual block,頭尾的維度(channels數(shù)量)顯然比中間要低铁孵,
我們可以理解成為y = B^{-1} * Relu(A * x)
锭硼。x為輸入,y為輸出蜕劝,A為中間的升維操作檀头,B的逆矩陣為降維操作。而輸入和輸出的維度是近似相同的岖沛,那么其實(shí)我們用linear操作更為適合磅网。若使用Relu的話最后輸出可能出現(xiàn)0。這樣輸出是不可逆的宏赘,信息也會(huì)損失疾棵。所以我們最后一層使用Linear來(lái)保留大量有用的信息。再者我們也可以這樣理解馆蠕,最后一層輸出的降維操作期升,那么假如用Relu會(huì)加劇信息流失。而論文最后的Appendix互躬,作者認(rèn)為其實(shí)目標(biāo)(圖像)是可以用一個(gè)低維子空間表示播赁,通過(guò)降低激活空間的維度最終希望讓感興趣信息充滿整個(gè)字空間。
那有人會(huì)問(wèn)我:既然參數(shù)是變多了吼渡,那么MoblieNet v2還是速度不是應(yīng)該更慢嗎容为?其實(shí)在頭尾的channels數(shù)量是很少,從而減少了Inverted Residual block中間升維的影響寺酪。
5. ShuffleNet V2
ShuffleNet v2論文題目是說(shuō)Guidelines for Efficient CNN Architecture Design坎背。一般衡量CNN網(wǎng)絡(luò)的理論運(yùn)算時(shí)間,我們都是用FLOPS(浮點(diǎn)運(yùn)算次數(shù))來(lái)表示寄雀。但其實(shí)這個(gè)有不太符合實(shí)際情況的得滤。首先在不同硬件平臺(tái)上,convolution運(yùn)算可能是存在優(yōu)化的盒犹。例如一個(gè)做3 * 3的convolution操作運(yùn)算時(shí)間不一定是1 *1的convolution操作的9倍懂更。因?yàn)樵贑UDNN下是有CNN并行優(yōu)化的,所以不能單單用FLOPS來(lái)衡量一個(gè)CNN的運(yùn)算時(shí)間急膀。此外FLOPS只是考慮到浮點(diǎn)的運(yùn)算次數(shù)沮协,但是還有其他因素影響CNN的實(shí)際運(yùn)算時(shí)間,例如memory access cost —— MAC(內(nèi)存訪問(wèn)損失)卓嫂,ShuffleNet v2就是將其作為指標(biāo)設(shè)計(jì)出來(lái)的模型并得到4條Guidelines慷暂。
5.1 相同的通道寬度可最小化內(nèi)存訪問(wèn)成本(MAC)
對(duì)于1 * 1的卷積,我們考慮以下其MAC:hwc_{1}(讀取輸入的feature map的MAC) + hwc_{2}(寫入輸出的feature map的MAC) + c_{1} c_{2}(讀取1 * 1的卷積大忻)呜呐。那么總的MAC為:h * w * (c_{1} + c_{2}) + c_{1} * c_{2}
就斤。那么1 * 1的卷積FLOPS為:B = h * w * c_{1} * c_{2}
。通過(guò)三角不等式我們可以得到以下的不等式:
根據(jù)三角不等式蘑辑,我們可以知道僅且盡當(dāng)c_1 = c_2時(shí)候洋机,等號(hào)成立且MAC最小。所以我們希望convolution操作的輸入輸出channel一致洋魂。
5.2 過(guò)度的組卷積會(huì)增加 MAC
再考慮有g(shù)個(gè)group convolution的時(shí)候绷旗,MAC值應(yīng)該是:h * w * (c_{1} + c_{2}) + c_{1} * c_{2} / g
,F(xiàn)LOPS值應(yīng)該是:B = h * w * c_{1} * c_{2} / g
副砍。在一般的情況下衔肢,input features的大小是固定的,其次我們要討論的是group的個(gè)數(shù)對(duì)MAC的影響豁翎,那么我應(yīng)該控制FLOPS都是一致的角骤。因此我們假設(shè)給定的輸入input features size以及FLOPS,那么我們MAC式子進(jìn)行轉(zhuǎn)換可以得到:h * w * c_{1} + B * g / c_{1} + B / hw
心剥“钭穑可見(jiàn)Group個(gè)數(shù)越多那么MAC也就越大∮派眨回顧之前討論shuffleNet v1的時(shí)候蝉揍,在固定的features map和FLOPS上,group增加那么輸出的channels(c_{2})也就應(yīng)該同等比例增加畦娄。隨之MAC的第一項(xiàng)h * w * (c_{1} + c_{2})
也變大又沾。
5.3 網(wǎng)絡(luò)碎片化(例如 GoogLeNet 的多路徑結(jié)構(gòu))會(huì)降低并行度
在論文當(dāng)中的Appendix給出了一些碎片化的convolution:
這種操作是將一個(gè)大kernels的conv轉(zhuǎn)換為多個(gè)小kernels的conv。這樣確實(shí)有助于提高模型的精度熙卡,但是這是通過(guò)模型的運(yùn)行效率來(lái)交換的杖刷。這樣效率的差異在并行計(jì)算強(qiáng)的硬件上是尤其突出。
在GPU上差異是十分明顯再膳,但是在ARM就不是特別明顯了挺勿。所以這個(gè)Guideline可以作為思考精度和效率的取舍點(diǎn)。
5.4 元素級(jí)運(yùn)算不可忽視
一些Elements-wise的操作(如Add喂柒,ReLu),雖然這些FLOPS幾乎是沒(méi)小,但是它是存在大量的MAC禾嫉,所以不能忽略其對(duì)效率的影響灾杰。
根據(jù)以上這個(gè)4條Guideline,作者設(shè)計(jì)出ShuffleNet v2:
我們保證每個(gè)Conv的輸入channels數(shù)量和輸出channels數(shù)量是一致的(符合G1)熙参,我們這里沒(méi)有使用Group convolution艳吠,而是采用channels split的操作(Group可以看作是2,其中論文為了簡(jiǎn)便兩個(gè)branch的channel數(shù)量是一樣的)孽椰,盡可能減少了group的數(shù)量(符合G2)昭娩,在圖c當(dāng)中凛篙,其中一個(gè)branch是identity沒(méi)有減弱并行度(符合G3),最后我們?cè)谧詈筮B接上沒(méi)有用上Add和ReLU栏渺,而是Concat降低一定的MAC(符合G4)呛梆。首先這個(gè)構(gòu)造是可以提高模型的運(yùn)行效率的,我們可以看看下圖的一小部分實(shí)驗(yàn)結(jié)果(有興趣的同學(xué)可以看看論文的實(shí)驗(yàn)部分):
可見(jiàn)shuffleNet v2的效果是挺優(yōu)秀的磕诊。
這里我們可以討論一下為什么shuffleNet v2也能夠在提高模型精度填物。
- 在同一樣的FLOPS下,效率越高的模型霎终,其可以將模型做得更深滞磺,精度自然也會(huì)上來(lái)。
- 在每一個(gè)block里面莱褒,我們都有一個(gè)branch(一般的feature map)是直接join到最后的結(jié)果的击困,它存在一種特征復(fù)用的效果。這一塊有點(diǎn)類似于DenseNet广凸。我們通過(guò)下圖每一層權(quán)值的L1-norm對(duì)比得知:
由于DenseNet把當(dāng)前輸出連接到后續(xù)的每一個(gè)blocks阅茶,所以它引入了冗余性,而ShuffleNet v2將特征從用雖然也是會(huì)傳遞到后續(xù)的每一層炮障,但是傳遞的feature數(shù)量是呈指數(shù)遞減的目派。在本論文當(dāng)中,只有一半的feature map直接join到輸出當(dāng)中胁赢,再通過(guò)channels shuffle企蹭,本層傳遞到后兩層的feature map的數(shù)量只有0.25,如此類推智末。那么重用率大約是r^{j - i}
谅摄,r為channel split當(dāng)中identity的占比數(shù)量,而i系馆,j代表目標(biāo)層序號(hào)送漠。
6. Summary
我覺(jué)得這些CNN的網(wǎng)絡(luò)其實(shí)給我的感覺(jué)是設(shè)計(jì)符合自己業(yè)務(wù)需求的Guidelines。所以根據(jù)需求去選擇符合自己的Guidelines便好由蘑,有空我會(huì)將這些模型都寫一遍闽寡,讓自己和大家都能夠 get your hands dirty。講真算法不能光看論文還需要落地的尼酿。