01前言
在大多數(shù)情況下,實用的機器學習算法需要大量計算資源(CPU 運算周期和內(nèi)存占用)。不過,TensorFlow Lite 近期推出了一個實驗版本,可在多款微控制器上運行。倘若我們能構建出適用于資源受限設備的模型,便能著手將嵌入式系統(tǒng)改造為小型機器學習(TinyML)設備。
TensorFlow Lite Micro(簡稱 TFLM)是一款開源的機器學習推理框架,專為在嵌入式系統(tǒng)上運行深度學習模型而設計。由于嵌入式系統(tǒng)存在資源受限的問題,且碎片化現(xiàn)象導致跨平臺互操作性幾乎無法實現(xiàn),而 TFLM 恰好滿足了相關效率要求。該框架采用基于解釋器的設計方案,既能克服這些獨特挑戰(zhàn),又能提供良好的靈活性。

圖 1:一個包含兩層的簡易深度學習網(wǎng)絡
02開發(fā)
開發(fā) TFLM 應用的第一步是在內(nèi)存中創(chuàng)建一個有效的神經(jīng)網(wǎng)絡模型對象。應用開發(fā)者需通過客戶端 API 創(chuàng)建一個 “算子解析器”(operator resolver)對象。該 “算子解析器”(OpResolver)API 會控制與最終二進制文件關聯(lián)的算子,并最大限度減小文件體積。
第二步是提供一塊連續(xù)的內(nèi)存 “區(qū)域”(arena),用于存儲解釋器所需的中間結果和其他各類變量。這一步是必不可少的,因為嵌入式設備默認不支持動態(tài)內(nèi)存分配。
第三步是創(chuàng)建一個編譯示例,并將模型、算子解析器和內(nèi)存區(qū)域作為參數(shù)傳入。編譯器會在初始化階段,將運行所需的所有內(nèi)存分配到該內(nèi)存區(qū)域中。我們避免進行任何動態(tài)內(nèi)存分配,以防止棧碎片化導致長期運行的應用程序出現(xiàn)錯誤。觸發(fā)式應用可在模型評估階段分配所需內(nèi)存,因此此時會調(diào)用算子初始化函數(shù),并將其占用的內(nèi)存轉移至解釋器中。應用程序提供的算子解析器(OpResolver)會將序列化模型中列出的算子類型,映射到對應的執(zhí)行函數(shù)。C 語言 API 調(diào)用負責管控解釋器與算子之間的所有通信,確保算子的實現(xiàn)具備模塊化特性,且獨立于解釋器的內(nèi)部細節(jié)。這種設計方案不僅能讓開發(fā)者輕松地將算子執(zhí)行器實現(xiàn)替換為優(yōu)化版本,還能更便捷地復用其他系統(tǒng)的算子執(zhí)行庫(例如,作為代碼生成項目的一部分)。
第四步是執(zhí)行階段。應用程序先獲取指向代表模型輸入的內(nèi)存區(qū)域指針,然后為其填充數(shù)據(jù)(這些數(shù)據(jù)通常來源于傳感器或其他用戶提供的輸入)。輸入數(shù)據(jù)準備就緒后,應用程序調(diào)用解釋器來執(zhí)行模型計算。該過程包括:遍歷按拓撲結構排序的算子、利用內(nèi)存規(guī)劃階段計算得到的偏移量定位輸入與輸出數(shù)據(jù)、以及為每個算子調(diào)用對應的評估執(zhí)行函數(shù)。
最后,當所有算子評估執(zhí)行完成后,解釋器會將控制權交還給應用程序。大多數(shù)微控制器(MCU)都是單線程架構,依靠中斷來處理緊急任務,這種方式是完全可行的。不過,應用程序仍可在單線程上運行,且特定于平臺的算子仍能在多個處理器之間分配計算任務。當解釋器調(diào)用完成后,應用程序可向解釋器查詢包含模型計算輸出結果的數(shù)組所在位置,隨后即可使用該輸出結果。

