最近在學習張紹文老師的《Android開發高手課》課程,學習到了不少的乾貨,特別是在處理問題的策略和知識的廣度方面給了我不少的啓發,對將來的學習也提供了方向。git
目前,技術的發展有兩個趨勢。一個趨勢是,隨着5G網絡的發展,物聯網使「萬物互聯」成爲可能。物聯網時代,也是雲計算和邊緣計算並存的世界,且邊緣計算將扮演重要的角色。邊緣計算是與雲計算相反的計算範式,指的是在網絡邊緣節點(終端設備)進行數據處理和分析。邊緣計算之因此重要,緣由在於:首先,在物聯網時代,將有數十億的終端設備持續採集數據,帶來的計算量將是雲計算所不能承受的;其次,終端設備的計算能力不斷提升,並非全部的計算都須要在雲端完成;再有,將數據傳回雲端計算再將結果返回終端的模式,不可避免存在時延,不只影響用戶體驗,有些場景也是不可接受的;最後,隨着用戶對數據安全和隱私的重視,也會要求在終端進行數據加工和計算。github
另外一個趨勢是,人工智能技術的迅速發展。最近幾年,以深度學習爲表明的人工智能技術取得了突破性的進展,不只在社會上引發了人們的興趣和關注,同時也正在重塑商業的格局。人工智能技術的重大價值在於,藉助智能算法和技術,將以前必須人工才能完成的工做進行機器化,用機器的規模化解放人工,突破人力生產要素的瓶頸,從而大幅提升生產效率。在商業社會,「規模化」技術將釋放巨大的能量、創造巨大的價值,甚至重塑商業的競爭,拓展整個商業的外部邊界。算法
邊緣計算既然有計算能力,在不少應用場景中就會產生智能計算的需求,二者結合在一塊兒,就造成了邊緣智能計算。安全
目前,移動端機器學習的應用技術主要集中在圖像處理、天然語言處理和語音處理。在具體的應用上,包括但不限於視頻圖像的物體檢測、語言翻譯、語音助手、美顏等,在自動駕駛、教育、醫療、智能家居和物聯網等方面有巨大的應用需求。目前已經商用的深度學習技術主要有以下一些:性能優化
框架 | 研發公司 | 支持平臺 |
---|---|---|
TF_lite | ARM | |
Caffe2 | ARM | |
TF_lite | Xiaomi | ARM、DSP、GPU |
paddle-mobile | Baidu | ARM、GPU |
FeatherCNN | Tencent | ARM |
NCNN | Tencent | ARM |
由於深度學習算法具備不少特定的算法算子,爲了提升移動端開發和模型部署的效率,各大廠都開發了移動端深度學習的計算框架,例如谷歌的TensorFlow Lite、Facebook的Caffe2等,Android開發的同窗仍是挺有必要去了解這些計算框架的。爲了培養興趣這方面的興趣並得到感性的認識,你能夠挑選一個比較成熟的大廠框架,例如 TensorFlow Lite,在手機開發一個物體檢測的Demo練練手。服務器
在實際項目中,TensorFlow Lite和Caffe2等一般運行比較慢。在網上能夠很容易找到各個計算框架的對比圖。若是要真正入門的話,在這裏我推薦你們使用NCNN框架。NCNN是騰訊開源的計算框架,優勢比較明顯,代碼結構清晰、文件不大,並且運行效率高。強烈推薦有興趣的Android開發同窗把源碼閱讀幾遍,不只有助於理解深度學習經常使用的算法,也有助於理解移動端機器學習的計算框架。網絡
閱讀NCNN源碼抓住三個最基礎的數據結構,Mat、Layer和Net。其中,Mat用於存儲矩陣的值,神經網絡中的每一個輸入、輸出以及權重,都是用Mat來存儲的。Layer實際上表示操做,因此每一個Layer都必須有前向操做函數(forward函數),全部算子,例如,卷積操做(convolution)、LSTM操做等都是從Layer派生出來的。Net用來表示整個網絡,將全部數據節點和操做結合起來。數據結構
在閱讀NCNN源碼的同時,建議你們也能夠看些關於卷積神經網絡算法的入門資料,會有助於理解。框架
在實際項目中,若是某個路徑成爲時間開銷的瓶頸,一般能夠將該節點用NDK去實現。但在一般狀況下,移動端機器學習的計算框架已經在NDK中進行實現的,這時改進的方向是採用ARM NEON指令彙編進行優化。機器學習
NEON是適用於ARMCortex-A系列處理器的一種128Bit SIMD(Single Instruction%2CMultipleData,單指令、多數據)擴展結構。ARMNEON指令之全部能達到性能優化的目的,關鍵就在於單指令多數據。以下圖所示:
NEON的兩個操做數各有128Bit,各包含4個32Bit的同類型的寄存器,經過以下所示的一條指令,就能夠實現4個32Bit數據的並行計算,從而達到性能優化的效果。
VADDQ.S32 Q0,Q1,Q2
咱們曾經用NDK的方式實現了深度學習算法中的PixelShuffle操做,後來採用ARMNEON%2B彙編優化的方式,計算的效率提高40倍,效果仍是很顯著的。
若是還想進一步提升計算的性能,能夠採用Int 8量化的方法。在深度學習裏面,大多數運算都是基於Float 32類型進行的,Float 32是32Bit,128Bit的寄存器一次能夠存儲4個Float 32類型數據;相比之下,Int 8類型的數據能夠存儲16個。結合前面提到的單指令多數據,若是採用Int 8類型的數據,單條指令能夠同時執行16個Int 8數據的運算,從而大大提升了並行性。
可是,將Float 32類型的數值量化到Int 8表達,不可避免會影響到數據的精度,並且量化的過程也是須要時間開銷的,這些都是須要注意的地方。關於量化的方法,感興趣的同窗能夠閱讀這篇論文。
若是設備具備GPU,還能夠應用OpenCL進行GPU加速,例如小米開源的移動端機器學習框架MACE。
對於剛開始學習算法的同窗,我一直主張不要把算法想象得太複雜,也不要想得太數學化,不然容易讓人望而生畏。數學是思惟邏輯的表達,咱們但願用數學幫助咱們理解算法。咱們要可以達到對算法的直觀理解,從直觀上知道和理解爲何這個算法會有這樣的效果,只有這樣纔算是真正掌握了算法。相反,對於一個算法,若是你只記住了數學推導,沒造成直觀的理解,是不可以靈活應用的。
深度學習的圖像處理具備很廣的應用,並且比較直觀和有趣,建議你能夠從深度學習的圖像處理入手。深度學習的圖像處理,最基本的知識是卷積神經網絡,因此你能夠先學習卷積神經網絡。網上有不少關於卷積神經網絡的介紹,這裏就不贅述了。
理解卷積神經網絡關鍵是理解卷積神經網絡的學習機制,理解爲何可以學習。想要理解這一點,首先須要明確兩個關鍵點「前向傳播」和「反向傳播」。整個神經網絡在結構和激活函數肯定以後,所謂「訓練」或者「學習」的過程,其實就是在不斷地調整神經網絡的每一個權重,讓整個網絡的計算結果趨近於指望值(目標值)。前向傳播是從輸入端開始計算,目標是獲得網絡的輸出結果,再將輸出結果和目標值相比較,獲得結果偏差。以後將結果偏差沿着網絡結構反向傳播拆解到每一個節點,獲得每一個節點的偏差,而後根據每一個節點的偏差調整該節點的權重。「前向傳播」的目的是獲得輸出結果,「反向傳播」的目的是經過反向傳播偏差來調整權重。經過二者互相交替迭代,但願達到輸出結果和目標值一致。
理解卷積神經網絡以後,咱們能夠動手實現手寫字體識別的示例。掌握以後,能夠接着學習深度學習裏的物體檢測算法,例如YOLO、FasterR-CNN等,最後能夠動手用TensorFlow都寫一遍,跑跑訓練數據、調調參數,邊動手邊理解。在學習過程當中,要特別留意算法模型的設計思想和解決思路。
效果優化指提高算法模型的準確率等指標,一般的方式有如下幾種:
由於算法模型是從訓練數據中學習的,模型沒法學習到訓練數據以外的模式。因此,在選擇訓練數據時要特別當心,必須使得訓練數據包含實際場景中會出現的模式。精心挑選或標註訓練數據,會有效提高模型的效果。訓練數據的標註對效果很是重要,以致於有創業公司專門從事數據標註,還得到了很多融資。
根據問題採用更好的算法模型,採用深度學習模型而不是傳統的機器學習模型,採用具備更高特徵表達能力的模型等,例如使用殘差網絡或DenseNet提升網絡的特徵表達能力。
優化模型訓練方式包括採用哪一種損失函數、是否使用正則項、是否使用Dropout結構、使用哪一種梯度降低算法等。
雖然咱們在框架側作了大量的工做來提升計算性能,可是若是在算法側可以減小計算量,那麼總體的計算實時性也會提升。從模型角度,減小計算量的思路有兩種,一種是設計輕量型網絡模型,一種是對模型進行壓縮。輕量型網絡設計學術界和工業界都設計了輕量型卷積神經網絡,在保證模型精度的前提下,大幅減小模型的計算量,從而減小模型的計算開銷。這種思路的典型表明是谷歌提出的MobileNet,從名字上也能夠看出設計的目標是移動端使用的網絡結構。MobileNet是將標準的卷積神經網絡運算拆分紅Depthwise卷積運算和Pointwise卷積運算,先用Depthwise卷積對輸入各個通道分別進行卷積運算,而後用Pointwise卷積實現各個通道間信息的融合。
模型壓縮包括結構稀疏化和蒸餾兩種方式。
在邏輯迴歸算法中,咱們經過引入正則化,使得某些特徵的係數近似爲0。在卷積神經網絡中,咱們也但願經過引入正則化,使得卷積核的係數近似爲0。與普通的正則化不一樣的是,在結構稀疏化中,咱們但願正則化實現結構性的稀疏,好比某幾個通道的卷積核的係數所有近似爲0,從而能夠將這幾個通道的卷積核剪枝掉,減小沒必要要的計算開銷。
蒸餾方法有遷移學習的意思,就是設計一個簡單的網絡,經過訓練的方式,使得該簡單的網絡具備目標網絡近似的表示能力,從而達到「蒸餾」的效果。
移動端機器學習的計算框架和算法,前者負責模型計算的性能,減小時間開銷;後者主要負責模型的精度,還能夠經過一些算法設計減小算法的計算量,從而達到減小時間開銷的目的。
須要注意的是,在移動端機器學習中,算法模型的訓練一般是在服務器端進行的。目前,終端設備一般不負責模型的訓練。在使用時,由終端設備加載訓練結果模型,執行前向計算獲得模型的計算結果。
可是前面講了那麼多行業趨勢和機器學習的基本技術,那對於移動開發的同窗來講,如何進入這個「熱門」的領域呢?移動端機器學習是邊緣智能計算範疇的一個領域,並且移動端開發是Android開發同窗特別熟悉的領域,因此這也是Android開發同窗的一個發展機會,轉型進入邊緣智能計算領域。Android開發同窗能夠發揮本身的技術專業優點,先在邊緣計算的終端設備程序開發中站穩腳跟,在將來的技術分工體系中有個堅固的立足點;同時,逐步學習深度學習算法,以備未來往前邁一步,進入邊緣智能計算領域,創造更高的技術價值。
可能在大部分狀況下,Android開發同窗在深度學習算法領域,跟專業的算法同窗相比,不具備競爭優點,因此咱們千萬不要放棄本身所專長的終端設備的開發經驗。對大多數Android開發同窗而言,「專精Android開發並懂深度學習算法」纔是在將來技術分工中,創造最大價值的姿式。
對於學習路徑,我建議Android開發同窗能夠先學習卷積神經網絡的基礎知識(結構、訓練和前向計算),而後閱讀學習NCNN開源框架,掌握計算性能的優化方法,把開發技術掌握好。同時,能夠逐步學習算法技術,主要學習各類常見的深度學習算法模型,並重點學習近幾年出現輕量型神經網絡算法。總之,Android開發同窗要重點掌握提升計算實時性的開發技術和算法技術,兼顧學習深度學習算法模型。
基於前面的描述,我梳理了移動端機器學習的技術大圖供你參考。圖中紅圈的部分,是我建議Android開發同窗重點掌握的內容。
最近在學習張紹文老師的《Android開發高手課》課程,學習到了不少的乾貨,特別是在處理問題的策略和知識的廣度方面給了我不少的啓發,對將來的學習也提供了方向。
目前,技術的發展有兩個趨勢。一個趨勢是,隨着5G網絡的發展,物聯網使「萬物互聯」成爲可能。物聯網時代,也是雲計算和邊緣計算並存的世界,且邊緣計算將扮演重要的角色。邊緣計算是與雲計算相反的計算範式,指的是在網絡邊緣節點(終端設備)進行數據處理和分析。邊緣計算之因此重要,緣由在於:首先,在物聯網時代,將有數十億的終端設備持續採集數據,帶來的計算量將是雲計算所不能承受的;其次,終端設備的計算能力不斷提升,並非全部的計算都須要在雲端完成;再有,將數據傳回雲端計算再將結果返回終端的模式,不可避免存在時延,不只影響用戶體驗,有些場景也是不可接受的;最後,隨着用戶對數據安全和隱私的重視,也會要求在終端進行數據加工和計算。
另外一個趨勢是,人工智能技術的迅速發展。最近幾年,以深度學習爲表明的人工智能技術取得了突破性的進展,不只在社會上引發了人們的興趣和關注,同時也正在重塑商業的格局。人工智能技術的重大價值在於,藉助智能算法和技術,將以前必須人工才能完成的工做進行機器化,用機器的規模化解放人工,突破人力生產要素的瓶頸,從而大幅提升生產效率。在商業社會,「規模化」技術將釋放巨大的能量、創造巨大的價值,甚至重塑商業的競爭,拓展整個商業的外部邊界。
邊緣計算既然有計算能力,在不少應用場景中就會產生智能計算的需求,二者結合在一塊兒,就造成了邊緣智能計算。
移動端機器學習的開發技術
目前,移動端機器學習的應用技術主要集中在圖像處理、天然語言處理和語音處理。在具體的應用上,包括但不限於視頻圖像的物體檢測、語言翻譯、語音助手、美顏等,在自動駕駛、教育、醫療、智能家居和物聯網等方面有巨大的應用需求。目前已經商用的深度學習技術主要有以下一些:
框架 研發公司 支持平臺
TF_lite Google ARM
Caffe2 Facebook ARM
TF_lite Xiaomi ARM、DSP、GPU
paddle-mobile Baidu ARM、GPU
FeatherCNN Tencent ARM
NCNN Tencent ARM
1.計算框架
由於深度學習算法具備不少特定的算法算子,爲了提升移動端開發和模型部署的效率,各大廠都開發了移動端深度學習的計算框架,例如谷歌的TensorFlow Lite、Facebook的Caffe2等,Android開發的同窗仍是挺有必要去了解這些計算框架的。爲了培養興趣這方面的興趣並得到感性的認識,你能夠挑選一個比較成熟的大廠框架,例如 TensorFlow Lite,在手機開發一個物體檢測的Demo練練手。
在實際項目中,TensorFlow Lite和Caffe2等一般運行比較慢。在網上能夠很容易找到各個計算框架的對比圖。若是要真正入門的話,在這裏我推薦你們使用NCNN框架。NCNN是騰訊開源的計算框架,優勢比較明顯,代碼結構清晰、文件不大,並且運行效率高。強烈推薦有興趣的Android開發同窗把源碼閱讀幾遍,不只有助於理解深度學習經常使用的算法,也有助於理解移動端機器學習的計算框架。
閱讀NCNN源碼抓住三個最基礎的數據結構,Mat、Layer和Net。其中,Mat用於存儲矩陣的值,神經網絡中的每一個輸入、輸出以及權重,都是用Mat來存儲的。Layer實際上表示操做,因此每一個Layer都必須有前向操做函數(forward函數),全部算子,例如,卷積操做(convolution)、LSTM操做等都是從Layer派生出來的。Net用來表示整個網絡,將全部數據節點和操做結合起來。
在閱讀NCNN源碼的同時,建議你們也能夠看些關於卷積神經網絡算法的入門資料,會有助於理解。
2.計算性能優化
在實際項目中,若是某個路徑成爲時間開銷的瓶頸,一般能夠將該節點用NDK去實現。但在一般狀況下,移動端機器學習的計算框架已經在NDK中進行實現的,這時改進的方向是採用ARM NEON指令彙編進行優化。
NEON是適用於ARMCortex-A系列處理器的一種128Bit SIMD(Single Instruction%2CMultipleData,單指令、多數據)擴展結構。ARMNEON指令之全部能達到性能優化的目的,關鍵就在於單指令多數據。以下圖所示:
在這裏插入圖片描述
NEON的兩個操做數各有128Bit,各包含4個32Bit的同類型的寄存器,經過以下所示的一條指令,就能夠實現4個32Bit數據的並行計算,從而達到性能優化的效果。
VADDQ.S32 Q0,Q1,Q2
咱們曾經用NDK的方式實現了深度學習算法中的PixelShuffle操做,後來採用ARMNEON%2B彙編優化的方式,計算的效率提高40倍,效果仍是很顯著的。
若是還想進一步提升計算的性能,能夠採用Int 8量化的方法。在深度學習裏面,大多數運算都是基於Float 32類型進行的,Float 32是32Bit,128Bit的寄存器一次能夠存儲4個Float 32類型數據;相比之下,Int 8類型的數據能夠存儲16個。結合前面提到的單指令多數據,若是採用Int 8類型的數據,單條指令能夠同時執行16個Int 8數據的運算,從而大大提升了並行性。
可是,將Float 32類型的數值量化到Int 8表達,不可避免會影響到數據的精度,並且量化的過程也是須要時間開銷的,這些都是須要注意的地方。關於量化的方法,感興趣的同窗能夠閱讀這篇論文。
若是設備具備GPU,還能夠應用OpenCL進行GPU加速,例如小米開源的移動端機器學習框架MACE。
移動端機器學習的算法技術
對於剛開始學習算法的同窗,我一直主張不要把算法想象得太複雜,也不要想得太數學化,不然容易讓人望而生畏。數學是思惟邏輯的表達,咱們但願用數學幫助咱們理解算法。咱們要可以達到對算法的直觀理解,從直觀上知道和理解爲何這個算法會有這樣的效果,只有這樣纔算是真正掌握了算法。相反,對於一個算法,若是你只記住了數學推導,沒造成直觀的理解,是不可以靈活應用的。
1.算法設計
深度學習的圖像處理具備很廣的應用,並且比較直觀和有趣,建議你能夠從深度學習的圖像處理入手。深度學習的圖像處理,最基本的知識是卷積神經網絡,因此你能夠先學習卷積神經網絡。網上有不少關於卷積神經網絡的介紹,這裏就不贅述了。
理解卷積神經網絡關鍵是理解卷積神經網絡的學習機制,理解爲何可以學習。想要理解這一點,首先須要明確兩個關鍵點「前向傳播」和「反向傳播」。整個神經網絡在結構和激活函數肯定以後,所謂「訓練」或者「學習」的過程,其實就是在不斷地調整神經網絡的每一個權重,讓整個網絡的計算結果趨近於指望值(目標值)。前向傳播是從輸入端開始計算,目標是獲得網絡的輸出結果,再將輸出結果和目標值相比較,獲得結果偏差。以後將結果偏差沿着網絡結構反向傳播拆解到每一個節點,獲得每一個節點的偏差,而後根據每一個節點的偏差調整該節點的權重。「前向傳播」的目的是獲得輸出結果,「反向傳播」的目的是經過反向傳播偏差來調整權重。經過二者互相交替迭代,但願達到輸出結果和目標值一致。
理解卷積神經網絡以後,咱們能夠動手實現手寫字體識別的示例。掌握以後,能夠接着學習深度學習裏的物體檢測算法,例如YOLO、FasterR-CNN等,最後能夠動手用TensorFlow都寫一遍,跑跑訓練數據、調調參數,邊動手邊理解。在學習過程當中,要特別留意算法模型的設計思想和解決思路。
2.效果優化
效果優化指提高算法模型的準確率等指標,一般的方式有如下幾種:
優化訓練數據;
優化算法設計;
優化模型訓練方式
優化訓練數據
由於算法模型是從訓練數據中學習的,模型沒法學習到訓練數據以外的模式。因此,在選擇訓練數據時要特別當心,必須使得訓練數據包含實際場景中會出現的模式。精心挑選或標註訓練數據,會有效提高模型的效果。訓練數據的標註對效果很是重要,以致於有創業公司專門從事數據標註,還得到了很多融資。
優化算法設計
根據問題採用更好的算法模型,採用深度學習模型而不是傳統的機器學習模型,採用具備更高特徵表達能力的模型等,例如使用殘差網絡或DenseNet提升網絡的特徵表達能力。
優化模型訓練方式
優化模型訓練方式包括採用哪一種損失函數、是否使用正則項、是否使用Dropout結構、使用哪一種梯度降低算法等。
3.計算量優化
雖然咱們在框架側作了大量的工做來提升計算性能,可是若是在算法側可以減小計算量,那麼總體的計算實時性也會提升。從模型角度,減小計算量的思路有兩種,一種是設計輕量型網絡模型,一種是對模型進行壓縮。輕量型網絡設計學術界和工業界都設計了輕量型卷積神經網絡,在保證模型精度的前提下,大幅減小模型的計算量,從而減小模型的計算開銷。這種思路的典型表明是谷歌提出的MobileNet,從名字上也能夠看出設計的目標是移動端使用的網絡結構。MobileNet是將標準的卷積神經網絡運算拆分紅Depthwise卷積運算和Pointwise卷積運算,先用Depthwise卷積對輸入各個通道分別進行卷積運算,而後用Pointwise卷積實現各個通道間信息的融合。
模型壓縮
模型壓縮包括結構稀疏化和蒸餾兩種方式。
在邏輯迴歸算法中,咱們經過引入正則化,使得某些特徵的係數近似爲0。在卷積神經網絡中,咱們也但願經過引入正則化,使得卷積核的係數近似爲0。與普通的正則化不一樣的是,在結構稀疏化中,咱們但願正則化實現結構性的稀疏,好比某幾個通道的卷積核的係數所有近似爲0,從而能夠將這幾個通道的卷積核剪枝掉,減小沒必要要的計算開銷。
蒸餾方法有遷移學習的意思,就是設計一個簡單的網絡,經過訓練的方式,使得該簡單的網絡具備目標網絡近似的表示能力,從而達到「蒸餾」的效果。
Android開發同窗的機會
移動端機器學習的計算框架和算法,前者負責模型計算的性能,減小時間開銷;後者主要負責模型的精度,還能夠經過一些算法設計減小算法的計算量,從而達到減小時間開銷的目的。
須要注意的是,在移動端機器學習中,算法模型的訓練一般是在服務器端進行的。目前,終端設備一般不負責模型的訓練。在使用時,由終端設備加載訓練結果模型,執行前向計算獲得模型的計算結果。
可是前面講了那麼多行業趨勢和機器學習的基本技術,那對於移動開發的同窗來講,如何進入這個「熱門」的領域呢?移動端機器學習是邊緣智能計算範疇的一個領域,並且移動端開發是Android開發同窗特別熟悉的領域,因此這也是Android開發同窗的一個發展機會,轉型進入邊緣智能計算領域。Android開發同窗能夠發揮本身的技術專業優點,先在邊緣計算的終端設備程序開發中站穩腳跟,在將來的技術分工體系中有個堅固的立足點;同時,逐步學習深度學習算法,以備未來往前邁一步,進入邊緣智能計算領域,創造更高的技術價值。
可能在大部分狀況下,Android開發同窗在深度學習算法領域,跟專業的算法同窗相比,不具備競爭優點,因此咱們千萬不要放棄本身所專長的終端設備的開發經驗。對大多數Android開發同窗而言,「專精Android開發並懂深度學習算法」纔是在將來技術分工中,創造最大價值的姿式。
對於學習路徑,我建議Android開發同窗能夠先學習卷積神經網絡的基礎知識(結構、訓練和前向計算),而後閱讀學習NCNN開源框架,掌握計算性能的優化方法,把開發技術掌握好。同時,能夠逐步學習算法技術,主要學習各類常見的深度學習算法模型,並重點學習近幾年出現輕量型神經網絡算法。總之,Android開發同窗要重點掌握提升計算實時性的開發技術和算法技術,兼顧學習深度學習算法模型。
基於前面的描述,我梳理了移動端機器學習的技術大圖供你參考。圖中紅圈的部分,是我建議Android開發同窗重點掌握的內容。
在這裏插入圖片描述
Markdown 已選中 5169 字數 105 行數 當前行 105, 當前列 63HTML 4783 字數 71 段落