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

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

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

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

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

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

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

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

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

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

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