圖 2:實現(xiàn)模塊概述
03部署
使用 Keras 或 TensorFlow 構建的模型,需要先轉換為 TensorFlow Lite 格式并導出,才能部署到微控制器上運行。我們可以借助 TensorFlow Lite Converter 的 Python API 來完成這項轉換工作。該 API 會接收我們的 Keras 模型,并將其以 FlatBuffer 格式寫入磁盤 ——FlatBuffer 是一種專為提升空間利用率而設計的特殊文件格式。由于我們要部署的目標設備是內(nèi)存受限的微控制器,這種高效的文件格式將會大有用處。
要將模型部署到 STM32 微控制器和 Arduino 平臺,我們可以使用 EloquentTinyML 庫來實現(xiàn)無縫部署。這是一款專為在微控制器上運行 TinyML 模型而設計的庫,能夠讓開發(fā)者無需應對復雜的編譯流程,也無需排查晦澀難懂的報錯信息。
你首先必須安裝該庫的最新版本(如果 0.0.5 版本不可用,可選擇 0.0.4 版本),安裝方式既可以通過庫管理器(Library Manager)完成,也可以直接從 Github 平臺下載安裝。
04示例代碼
以下是用于在 STM32 和 Arduino 微控制器上運行并部署數(shù)字識別 TinyML 模型的示例代碼。
向上滑動閱覽
#include// copy the printed code from tinymlgen into this file #include"digits_model.h" #defineNUMBER_OF_INPUTS 64 #defineNUMBER_OF_OUTPUTS 10 #defineTENSOR_ARENA_SIZE 8*1024 Eloquent::TfLite ml; voidsetup(){ Serial.begin(115200); ml.begin(digits_model); } voidloop(){ // a random sample from the MNIST dataset (precisely the last one) floatx_test[64] = {0.,0.,0.625,0.875,0.5 ,0.0625,0.,0., 0.,0.125,1.,0.875,0.375,0.0625,0.,0., 0.,0.,0.9375,0.9375,0.5 ,0.9375,0.,0., 0.,0.,0.3125,1.,1.,0.625,0.,0., 0.,0.,0.75 ,0.9375,0.9375,0.75 ,0.,0., 0.,0.25 ,1.,0.375,0.25 ,1.,0.375,0., 0.,0.5 ,1.,0.625,0.5 ,1.,0.5 ,0., 0.,0.0625,0.5 ,0.75 ,0.875,0.75 ,0.0625,0.}; // the output vector for the model predictions floaty_pred[10] = {0}; // the actual class of the sample inty_test =8; // let's see how long it takes to classify the sample uint32_tstart =micros(); ml.predict(x_test, y_pred); uint32_ttimeit =micros() - start; Serial.print("It took "); Serial.print(timeit); Serial.println(" micros to run inference"); // let's print the raw predictions for all the classes // these values are not directly interpretable as probabilities! Serial.print("Test output is: "); Serial.println(y_test); Serial.print("Predicted proba are: "); for(inti =0; i 10; i++) { Serial.print(y_pred[i]); Serial.print(i ==?9???' '?:?','); } // let's print the "most probable" class // you can either use probaToClass() if you also want to use all the probabilities Serial.print("Predicted class is: "); Serial.println(ml.probaToClass(y_pred)); // or you can skip the predict() method and call directly predictClass() Serial.print("Sanity check: "); Serial.println(ml.predictClass(x_test)); delay(1000); }
歡迎您點擊“閱讀原文”訪問e絡盟官網(wǎng)。如有任何業(yè)務、訂購相關問題,歡迎撥打全國客服熱線:4008205857咨詢e絡盟相關產(chǎn)品。
-
微控制器
+關注
關注
48文章
8305瀏覽量
163538 -
STM32
+關注
關注
2307文章
11150瀏覽量
372393 -
Arduino
+關注
關注
190文章
6523瀏覽量
196459 -
卷積神經(jīng)網(wǎng)絡
關注
4文章
372瀏覽量
12795
原文標題:如何在 STM32 和 Arduino 上實現(xiàn)卷積神經(jīng)網(wǎng)絡
文章出處:【微信號:易絡盟電子,微信公眾號:易絡盟電子】歡迎添加關注!文章轉載請注明出處。
發(fā)布評論請先 登錄
如何在STM32和Arduino上實現(xiàn)卷積神經(jīng)網(wǎng)絡
評論