出品 | 智東西公開課
講師 | 童志軍 閱面科技合伙人&CTO
提醒 | 點(diǎn)擊上方藍(lán)字關(guān)注我們,并回復(fù)關(guān)鍵詞 嵌入式04,即可獲取課件。
導(dǎo)讀:
4月17日,閱面科技合伙人&CTO童志軍在智東西公開課進(jìn)行了嵌入式AI合輯第四講的直播講解,主題為《面向嵌入式設(shè)備的輕量級(jí)神經(jīng)網(wǎng)絡(luò)模型設(shè)計(jì)》。
在本次講解中,童志軍老師從神經(jīng)網(wǎng)絡(luò)模型在嵌入式設(shè)備運(yùn)行的挑戰(zhàn)、神經(jīng)網(wǎng)絡(luò)模型從“特征驅(qū)動(dòng)”、“數(shù)據(jù)驅(qū)動(dòng)”、“精度優(yōu)先”到“速度優(yōu)先”等不同階段的發(fā)展歷程,并通過實(shí)際案例解讀如何在嵌入式設(shè)備上實(shí)現(xiàn)神經(jīng)網(wǎng)絡(luò)模型的高效部署和運(yùn)行。
本文為此次課程主講環(huán)節(jié)的圖文整理:
正文:
大家好,我是閱面科技合伙人&CTO童志軍,很高興能在智東西公開課和大家一起分享今天的課題。我今天分享的主題為《面向嵌入式設(shè)備的輕量級(jí)神經(jīng)網(wǎng)絡(luò)模型設(shè)計(jì)》,主要分為以下4個(gè)部分:
1、神經(jīng)網(wǎng)絡(luò)模型在嵌入式設(shè)備運(yùn)行的挑戰(zhàn)
2、從“特征驅(qū)動(dòng)”到“數(shù)據(jù)驅(qū)動(dòng)”的大型神經(jīng)網(wǎng)絡(luò)模型設(shè)計(jì)
3、從“精度優(yōu)先”到“速度優(yōu)先”的輕量級(jí)神經(jīng)網(wǎng)絡(luò)模型設(shè)計(jì)
4、在嵌入式設(shè)備實(shí)現(xiàn)神經(jīng)網(wǎng)絡(luò)模型的高效部署與運(yùn)行
神經(jīng)網(wǎng)絡(luò)模型在嵌入式設(shè)備運(yùn)行的挑戰(zhàn)
目前,在所看見的嵌入式設(shè)備上,很大一部分會(huì)有AI的算法的身影。在我們身邊也有很多應(yīng)用,比如刷臉解鎖手機(jī)、刷臉支付、家用的攝像頭,或馬路上隨處可見的公共安防攝像頭等。
嵌入式設(shè)備在我們身邊無孔不入,這些設(shè)備分為兩種,一種是只做視頻的抓取沒有計(jì)算,只是把視頻傳到后臺(tái)服務(wù)器,然后做分析;另一種是設(shè)備上會(huì)帶有AI計(jì)算能力,一些算法會(huì)在前端設(shè)備上去計(jì)算,然后把計(jì)算得到的結(jié)構(gòu)化數(shù)據(jù)再傳到后端服務(wù)器去做進(jìn)一步分析。

