在使用神經(jīng)網(wǎng)絡(luò)算法解決問題的時(shí)候,算法效率問題是必要的考量的。特別是在資源與算力不足的嵌入式端,更是頭等大問題。除了依托TensorFlow、Keras等開源框架,根據(jù)其前向傳播的原理寫成C++程序,還有必要的編譯優(yōu)化外,模型權(quán)重參數(shù)的清洗和算法計(jì)算的向量化都是比較有效的手段。
1)模型權(quán)重參數(shù)清洗
權(quán)重參數(shù)清洗對神經(jīng)網(wǎng)絡(luò)算法的效率影響相當(dāng)大,沒有進(jìn)行清洗的權(quán)重參數(shù)訪問與操作非常低效,與清洗后的權(quán)重參數(shù)相比往往能效率相差6-8倍。這差距在算力不足的嵌入式端非常明顯,往往決定一個(gè)算法是否能落地。具體的方法就是先讀取原模型進(jìn)行重組,讓參數(shù)變得緊湊且能在計(jì)算時(shí)連續(xù)訪問計(jì)算,最后獲得重組后的模型與對應(yīng)的重組模型的計(jì)算方法。這個(gè)步驟需要一定的優(yōu)化實(shí)踐經(jīng)驗(yàn)以達(dá)到滿意的效果,對模型讀取效率與運(yùn)算效率都會有顯著的提高。
2)算法計(jì)算向量化
對于算法的向量化的做法就是讓算法的計(jì)算能夠使用向量乘加等運(yùn)算,而特別是在使用神經(jīng)網(wǎng)絡(luò)算法情況下,大量的計(jì)算沒有前后相關(guān)性且執(zhí)行相類似的步驟,所以向量化計(jì)算會對算法有明顯的提升,一般能把算法效率提升三倍左右。
使用NEON指令集的SIMD指令取代ARM通用的SISD指令,是一個(gè)常用的算法向量化方法。在基于ARMV7-A和ARMV7-R的體系架構(gòu)上基本采用了NEON技術(shù),ARMV8也支持并與ARMV7兼容。
以IMX6ULL芯片為例,可以通過查閱官方的參考手冊查看其NEON相關(guān)信息:
下面舉例說明普通的編程寫法與NEON instrinsics編程、NEON assembly編程區(qū)別。以下為普通的編程寫法:
以下為轉(zhuǎn)化為NEON instrinsics的編程:
以為轉(zhuǎn)為NEON assembly的編程:
一般NEON instrinsics已經(jīng)能做到三倍的提速效果,而NEON assembly效果會更好一些。但是程序向量化需要特殊訪存規(guī)則,如果不符合則會對導(dǎo)致提速效果大打折扣。
訪存特征詳細(xì)分類如表所示:
其中,無冗余飽和順序模式是理想的訪問模式,能夠發(fā)揮算法計(jì)算向量化的效果。但是我們神經(jīng)網(wǎng)絡(luò)算法的最基本的卷積、全連接等計(jì)算卻是冗余飽和非順序模式的計(jì)算,這要如何解決呢?
查閱相關(guān)論文、期刊對這程序向量化非規(guī)則訪存的研究,可以發(fā)現(xiàn)程序向量化有以下步驟:
如上圖所示,需要對卷積、全連接等冗余飽和非順序模式計(jì)算通過向量混洗為無冗余飽和順序的模式,以達(dá)到優(yōu)化的效果。
7.人臉識別效果展示
基于PC的人臉識別展示demo如下視頻所示: