Date: 2020/02/07
Author: CW
Foreword:
輕量化網(wǎng)絡(luò)是深度學(xué)習(xí)領(lǐng)域的研究熱點(diǎn)之一,其目標(biāo)是在網(wǎng)絡(luò)的參數(shù)量少洛退、訓(xùn)練和預(yù)測(cè)速度快的情況下又能夠保持一定的準(zhǔn)確率瓣俯,以下是一些常用的減少網(wǎng)絡(luò)計(jì)算量的方法:
i). 網(wǎng)絡(luò)模型設(shè)計(jì):使用組卷積(Group Conv)、1x1 卷積(Ponit-Wise Conv)等在達(dá)到相同(或近似)效果的同時(shí)減少計(jì)算量兵怯,類似的案例如 Inception彩匕、Xception、ShuffleNet 以及本文的主角MobileNet等媒区;
ii). 剪枝: 通過剪去網(wǎng)絡(luò)中的冗余部分來減少網(wǎng)絡(luò)計(jì)算量驼仪;
iii). 知識(shí)蒸餾:利用大模型(Teacher-Model)來輔助小模型(Student-Model)學(xué)習(xí)掸犬,從而在小模型上達(dá)到目標(biāo)效果。
MobileNet是Google的作品绪爸,能夠?qū)⒛P筒渴饝?yīng)用于移動(dòng)端登渣,同時(shí)又保證良好的效果,目前Google Pixel 系列的手機(jī)就是用的MobileNet毡泻。MobileNet目前更新到了v3版本,CW參考和收集了網(wǎng)上的資料及博文粘优,在本文中會(huì)從入門到放棄...哦不仇味,是會(huì)從v1到v3都進(jìn)行解讀,供廣大帥哥靚女們參考學(xué)習(xí)雹顺。如有不當(dāng)之處丹墨,盡管反饋,大家一起學(xué)習(xí)與進(jìn)步嬉愧,歡迎交流贩挣,謝謝!
Outline
1没酣、MobileNetv1
? ? ?i). 對(duì)標(biāo)準(zhǔn)卷積層進(jìn)行改進(jìn)
? ? ?ii). 使用2個(gè)超參數(shù)構(gòu)建更小的模型
2王财、MobileNetv2
? ? ?i). 擴(kuò)展層:Expansion Layer
? ? ?ii). 線性瓶頸:Linear Bottleneck
? ? ?iii). “倒”殘差結(jié)構(gòu):Inverted Residual
3、MobileNetv3
? ? ?i). 新的非線性激活函數(shù):h-swish
? ? ?ii). 基于Squeeze & Excitation(SE)的輕量級(jí)注意力結(jié)構(gòu)
? ? ?iii). 修改了部分v2的結(jié)構(gòu):頭部卷積核的通道數(shù)及最后的尾部結(jié)構(gòu)
? ? ?iv). 網(wǎng)絡(luò)結(jié)構(gòu)搜索:資源受限的NAS(Platform-Aware NAS)與 NetAdapt
4裕便、MobileNet為何這么快绒净?
MobileNetv1
v1的主要工作是將標(biāo)準(zhǔn)的卷積過程拆為兩個(gè)步驟 —— Depth-Wise Conv 和 Point-Wise Conv,并且引入2個(gè)超參偿衰,減少了計(jì)算量并且模型也更小,從而可以輕松地匹配移動(dòng)和嵌入式視覺應(yīng)用的設(shè)計(jì)要求下翎。
i). 對(duì)標(biāo)準(zhǔn)卷積層的改進(jìn) —— Depth-Wise Conv 和 Point-Wise Conv
Depth-Wise Conv(簡稱dw),也稱深度可分離卷積胆萧,它將卷積核的每個(gè)通道分別應(yīng)用于輸入特征圖的每個(gè)通道(這樣郑口,輸入和輸出的通道數(shù)維持一致),而非如標(biāo)準(zhǔn)卷積般將輸入特征圖的所有通道加權(quán)組合在一起瞻离。
Point-Wise Conv(簡稱pw), 也稱逐點(diǎn)卷積乒裆,它使用1x1大小的卷積核,用于組合深度可分離卷積的輸出結(jié)果(將深度可分離卷積的輸出通道數(shù)映射到目標(biāo)通道數(shù))肉迫。
標(biāo)準(zhǔn)卷積將提取空間特征和通道之間的相關(guān)性組合在一起,而MobileNet將其分解為Depth-Wise + Point-Wise跌造,這樣的效果是先基于各個(gè)通道提取空間特征(空間相關(guān)性),之后再組合通道之間的相關(guān)性族购,這種因式分解操作具有大幅度減少計(jì)算和模型大小的效果壳贪。
為何說這樣能夠減少計(jì)算量?根據(jù)上圖寝杖,舉個(gè)例子動(dòng)手計(jì)算下才有說服力(下文均使用 channel first 慣例违施,所謂的計(jì)算量指乘法次數(shù)):
(a) 表示標(biāo)準(zhǔn)卷積的過程:有N個(gè)卷積核,每個(gè)卷積核維度是M xx
瑟幕,輸入特征圖的通道數(shù)是M磕蒲,輸出特征圖維度為N x?
x
,計(jì)算量為
只盹;
(b) 表示dw的過程:用M個(gè)維度為1 x? x
的卷積核去卷積對(duì)應(yīng)輸入特征圖的M個(gè)通道辣往,得到M個(gè)輸出結(jié)果,注意這M個(gè)結(jié)果不會(huì)進(jìn)行相加(相比標(biāo)準(zhǔn)卷積是卷積輸入特征圖的所有通道鹿霸,并累加這M個(gè)結(jié)果)排吴,輸出結(jié)果的維度是
,這時(shí)計(jì)算量為
?x
懦鼠;
(c) 表示pw的過程:用N個(gè)維度為的卷積核卷積上述(b)的輸出結(jié)果钻哩,最終得到維度為
的 feature map。這個(gè)過程和普通卷積無異肛冶,只是卷積核大小為1 x 1街氢,此時(shí)計(jì)算量是
。
(b) + (c) 總共的計(jì)算量是+
睦袖,我們拿它除以標(biāo)準(zhǔn)卷積 (a)的計(jì)算量珊肃,來看看縮減了多少:
=
也就是說,如果使用將我們最常使用的3x3標(biāo)準(zhǔn)卷積分解為dw+pw烈和,那么計(jì)算量將縮減為原來的有多恬试!
根據(jù)paper原文的意思训柴,有些點(diǎn)還需要提下:
MobileNet在每一層均使用BN和ReLU兩種非線性變換;
與標(biāo)準(zhǔn)卷積相比宣赔,dw非常有效吏祸。然而蹈矮,它只會(huì)濾除輸入通道,不會(huì)將它們組合起來以創(chuàng)建新功能北滥。因此再芋,需要通過pw來計(jì)算深度卷積輸出的線性組合的附加層來生成這些新特征。
ii). 使用2個(gè)超參數(shù)構(gòu)建更小的模型
(1) 寬度乘數(shù)(mulitiplier)
記寬度乘數(shù)為α,其作用是在每層均勻地減薄網(wǎng)絡(luò)壳猜。對(duì)于給定的層和寬度乘數(shù)α蓖谢,輸入通道M的數(shù)量變?yōu)棣罬啥辨,輸出通道數(shù)量N變?yōu)棣罭溉知。
再拿上述例子來說,使用了寬度乘數(shù)后玫荣,dw+pw的計(jì)算量為:捅厂,通常
設(shè)置為0.75。
(2) 分辨率乘數(shù)
這個(gè)超參通常隱式設(shè)置辙芍,應(yīng)用于輸入圖像,以降低分辨率契吉,記其為捐晶。
同樣地,拿上述例子來說英支,在使用了寬度乘數(shù)的基礎(chǔ)上干花,進(jìn)一步使用分辨率乘數(shù)后抡驼,dw+pw的計(jì)算量為:
最后來看下MobileNetv1的整體架構(gòu),總共28個(gè)卷積層(conv+bn+relu)馏锡,第1個(gè)和最后1個(gè)都是標(biāo)準(zhǔn)卷積層,中間13個(gè)是dw+pw卷積層(dw+pw算作1個(gè)卷積層)
MobileNetv2
回顧下MobileNetv1的騷操作——首先利用3×3的深度可分離卷積提取空間特征,然后利用1×1的逐點(diǎn)卷積來組合通道特征,同時(shí)映射到目標(biāo)通道數(shù)。這樣既減少了參數(shù)量达舒、計(jì)算量昨登,同時(shí)又提高了網(wǎng)絡(luò)運(yùn)算速度丰辣,還能得到一個(gè)接近于標(biāo)準(zhǔn)卷積的不錯(cuò)的結(jié)果,看起來十分美好胚想。
然而统屈,現(xiàn)實(shí)是殘酷的腕扶!
不少煉丹者在實(shí)際使用過程中, 發(fā)現(xiàn)深度卷積部分的卷積核被廢掉了——訓(xùn)練完之后發(fā)現(xiàn)深度卷積核有不少是空的代虾!
于是,作者趕緊再發(fā)一篇paper(心想:本來想坑你們一把,沒想到這么快就被識(shí)破了策泣,不好玩? ?M程А)茫陆,把鍋甩給了ReLU(ReLU內(nèi)心獨(dú)白:我太難了;酉隆)见秽,同時(shí)解取,MobileNetv2也誕生了(此刻腦補(bǔ)眾煉丹者們內(nèi)心:也不知道是不是新挖的坑...)蔓肯。
在MobileNetv2的paper中蔗包,作者舉出一個(gè)充分必要條件將鍋“合乎所以然”地甩給了ReLU——將低維流形映射到高維空間后使用ReLU變換再復(fù)原的例子:
如上圖,在2維空間有一組由m個(gè)點(diǎn)組成的螺旋線Xm數(shù)據(jù)(上圖input)误澳,利用隨機(jī)矩陣T映射到n維空間上并進(jìn)行ReLU運(yùn)算:
這時(shí)耻矮,再利用隨機(jī)矩陣T的逆矩陣,將y映射回2維空間中:
最后忆谓,根據(jù)映射到不同維度空間的情況裆装,對(duì)比下逆映射后的結(jié)果與原始輸入:
可以看到,當(dāng)映射到2倡缠、3維空間(n = 2, 3)時(shí)哨免,與原始輸入input相比有很大一部分的信息已經(jīng)丟失了采桃;而映射到15吏饿、30維空間(n = 15, 30)時(shí),還有許多信息能被保留下來。
這就是說果元,在低維度空間下與ReLU擁抱(做ReLU運(yùn)算),很容易造成信息丟失焦匈;而在高維度的情況下吕世,信息丟失則相對(duì)沒那么嚴(yán)重尔许。
這就解釋了為什么dw的卷積核有不少是空,因?yàn)閐w本身不會(huì)改變通道數(shù),如果輸入通道本來就少的話塞栅,經(jīng)過ReLU后信息丟失就會(huì)比較嚴(yán)重如蚜。
咦...說了那么久讨勤,怎么好像都沒有提到MobileNetv2呀?是不是跑題了蝶桶?矣?對(duì)耶规阀!
哦呵曹,不不不词疼,以上鋪墊的這個(gè)問題很重要,因?yàn)獒槍?duì)這個(gè)問題的解決手段正是MobileNetv2最重要的騷操作,好了,接下來進(jìn)入正題。
i). Expansion Layer
對(duì)于深度可分離卷積剿配,其本身沒有改變通道的能力,輸入通道多少輸出就是多少蝇更。有上述可知沪编,這樣的話,若輸入通道很少年扩,經(jīng)過深度可分離卷積后再接ReLU蚁廓,效果便不是很好,那怎么辦呢厨幻?
我們可以在深度可分離卷積前先擴(kuò)展通道數(shù)相嵌,也稱作Expansion Layer(擴(kuò)展層)。OK况脆,那具體如何擴(kuò)展呢饭宾?
既然在深度可分離卷積后我們使用了逐點(diǎn)卷積來將feature map的通道數(shù)映射到目標(biāo)通道數(shù),那么同樣地格了,我們也可以在深度可分離卷積之前先使用逐點(diǎn)卷積進(jìn)行升維(paper原文是升6倍)看铆。
ii). Linear Bottleneck
相對(duì)于上述方式,這是一個(gè)比較“暴力”的手段悄但,干脆把ReLU換掉肤频,使用線性激活層替代。不過算墨,我們可不能把所有的激活函數(shù)都換成線性的宵荒,這樣整張網(wǎng)絡(luò)就相當(dāng)于一個(gè)線性操作了(別忘記使用激活函數(shù)的一個(gè)原因之一就是引入非線性變換),那么應(yīng)該替換掉哪里的ReLU呢净嘀?
仔細(xì)看上圖报咳,第1個(gè)pw已將通道數(shù)擴(kuò)展,中間的pw不會(huì)改變通道數(shù)挖藏,那么這兩層后面使用ReLU通常較為“安全”暑刃,而最后1個(gè)pw通常是壓縮通道,如果后面接ReLU膜眠,效果可能就相對(duì)沒那么好了岩臣,因此可以將最后1個(gè)pw后的ReLU替換為線性激活函數(shù)溜嗜,這樣的結(jié)構(gòu)也稱作Linear Bottleneck。
iii). Inverted Residual
還記得ResNet那貨不架谎?哦炸宵,這肯定是廢話了,對(duì)于眾煉丹者來說谷扣,它也算得上是個(gè)全明星了土全。
殘差結(jié)構(gòu)(通常也稱作shortcut)能夠其起到特征復(fù)用和避免梯度消失的作用,于是在MobileNetv2里也引入這一騷操作会涎。
根據(jù)上圖裹匙,對(duì)比下可以發(fā)現(xiàn),兩者都采用了 1×1 -> 3 ×3 -> 1 × 1 的卷積模式以及shortcut末秃,不同點(diǎn)在于ResNet先使用pw降維概页,后使用pw升維,而MobileNetV2“反其道而行之”——先使用pw升維练慕,后使用pw降維绰沥。
這樣一來,MobileNetv2的block形狀看起來就剛好與ResNet的block相反贺待,因此作者給了它一個(gè)網(wǎng)紅名字——Inverted-Residual徽曲。
綜合以上,我們來看下MobileNetv2的block:
再來對(duì)比下v1和v2的block:
上圖左邊是v1的block麸塞,沒有shortcut并且最后的pw后面接了ReLU6秃臣;
右邊的是v2的block,加入了Expansion Layer(使用1×1 pw 升維)哪工,引入shortcut奥此,同時(shí)去掉了最后pw后的ReLU,改為線性激活函數(shù)雁比。注意稚虎,v2的block有2種,當(dāng)dw的步長(stride)為1時(shí)偎捎,使用了shortcut蠢终,形成殘差結(jié)構(gòu);而dw的步長(stride)為2時(shí)茴她,由于input與output的尺寸不同寻拂,因此沒有使用shortcut結(jié)構(gòu)。
最后,附上MobileNetv2的網(wǎng)絡(luò)結(jié)構(gòu):
MobileNetv3
本以為v2能成為網(wǎng)紅,沒想到一下子被v3干掉了...好吧名挥,我們先來回顧下v1和v2都做了哪些騷操作冯痢。
v1將標(biāo)準(zhǔn)卷積分解為dw+pw,同時(shí)使用2個(gè)超參進(jìn)一步構(gòu)建小模型和降低計(jì)算量谈跛;
v2在v1基礎(chǔ)上习寸,在dw前加入 Expansion Layer 進(jìn)行通道數(shù)的擴(kuò)展祭阀,將dw后的pw接的ReLU6替換為線性激活層垮卓,并且引入了shortcut垫桂,最終形成 inverted-residual(“倒殘差”) 這樣的結(jié)構(gòu)。
簡單精煉扒接,OK!那么v3在以上的基礎(chǔ)上又有哪些騷操作呢们衙?
i). 新的非線性激活函數(shù) —— h-swish
在介紹h-swish先來認(rèn)識(shí)一個(gè)家伙——swish钾怔,它一次是在谷歌大腦2017的論文?Searching for Activation functions 種亮相,其具備無上界有下界蒙挑、平滑以及非單調(diào)的特性宗侦,并且在深層模型上的效果優(yōu)于ReLU,并且作者通過實(shí)驗(yàn)進(jìn)行了驗(yàn)證忆蚀。
?(
)
這好東西v3當(dāng)然也嘗試使用過矾利,但是作者又認(rèn)為這家伙雖然提高了精度,但在嵌入式環(huán)境中馋袜,還是有不少計(jì)算成本男旗,原因是在移動(dòng)設(shè)備上計(jì)算sigmoid 函數(shù)成本不小,因此把sigmoid這部分替換掉欣鳖,改為ReLU6察皇,并且將這整個(gè)激活函數(shù)命名為h-swish:
為啥叫h-siwsh?h代表什么呢泽台?h其實(shí)是單詞hard的第一個(gè)字母什荣,h-swish的意思就是這個(gè)近似的函數(shù)可以逼近swish,讓swish硬(hard)起來(別想歪呀...)怀酷。那為啥使用ReLU6呢稻爬?作者認(rèn)為幾乎所有的軟硬件框架上都可以方便計(jì)算ReLU6,同時(shí)它能在特定模式下消除由于近似sigmoid的不同實(shí)現(xiàn)而帶來的潛在數(shù)值精度損失蜕依。
下圖展示了使用h-swish對(duì)于時(shí)間以及精度的影響,可以發(fā)現(xiàn)样眠,使用h-swish@16可以提高大約0.2%的精度竞滓,但是持劍延長了大約20%。因此吹缔,總的來說商佑,在更深的層中使用h-swish好處更大,于是建議通常在模型的后半部分使用厢塘。
ii). 基于Squeeze & Excitation(SE)的輕量級(jí)注意力結(jié)構(gòu)
在bottleneck中加入了SE結(jié)構(gòu)茶没,并且放在了dw之后肌幽。另外,由于SE部分的計(jì)算會(huì)消耗一定的時(shí)間抓半,因此在SE結(jié)構(gòu)的第1個(gè)FC層中喂急,壓縮了通道數(shù)(paper原文是變?yōu)樵瓉淼?/4),在最后的FC層再復(fù)原笛求,通過實(shí)驗(yàn)證明廊移,這樣在減少時(shí)耗的同時(shí)也提高了精度,這是屬于MobileNet的輕量級(jí)SE結(jié)構(gòu)探入。
關(guān)于這里的SE狡孔,有幾點(diǎn)提醒下:
(1). 這里的Pool指的是GAP(Global Average Pooling),即全局平均池化蜂嗽,經(jīng)過它的“沐浴”后苗膝,feature map的大小變?yōu)? x 1,通道數(shù)維持不變植旧;
(2). 第1個(gè)FC后的激活函數(shù)是ReLU辱揭,最后1個(gè)FC后的激活函數(shù)是h-sigmoid(注意不是 h-swish,相比 h-swish 少乘了1個(gè) x病附,即)
iii). 修改了部分v2的結(jié)構(gòu) —— 頭部卷積核的通道數(shù) 和 尾部結(jié)構(gòu)
(1). 修改頭部卷積核的通道數(shù)
v2中的頭部卷積核是 32 x 3 x 3问窃,v3中改成了 16 x 3 x 3,作者發(fā)現(xiàn)這樣在保證了精度的前提下還降低了3ms的時(shí)耗完沪。
(2). 修改尾部結(jié)構(gòu)
v2中泡躯,在最后的 Avg-Pooling 之前,使用了1個(gè)pw來升維丽焊,有利于結(jié)構(gòu)的預(yù)測(cè)较剃,但這同時(shí)引入了一定的計(jì)算量,于是作者在v3中作了修改:
先去掉這個(gè) pw 前的 bottleneck 中的 dw 和后面的 pw技健,然后將原本位于 Avg-Pooling 前的 pw 放置于 Avg-Pooling 后写穴,這樣就變?yōu)橄扔?Avg-Pooling 將feature map大小由 7 x 7 降到了 1 x 1(Avg-Pooling 的 kernel size 是 7 x 7),然后再使用 pw 升維度雌贱,減少了計(jì)算量和時(shí)耗啊送,同時(shí)發(fā)現(xiàn)精度并沒有得到損失,最終變?yōu)槿缦滤镜慕Y(jié)構(gòu):
相比于v2:
iv). 網(wǎng)絡(luò)結(jié)構(gòu)搜索 —— 資源受限的NAS(Platform-Aware NAS)與 NetAdapt
通過上述欣孤,可以發(fā)現(xiàn)v3相比于v2并沒有做太多創(chuàng)新馋没,其實(shí)重頭之戲在于這部分。但是CW對(duì)這部分沒有深入了解降传,參考了一些博文篷朵,在這里簡單介紹一下。
總體過程就是先用資源受限的NAS,在計(jì)算和參數(shù)量受限的前提下搜索網(wǎng)絡(luò)來優(yōu)化各個(gè)塊(block)声旺,稱之為模塊級(jí)搜索(Block-wise Search)笔链。然后再使用 NetAdapt 算法對(duì)各個(gè)模塊確定每一層的卷積核數(shù)量,稱之為層級(jí)搜索(Layer-wise Search)腮猖。
MobileNet為何這么快鉴扫?
看到這里,你有沒有認(rèn)真想過其實(shí)為何MobileNet會(huì)這么快呢澈缺?它是閃電俠嗎坪创,sorry跑題...
或許你會(huì)說因?yàn)樗鼘?biāo)準(zhǔn)卷積分解為dw+pw、使用了寬度乘數(shù)和分辨率乘數(shù)縮減計(jì)算量姐赡、使用了h-swish...blablabla等等莱预,嗯,也沒錯(cuò)雏吭,但是這里可以嘗試從另一個(gè)視角去理解锁施。
以v1為例陪踩,來看看計(jì)算資源分布情況:
可以看到杖们,大部分計(jì)算都分布在了pw也就是1 x 1卷積上,這么看來肩狂,快就快在1 × 1卷積了摘完。咦,難道1 x 1卷積才是閃電俠傻谁?(⊙o⊙)…又跑題孝治,sorry...
我們知道,卷積實(shí)質(zhì)是矩陣之間的加乘運(yùn)算审磁,而在計(jì)算機(jī)進(jìn)行操作時(shí)谈飒,需要將其先存入內(nèi)存再操作,按照 “行先序”:
再來一張圖态蒂,你會(huì)發(fā)現(xiàn)這是有點(diǎn)“辛苦”的:
于是,通常都會(huì)使用到一個(gè)叫im2col的騷操作钾恢,其實(shí)質(zhì)是通過犧牲空間的手段(約擴(kuò)增K×K倍)手素,將特征圖轉(zhuǎn)換成更大的矩陣來進(jìn)行卷積計(jì)算,具體為:
把在特征圖中每一次循環(huán)所需的數(shù)據(jù)排列成列向量瘩蚪,然后逐一堆疊起來形成矩陣(按通道順序在列方向上拼接)泉懦,比如輸入特征圖維度為 Ci × Wi × Hi ,卷積核尺寸為 K × K 疹瘦,輸出維度為Co×Wo×Ho崩哩,那么卷積核轉(zhuǎn)換為 Co x ( K x K) 的矩陣,同時(shí)輸入特征圖轉(zhuǎn)換為(K x K) × (Ci x Wo x Ho)的矩陣言沐,如下所示琢锋。
然后調(diào)用諸如 GEMM(矩陣乘矩陣)這樣的庫加速兩矩陣的相乘計(jì)算辕漂。由于這過程按照計(jì)算需求排布了數(shù)據(jù)順序,使得計(jì)算機(jī)每次計(jì)算過程中能夠依次訪問到特征圖中所需的數(shù)據(jù)吴超,因此極大地提高了運(yùn)算速度钉嘹。
OK,現(xiàn)在回來看看MobileNet的寶貝1×1卷積鲸阻,根據(jù)上述跋涣,1×1卷積的“行先序”儲(chǔ)存結(jié)構(gòu)以及使用im2col后的結(jié)構(gòu)分別如下圖所示:
咦,這是...一樣噠鸟悴!也就是說陈辱,1x1卷積根本不需要im2col的過程,“即插即用”细诸!大大節(jié)省了數(shù)據(jù)重排列的時(shí)間和空間沛贪,因此在底層計(jì)算中相對(duì)更快。
#最后
若你認(rèn)真看完了本文震贵,那么CW真心感謝你利赋!與此同時(shí),如果你覺得本文給予了你幫助或者讓你有了新的認(rèn)知猩系,那我就更開心了媚送,CW期待與大家共同成長!
參考:
https://cloud.tencent.com/developer/article/1467101
https://blog.csdn.net/u010712012/article/details/95922901
https://blog.csdn.net/qq_38807688/article/details/84590717
https://blog.csdn.net/Chunfengyanyulove/article/details/91358187