上圖左邊列舉了一些主流的神經(jīng)網(wǎng)絡(luò)模型,包括計(jì)算量及參數(shù)量,相應(yīng)在Imagenet公開數(shù)據(jù)集上Top-1的精度。上圖橫坐標(biāo)代表的是計(jì)算的浮點(diǎn)計(jì)算量,然后縱坐標(biāo)是精度??梢钥吹缴窠?jīng)網(wǎng)絡(luò)模型的精度與模型的計(jì)算量成正比,隨著模型計(jì)算量越來越大,精度也越來越高。
但也可以看到,網(wǎng)絡(luò)模型的精度與模型的參數(shù)量是沒有完全呈正比。比如VGG網(wǎng)絡(luò),它的參數(shù)量很大,但是精度不是特別高。在嵌式設(shè)備上運(yùn)行神經(jīng)網(wǎng)絡(luò),首先要求模型的精度要非常高,只有模型的精度達(dá)到一定的準(zhǔn)確率才能滿足人們實(shí)際使用的需求。由于嵌入式設(shè)備的功耗、存儲(chǔ)及計(jì)算資源都非常有限,如何在有限的計(jì)算資源下把高精度的模型運(yùn)行為實(shí)時(shí)動(dòng)態(tài)的效果是非常重要的,這里會(huì)涉及到算法、算力及數(shù)據(jù)幾個(gè)層面的優(yōu)化,今天主要與大家探討在算法層面,更確切的是在網(wǎng)絡(luò)設(shè)計(jì)的層面如何解決?
從“特征驅(qū)動(dòng)”到“數(shù)據(jù)驅(qū)動(dòng)”的大型神經(jīng)網(wǎng)絡(luò)模型設(shè)計(jì)
首先回顧下大型的神經(jīng)網(wǎng)絡(luò)模型的發(fā)展脈絡(luò),其實(shí)卷積神經(jīng)網(wǎng)絡(luò)很早就出現(xiàn), LeNet-5很早在美國(guó)郵政的數(shù)字識(shí)別上已經(jīng)得到很好的應(yīng)用。但后來并沒有得到更多的推廣,沉默了10年,10年內(nèi)主流的一些視覺分析的方法還是手工特征。
對(duì)于手工特征,大家比較熟悉的是SIFT特征,它是在x方向跟y方向去提取梯度圖,然后把每一個(gè)像素的梯度圖按照一定的角度區(qū)間各自去做梯度方向的投影,最終得到128位的描述子。如果把這個(gè)問題換一個(gè)角度來思考,可以發(fā)現(xiàn) SIFT特征的生成過程,可以等效是一個(gè)卷積層和一個(gè)pooling層。

上圖可以看到它的8個(gè)方向的梯度,代表的是輸出Channel為8,kernel大小為1*1的卷積,輸入是x方向跟y方向的梯度流。對(duì)于 x方向跟y方向的圖,等效成一個(gè)2*8*1*1的卷積操作,后面再接了一個(gè)8*8*4*4的Pooling層,最終得到一個(gè)兩層的神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)。
隨著特征描述的發(fā)展,逐漸從底層的特征設(shè)計(jì)發(fā)展到中層特征設(shè)計(jì)。中層特征設(shè)計(jì)比較典型的是Fisher Vector,它在圖像搜索的方面應(yīng)用的非常廣泛。Fisher Vector特征首先對(duì)圖像做特征提取,然后基于GMM模型對(duì)特征做進(jìn)一步的編碼,編碼得到的特征,再通過空間卷積得到在不同的尺度空間上的特征描述。用現(xiàn)在的神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)的方式去看,可以等效為一個(gè)SIFT特征提取過程,加一個(gè)編碼層和一個(gè)Pooling層,即為一個(gè)四層的神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)。4層的網(wǎng)神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)比兩層的神經(jīng)網(wǎng)絡(luò)精度會(huì)更高,特征也更抽象,表達(dá)能力更強(qiáng)。
到2010年時(shí),李飛飛教授帶領(lǐng)的一幫學(xué)者整理了一個(gè)非常大型的數(shù)據(jù)集-Imagenet,這個(gè)數(shù)據(jù)集有1000類,大概120萬(wàn)張圖片,這個(gè)數(shù)據(jù)集的出現(xiàn)是神經(jīng)網(wǎng)絡(luò)得到飛速發(fā)展的基石,掀起了整個(gè)AI界的軍備競(jìng)賽。
時(shí)間到了2012年,ImageNet比賽冠軍提出來一個(gè)新的網(wǎng)絡(luò)AlexNet。它由5個(gè)卷積層,3個(gè)全連接層。另外由于當(dāng)時(shí)GPU顯存的限制,把網(wǎng)絡(luò)的卷積分成分組的形式,使得網(wǎng)絡(luò)能夠在 GPU有限的情況下運(yùn)行起來,里面還有drop out的技巧等。AlexNet開創(chuàng)了神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)的一個(gè)新河,在此之后,工業(yè)界的人開始相信深度學(xué)習(xí)是有效的,可以產(chǎn)生一些有價(jià)值的東西,而不僅是學(xué)術(shù)界的一個(gè)玩具。

