全能電路設計實戰

2020年10月5日 星期一

AI邊緣運算實作: TensorFlow Lite for MCU




AI邊緣運算


隨著物聯網與人工智慧發展,工作負載開始由雲端移轉至終端,AI也隨之進入到嵌入式系統及物聯網終端裝置中。在終端或所謂邊緣裝置這類的超低功耗微處理器上所實現的深度學習,被稱呼為微型深度學習。然而在MCU本身運算速度就不快,記憶體空間也有限的情況下,AI模型也不能太大,因此要能確保AI 效能,同時兼顧低功耗、成本與縮短開發時間,都是研發人員所必須面對的挑戰。

什麼是TensorFlow Lite

TensorFlow Lite for MCU正是專為邊緣裝置設計的TensorFlow模型預測框架,是TensorFlow的精簡版本,讓開發者可以在物聯網與嵌入式裝置中部署微型機器學習模型。

AI模型佈署於微控制器,需要那些知識 ?

首先,必須先知道TensorFlow Lite for MCU 在實作上會涉及Deep Learning 觀念及MCU開發技術,然而這是兩個截然不同的技術領域的人, 故要能有效整合出好的AI系統,必須能同時理解這兩邊的技術。簡而言之,你會需要對於Deep Learning 有一定的概念、還要有模型優化(如Quantization)、TensorFlow Lite的框架以及MCU程式開發的相關知識。技術不能說很難,但對於初學者,沒有人引導,是有困難度的,因為開發環境包含AI環境與MCU的BSP環境都不太熟悉的情況下,產生的錯誤常常搞不清楚問題在那 。

在板子跑AI和我在電腦跑AI有何差別?

在電腦上跑AI,對於輸入資料多半是.csv或圖片,以檔案方式存在。 然而在邊緣運算上, 輸入的資料通常是來自硬體的感測器,因此要能正確且即時的對資料預處理並且轉換成模型所須要的x輸入型狀(x input shape)才能代入模型。但資料抓取上要如何切成一個剛好完整的x 來進行推論呢? 例如聲音訊號是連續波, 不可能每次都剛好切出一段完整的聲音丟入模型,而得到很好的正確率。還有,像是感測器訊號也可能有雜訊產生,也會造成模型誤判。所以在系統上,需要有一個處理的機制來讓我們的AI系統達到穏定。

在板子上讀取硬體訊號,作為模型輸入的資料 $x$

板子上的感測器,可能像是G-Sensor 、Microphone 這類的。接著我們要讀出感測訊號並觀察訊號。務必確認感測訊號是正確的,因為不對的$x$, 就會是GIGO (Garbage In Garbage Out)。
然後對原始訊號做訊號處理 (即數據的前處理) ,獲得訊號的特徵向量 $x'$ 後 ,再餵入模型 $\hat{y}=f(x')$

在Sparkfun edge board 讀取G-Sensor X, Y,Z 的變化


在Sparkfun edge board 讀取Microphone 左右聲道變化


Tiny DL Demo
底下Demo 幾個AI邊緣運算分別在圖像、聲音、感測訊號的應用

2020年10月2日 星期五

Quick guide for building Raspberry Pi kernel 4.4.x


For  Driver course (www.ittraining.com.tw)

1) 安裝toolchain (Cross compiler)

# For 32 位元Linux 

export PATH=/home/student/pi/tools/arm-bcm2708/arm-bcm2708-linux-gnueabi/bin:$PATH

# For 64 位元Linux
export PATH=/home/student/pi/tools/arm-bcm2708/arm-bcm2708-linux-gnueabi-x64/bin:$PATH


root@ubuntu:/home/student/pi# arm-linux-gnueabihf-gcc -v

..
gcc version 4.8.3 20140303 (prerelease) (crosstool-NG linaro-1.13.1+bzr2650 - Linaro GCC 2014.03)





2) Linux kernel 編譯

#進入kernel source tree

cd linux  

# 產生 .config


For Raspberry Pi 2, Pi 3, Pi 3+, and Compute Module 3 default build configuration

KERNEL=kernel7
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- bcm2709_defconfig

For Raspberry Pi 4
KERNEL=kernel7l
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- bcm2711_defconfig

#編譯 Linux kernel、kernel module 及 device tree

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- zImage modules dtbs -j 2
# 安裝  kernel module

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- INSTALL_MOD_PATH=../modules modules_install



#複製kernel image & dtb 到 Raspberry Pi


sudo cp arch/arm/boot/zImage /boot/$KERNEL.img
sudo cp arch/arm/boot/dts/*.dtb /boot/
sudo cp arch/arm/boot/dts/overlays/*.dtb* /boot/overlays/


#複製 kernel modules 到 Raspberry Pi


tar zcvf modules.tar.gz  modules

scp modules.tar.gz root@192.168.1.141:/root

tar zxf modules.tar.gz
解開後將 <kernel version> 目錄放到 /lib/modules/


----------------------------------------------------
在 Raspberry Pi 編譯kernel module

1.) copy kernel source to  Raspberry Pi

scp linux-rpi-4.14.98-v7.tar.gz root@192.168.1.157:/root

tar zxf linux-rpi-4.14.98-v7.tar.gz

2.)建立連結到 kernel source

cd /lib/modules/4.14.98-v7
ln -sf  /root/linux-rpi-4.14.98-v7 build




------------------------------------------------------------------------------------
3.) build  driver module from source

cd kernel_driver/01_LED 
.
├── chr_led.c
├── Makefile
└── test.c

make 


├── chr_led.c
├── chr_led.ko
├── chr_led.mod.c
├── chr_led.mod.o
├── chr_led.o
├── Makefile
├── modules.order
├── Module.symvers
└── test.c

發生 fixdep error! Exec format error

進入kernel source 重新產生ARM版本的工具集

cd /root/linux-rpi-4.14.98-v7
make scripts 







4.)   測試 module

#載入模組sudo insmod chr_led.ko

#顯示所有模組
lsmod




#用user應用程式測試driver
gcc test.c -o test

sudo ./test   ==> 你會看見LED 在閃礫

#卸載模組
rmmod chr_led