Gitee倉庫
git clone https://gitee.com/banana-peel-x/freedom-learn.git
項目場景:
解決面試時遺留的問題,面試官提了兩個問題:1.單片機能跑深度學習的模型嗎? 2.為什么FreeRTOS要采用SVC去觸發第一個任務,只用PendSV中斷切換不行嗎?(問題二后續研究) 問題一:當時回答的是理論上單片機掛載NPU,把數據發送給NPU的協議定好,理論上也是可以的。 本項目就從輪子出發,不借助任何庫,嘗試小RAM MCU部署神經網絡的方法。分別在MCU和PC端進行了嘗試。技術棧:多層網絡感知機(MLP),正反向傳播,梯度下降法。模型量化部署。結論:MCU受限于主頻速率,小RAM,在推理時間,模型大小方面均存在限制,即使使用硬件加速的NPU,速率也沒有優勢。
軟件架構
MCU端: 兩個Task,StartDefaultTask控制LED,觀察系統有沒有掛掉。StartTask_50ms里運行reason_task,執行時機通過flag_uart1_received變量判斷ReceiverState狀態,flag_uart1_received變量在Uart中斷切換狀態。 PC端: reasoning.py運行兩個線程,主線程負責PC端的推理,send_image_over_uart線程通過Uart發送圖像,并監聽下位機的推理結果。
NeuralNetworkFromScratch-main\train.py:使用MLP訓練一組權重參數,保存到文件\result\model_parameters.npz,后在終端隨機輸入圖片序號,進行預測,預測結果在數字上方,方便比較。
NeuralNetworkFromScratch-main\result\Tools.py:從model_parameters.npz文件中load權重參數,寫入model_parameters.c文件
NeuralNetworkFromScratch-main\result\quantization.py:將model_parameters.npz提取權重參數,量化為int8類型,后寫入quantized_model_parameters.c文件
NeuralNetworkFromScratch-main\result\reasoning.py:核心文件,加載量化后的參數,對權重參數反量化后推理,同時send_image_over_uart線程發送圖像數據給MCU
運行reasoning.py后,選擇圖片序號,終端打印預測概率,關閉窗口后send_image_over_uart線程發送圖像給MCU端,發送完成后會監聽下位機返回數據,并在終端打印。
細節:
1.不量化行不行:STM32F103C8T6又64K的ROM和20K的RAM,不量化權重參數會占用:(784x10+10+10x10+10)x4=31840 Bytes=31KB。量化后權重參數占用空間:7.7KB。
2.為什么網絡參數是 輸入層到隱藏層10個神經元,隱藏層到輸出層10個神經元,原始網絡分別是20,10。這樣的話很容易超出RAM大小。