2014年,出現(xiàn)了VGG和GoogleNet兩種不同的網(wǎng)絡(luò)結(jié)構(gòu),兩個(gè)網(wǎng)絡(luò)其實(shí)都是在不同層面對(duì)網(wǎng)絡(luò)去建模。在早期,AlexNet出現(xiàn)之后,在調(diào)網(wǎng)絡(luò)的時(shí)候發(fā)現(xiàn)一種很奇怪的現(xiàn)象,當(dāng)把層數(shù)往上堆時(shí),很容易出現(xiàn)梯度彌散的效應(yīng)。如何把網(wǎng)絡(luò)做深,在當(dāng)時(shí)一直沒有得到很好的解決。
VGG跟GoogleNet做的網(wǎng)絡(luò)都接近20層左右,這是一個(gè)突破,這里也是使用了一些技巧,比如 GoogleNet是在層中間插入 loss的監(jiān)督, 然后在block的設(shè)計(jì)上引入了一些技巧,通過這種多尺度的卷積核,提取圖像上的多尺度的信息。其實(shí)尺度是一個(gè)非常重要的因素。另外逐層的 finetuning,在VGG用的比較多,還引入了連續(xù)兩個(gè)3×3的卷積核去模擬5×5的感受野,它使得網(wǎng)絡(luò)可以做得更深,精度做得更高。
2015年,微軟亞洲研究員何凱明設(shè)計(jì)的殘差網(wǎng)絡(luò),把神經(jīng)網(wǎng)絡(luò)從20層提升到幾百層??梢钥吹骄W(wǎng)絡(luò)層數(shù)越來越深,而且網(wǎng)絡(luò)的寬度也越來越寬,當(dāng)然最終的精度也是非常高。

上圖為ImageNet分類Top5錯(cuò)誤率圖,可以看到網(wǎng)絡(luò)的精度隨著層數(shù)逐漸增加越來越高,網(wǎng)絡(luò)結(jié)構(gòu)也在不斷創(chuàng)新。
從“精度優(yōu)先”到“速度優(yōu)先”的輕量級(jí)神經(jīng)網(wǎng)絡(luò)模型設(shè)計(jì)
自2015-2016年之后出現(xiàn)網(wǎng)絡(luò)模型有往端上發(fā)展的趨勢(shì),如何把神經(jīng)網(wǎng)絡(luò)模型在終端上跑得更快,是演變的一個(gè)趨勢(shì),也就是模型的設(shè)計(jì)從精度優(yōu)先到后來的速度優(yōu)先。

我們可以簡(jiǎn)單分析下神經(jīng)網(wǎng)絡(luò)模型的計(jì)算量,可以看到一般的神經(jīng)網(wǎng)絡(luò)模型,大部分都是由卷積層組成,卷積層在里面的計(jì)算量占到了80%以上,卷積的計(jì)算示意圖如上圖所示,計(jì)算復(fù)雜度為N*M*H*W*K*K。
輕量級(jí)的神經(jīng)網(wǎng)絡(luò)模型所做的工作,就是圍繞著計(jì)算復(fù)雜度,把里面的一些參數(shù)盡量的減小,使得計(jì)算量能夠降低。計(jì)算量在嵌入式設(shè)備上體現(xiàn)最明顯的是它的速度。如何在優(yōu)化計(jì)算復(fù)雜度的同時(shí)保證模型的高精度,就是下面一些主流的神經(jīng)網(wǎng)絡(luò)模型設(shè)計(jì)所做的工作。
最開始比較有代表性的一個(gè)網(wǎng)絡(luò)是SqueezeNet網(wǎng)絡(luò),它有兩個(gè)特點(diǎn),先用1×1的卷積核做通道壓縮,然后把1×1與3×3的卷積核并排,使得卷積核可以更小。也就是通過減小通道數(shù)以及卷積核大小降低模型的計(jì)算量,使得模型可以推理的更快。
第二個(gè)是MobileNet網(wǎng)絡(luò)和ShuffleNet網(wǎng)絡(luò),MobileNet網(wǎng)絡(luò)用到一個(gè)比較重要的點(diǎn)是Depthwise卷積,也是把原來稠密的卷積N*M的計(jì)算量,直接優(yōu)化為N的計(jì)算量。ShuffleNet網(wǎng)絡(luò)借鑒了 MobileNet網(wǎng)絡(luò)一些點(diǎn),比如Depthwise卷積,當(dāng)應(yīng)用Depthwise卷積后,發(fā)現(xiàn)整個(gè)神經(jīng)網(wǎng)絡(luò)計(jì)算量更多是在1×1的卷積上,這時(shí)就可以把1×1卷積去做一個(gè)通道Shuffle分組,分組之后做通道卷積,使得它能夠在3×3上再進(jìn)一步的融合,可以看到大家更多的是把卷積由原來的稠密卷積變成通道的卷積。
最近的神經(jīng)網(wǎng)絡(luò)是模型搜索NAS,這方面有很多的輕量級(jí)的網(wǎng)絡(luò)結(jié)構(gòu),但是沒有把它應(yīng)用到嵌入設(shè)備上,為什么?因?yàn)?NAS搜索出來的網(wǎng)絡(luò)規(guī)律性比較差,對(duì)嵌入式設(shè)備不是很友好。實(shí)際應(yīng)用更多的還是停留在MobileNet網(wǎng)絡(luò)這種比較直線型的網(wǎng)絡(luò)上去優(yōu)化。
后來有一個(gè)EfficientNet網(wǎng)絡(luò)結(jié)構(gòu),它的想法比較綜合,把網(wǎng)絡(luò)計(jì)算量的幾個(gè)因素同時(shí)去做一個(gè)聯(lián)合搜索優(yōu)化,比如網(wǎng)絡(luò)的層數(shù),或者圖像的feature map的長(zhǎng)寬,以及計(jì)算復(fù)雜度中提到的N、M、K,去做一個(gè)統(tǒng)一的建模,通過增強(qiáng)學(xué)習(xí)去搜索最優(yōu)解。另外,網(wǎng)絡(luò)結(jié)構(gòu)也做一些重復(fù)的堆疊,相對(duì)非常有規(guī)律,對(duì)整個(gè)嵌入式設(shè)備還是非常友好的。
在嵌入式設(shè)備實(shí)現(xiàn)神經(jīng)網(wǎng)絡(luò)模型的高效部署與運(yùn)行

首先看下整體的加速框架,這里面大概包含了閱面所做的一些工作,左邊是訓(xùn)練端,主要做了模型的通道剪枝、模型蒸餾和量化訓(xùn)練的工作,右邊是在嵌入式設(shè)備上做模型的轉(zhuǎn)換,以及卷積運(yùn)算算子的優(yōu)化,使得我們的模型可以在一些硬件層面快速的跑起來。
第一個(gè)是通道剪枝,剪枝包括稀疏化等,但對(duì)嵌入式設(shè)備不是很友好,因?yàn)橄∈杌糁Φ玫降哪P蜎]有規(guī)律,讓內(nèi)存的取值變得隨機(jī),使得設(shè)備速度跑不起來。后來通道剪枝可以得到規(guī)則模型,使得剪完之后的模型能夠復(fù)用以前的計(jì)算引擎,這方面更多的是基于一些規(guī)則,比如選取響應(yīng)最大卷積核或選一些方差比較大的卷積核,對(duì)卷積核建模,通道壓縮率也可以通過強(qiáng)化學(xué)習(xí)的方法去反復(fù)搜索,最終得到最優(yōu)的結(jié)果。
通道剪枝主要針對(duì)MobileNetV2和 EfficientNet這類網(wǎng)絡(luò),可以看到當(dāng)模型從原來的200-300M的計(jì)算規(guī)模,到后來100M以下,其精度下降在一個(gè)可以接受的范圍內(nèi),這樣的模型可以在檢測(cè)或者是識(shí)別任務(wù)上得到很好的使用。
第二是模型蒸餾,最早主要是體現(xiàn)在loss設(shè)計(jì)上,比如 Student模型去學(xué)習(xí)Teacher模型的樣本分布,最終來提高Student模型的精度。以Margin為例,Margin在細(xì)粒度分類上用的比較多。通過Student模型去學(xué)習(xí)Teacher模型的Margin分布,使得Student模型的精度得到非常大的提升。

上圖為訓(xùn)練人臉識(shí)別網(wǎng)絡(luò),第一行是 Teacher模型的精度,第二行是Student模型的一個(gè)baseline ,第三行是用模型蒸餾的方法產(chǎn)生的Student模型的記錄,可以看到訓(xùn)練出的 Student模型的精度,是介于Teacher模型跟Student模型之間,而且比較接近Teacher模型的精度,相對(duì)于baseline有非常大的提升。
第三塊是量化訓(xùn)練,為什么要做量化訓(xùn)練?模型量化會(huì)帶來很多好處,最常見的比如可以把模型的存儲(chǔ)量,從原來的FP32減到INT16或INT8,直接減掉一半或1/4。另一點(diǎn)是做量化之后,使得模型做并行加速,比如同樣一個(gè)指令周期,原來可以操作1個(gè)浮點(diǎn)數(shù),現(xiàn)在可以同時(shí)操作2個(gè)INT16或4個(gè)INT8,使得數(shù)據(jù)的吞吐量提升,這也是一種提速。
它的流程如下:首先會(huì)收集前向的數(shù)據(jù)集,然后對(duì)網(wǎng)絡(luò)做統(tǒng)計(jì),統(tǒng)計(jì)分為兩部分,一個(gè)是模型的 weight做最大最小或者 kr散度分布上的統(tǒng)計(jì),另一個(gè)是對(duì)模型的輸入輸出做統(tǒng)計(jì),從而可以選取到最優(yōu)的一個(gè)標(biāo)準(zhǔn)去對(duì)模型做量化。如果只做INT16的量化,模型的精度是可以完全保持住的。但當(dāng)做更低精度,比如INT8或INT4,模型精度會(huì)有一些損失,這時(shí)還需要做一些finetune,使得模型精度可以回到跟原來浮點(diǎn)模型的精度。

上圖是在人臉識(shí)別模型上所做的工作,比如FP32在1/10萬(wàn)是達(dá)到97.94%的識(shí)別率,直接量化INT8,精度為 85.17,通過finetune使得最終的模型可能只降低了1~2個(gè)點(diǎn)。量化是一個(gè)非常有效的降低模型計(jì)算量,同時(shí)適合嵌入式設(shè)備,不管是功耗或存儲(chǔ)的占用都非常友好。
第四點(diǎn)是當(dāng)?shù)玫揭粋€(gè)最優(yōu)的模型結(jié)構(gòu)之后,最終部署到嵌入式設(shè)備上,就涉及到推理引擎。推薦引擎主要的計(jì)算在卷積運(yùn)算, 我們采用的是直接基于原始的卷積方式做優(yōu)化。這涉及到行主序的內(nèi)存重排、矩陣分塊、內(nèi)存對(duì)齊、內(nèi)存復(fù)用、緩存預(yù)讀取、SIMD并行加速、循環(huán)展開、多線程等。

我們?cè)赗K3288上做的優(yōu)化,對(duì)比的是騰訊開源的NCNN推理引擎??梢钥吹皆谕瑯拥妮斎胂?,我們的速度提升大概有40%~50%之間,這個(gè)引擎還在持續(xù)的優(yōu)化,算子的計(jì)算優(yōu)化也是非常重要的一環(huán)。

最后總結(jié)下,在嵌入式模型部署所做的工作,首先會(huì)得到檢測(cè)或識(shí)別的業(yè)務(wù)模型,根據(jù)具體客戶的需求訓(xùn)練浮點(diǎn)模型,之后做模型蒸餾的loss訓(xùn)練,把計(jì)算量做進(jìn)一步的精簡(jiǎn)。精簡(jiǎn)完之后,對(duì)一些稀疏的通道,做進(jìn)一步的剪枝,并且把模型finetune,得到一個(gè)最緊湊的深度學(xué)習(xí)模型。之后根據(jù)前面的一些積累,我們更多是基于Caffe的框架,在這個(gè)基礎(chǔ)之上對(duì)模型做進(jìn)一步的量化,量化可能會(huì)根據(jù)具體硬件不同會(huì)有所不同。最終得到一個(gè)最優(yōu)化的量化模型之后,把算子計(jì)算庫(kù)打包一起,最終形成一個(gè)運(yùn)行程序,部署到實(shí)際的設(shè)備上。上面就是完整的模型部署的流程。
以上就是我今天的分享內(nèi)容,謝謝大家。