【tinyML專題】 使用 EdgeImpulse 讓您的 Arduino 可以辨識手勢!

作者/攝影 曾吉弘
時間 2 小時
難度

★★★☆☆

材料表

1 認識 wio terminal

Wio Terminal 是一款專門用於 IoT 與 TinyML 的多功能開發板 – 包含了 ATSAMD51P19 晶片並以 ARM Cortex-M4F 為核心 (20MHz),已支援多種針對微控制器的 ML推論框架。

本開發板已包含:

  • 光感測器(類比)
  • 麥克風
  • 可自訂按鈕 x 3
  • 4 英吋彩色LCD
  • 加速度感測器
  • Grove 接頭 x 2,可連接多達300種 Grove 感測器

就軟體面來說, Arduino IDE 已可用於開發各種支援 Edge Impulse 與 Tensorflow Lite 的微控制器裝置來進行神經網路訓練與推論,或者您也可以玩玩看另一款熱門的開發環境 platformIO  也可以玩玩看。Edge Impulse 是一款針對邊緣運算裝置 x 機器學習的簡單易用的 coding free 開發環境。使用者可透過網頁介面就可以完成整個 tinyML 作業流程,從資料收集、資料處理、訓練神經網路到匯出部署,一條龍啊!

本文將示範如何把 wio terminal 所收集到的手勢資料 (光感測器數值變化) 上傳到 Edge Impulse,完成上述流程之後再放回到 wio terminal 來執行離線 ML 推論,超好玩又富有學習意義,您一定要試試看!

如何辨識手勢

在此的假設為,不同的手勢在光感測器上方晃動時,會產生可區別的時序資料(time series data),我們就是要把這些資料送到 Edge Impulse 網站來處理、學習,並匯出一個 wio terminal 可執行推論的神經網路模型檔!

可想而知,如果用傳統的做法就很難去定義,怎樣的 pattern 可以一體適用各種不同的手勢都可以有不錯的辨識效果。(後續各位在收資料的時候就知道,同一種手勢的 time series 資料形狀差異很大!

 

2 PC端設定

2-1 設定 Arduino IDE 2.0

根據原廠文件,請使用 Arduino IDE 1.9 以上,所以我直接使用 2.0,請根據您的作業系統版本取得對應的 Arduino 2.0 IDE

注意!編譯 Edge Impulse 匯出檔案才需要用到 Arduino IDE 1.9以上,如果是把 wio terminal 當作一般 arduno 使用的話,經我實測使用 Arudino 1.8.X 沒有問題

 

請在 File → Preference →  Additional Baord url 欄位中填入:

https://files.seeedstudio.com/arduino/package_seeeduino_boards_index.json

完成之後就可以透過  Tools → Board → Board manager,輸出 “Wio” 來安裝 wio terminal 相關套件,點選 INSTALL

完成就可以看到 Wio Terminal 相關選項

 

2-2 安裝 node.js 與 edge impulse 相關工具

根據您的平台安裝 Node.js 1.0 以上版本,完成之後開啟 cmd 輸入以下指令來安裝 edge-impulse-cli:

npm install -g edge-impulse-cli

3 透過 edge cli 上傳感測器資料到 Edge Impulse

請新增一個 Arduino專案,輸入以下程式碼上傳到 wio terminal,會透過 serial 把光感測器資料傳給 edge cli,再上傳到 Edge Impulse 網站的指定專案(當然是您的帳號)

由 FREQUENCY_HZ 40 可知,我們會在 1000 ms (1秒鐘) 的時間長度取得 40 筆光感測器資料,並以這一段時間中的亮度變化作為指定的手勢,也預設 石頭 的手勢差異是可以被學習出來的。

#define FREQUENCY_HZ 40
#define INTERVAL_MS   (1000 / (FREQUENCY_HZ))

void setup() {
    Serial.begin(115200);
    Serial.println("Started");
}

void loop() {
    static unsigned long last_interval_ms = 0;
    float light;
    if (millis() > last_interval_ms + INTERVAL_MS) {
        last_interval_ms = millis();
        light = analogRead(WIO_LIGHT);  //讀取 wio 光感測器類比腳位
        Serial.println(light);
    }
}

燒錄完成之後 wio terminal 就擺著,接著要透過 edge cli 來上傳資料到 edge Impulse 網站

開啟 cmd 之後輸入以下指令,會請您登入 edge Impulse 的帳號密碼並詢問以下事項:

  • 裝置所連接的 COM port
  • 命名資料欄位:如下圖的 light

由下圖可以看到您的裝置 ID: 01:DF:FE… 這一段,就是透過這個 ID 來識別您的裝置。

edge-impulse-data-forwarder

Edge Impulse – 登入與設定裝置

這一段最辛苦啦,幾乎所有的設定都是在 Edge Impulse 網站上完成,但說真的已經省很多事情了。

請先建立一個 Edge Impulse 帳號並登入。為了怕各位迷路,我會用顏色來標注現在是在哪一個 tab。以下是登入後的主畫面,也就是畫面左側 – Dashboard,可以看到專案相關設定。

左側 – Device

裝置基本設定,可以看到本帳號下的所有裝置,可以點選右側 來編輯裝置設定或刪除裝置

Edge Impulse – 收資料

這裡要收資料,請確認您的 wio terminal 已經上傳上述 arduino sketch 來準備傳資料,否則資料當然無法上傳到 Edge Impulse網站。

請點選左側 – Data acquisition

中間的 collected data 一開始當然不會有東西,因為還沒開始上傳資料。請於畫面右側這樣設定:

  • Label: rock (石頭)/ paper (布) -> 要辨識多少種手勢都沒問題,端看您願意花多少時間去收資料而已。
  • Sensor: Sensor with 1 axes (light)
  • sample length(ms): 1000
  • Frequency (39Hz) 這裡自動帶入 arduino sketch 的 FREQUENCY_HZ,不用改

好了之後,按下右下角的 Start sampling,這時候請準備好您的手在 wio terminal 的光感測器擺好手勢並晃動。取得資料,就會在畫面中間多一筆新的資料出來,點選該筆資料就可以看到他形狀(光感測器讀數 vs 時間)

上傳多筆資料之後的畫面如下,在此請讓您所要辨識的 label 的資料筆數盡量相等,反正上傳也不會很麻煩,每一筆資料右側的 都可以點選來編輯資料屬性或刪除該筆資料。

最後請點選 train / test split 來設定訓練/測試資料的分配比例,完成每一項的必要設定之後,前面會亮起綠色燈,才能進到下一步。

Edge Impulse – 訓練模型

左側 – impulse design / Create impulse

根據 EdgeImpulse 本身的定義,impulse 是指一個 pipeline,您會在此設定關於 raw data 處理方式、如何處理(processing block)、如何學習(learning block),這樣才算是一個完整的流程。

以我們的手勢辨識範例,在此是長度為一秒鐘的光感測器資料,所以屬於 time series data。在此請把 window size 與 window increase 分別設為 1000, 50ms,Frequency 會自動帶入 wio terminal Arduino 碼設定中所的頻率 (40Hz),這裡就不用動。

點選 [Add a processing block] ,選單中選擇  Raw data,就會新增這個block。

請在其中選擇 Input axes 也就是所要處理的資料,在此只有一筆,就是  light。不同型態的資料可能會用到更多 processing block,之後再慢慢說明。

接著點選 [Add a learning block] ,選單中選擇  Classification (Keras),就會新增這個 block。fafa   Input feature 選擇  Raw data,輸出會自動帶出 2 (paper, rock) 也就是 data acquisition 時所設定的 label 名稱。

本區設定完成如下圖,最後點選 Save Impulse 就完成了。

Edge Impulse – 原始資料產生特徵

左側 – impulse design / Raw data 

在此要針對原始資料產生特徵,先看到 Parameters 標籤,到時候要把 Raw feature 這一段複製到最後匯出的 arduino sketch 才能順利執行推論。

接著按下 Generate features 標籤,跑完會看到如右圖的資料特徵分布,這一段就完成了。

Edge Impulse – 訓練模型

左側 – impulse design /  NN classifier

本段要設定神經網路架構,可以自己定義神經網路架構,在此我新增了兩個 Dense 密集連接層,分別使用 20, 10 個神經元,相當小巧。另外兩個參數如下設定:

  • Number of training cycles: 看過一遍所有資料稱為一次,在此設定 500
  • Learning rate: 神經網路收斂的速度,這個數值通常非常小,在此設定 0.0001

當然功能不止這樣啦,點選 [Add an extra layer],可以看到以下 keras 層,要加入卷積層也是可以的,別急別急,之後都可以玩玩看的。

設定好架構之後,點選下方的 [Start training] 就會開始訓練,過程中沒有寫一行程式碼,真的很方便!右側可以看到訓練過程中的輸出訊息。

第一次訓練完的 accuracy / loss 只有 75%, 0.65,差強人意呢

我又上傳了一些手勢資料,用同樣的架構再跑一次,accuracy 就到 100%了!當然 loss 0.62 很高啦,不過這之後可以慢慢調,先繼續下去吧

Edge Impulse – 測試神經網路模型成效

 

網站左側,選擇Live Classification

先不急著匯出,先上傳一筆資料玩玩看,可以上傳懸心資料,或是從既有資料來看看

左下角可以看到 PAPERS 0.52, ROCK 0.48,這當然不是一個很好的結果,就需要回頭去調整資料,或是修正更好的神經網路架構

Edge Impulse – 匯出神經網路模型

網站左側,選擇 Deployment

會列出目前可匯出的平台,請點選 Arduino,另外也可以看到 NVIDIA tensorRT,各種選項愈來愈完整,非常棒。

同一個頁面往下拉,使用預設設定 Quantized (int8),接著選擇 Build

看到這張圖就沒問題了, .zip 檔不用解壓縮,等等直接匯入 Arduino IDE 即可。

 

Arduino 匯入之後開始使用

開啟 Arduino IDE,選擇 Sketch → Include Library → Add .ZIP library  匯入上一步取得的 .zip

完成之後就可以在 File 選到這個範例,請開啟其中的 static buffer

請到 Edge Impulse 網站,選擇 Impusle design / Raw data,複製 Raw features 到您的樣板專案中,有一個複製符號可以直接按,這裡的資料數量就會等於 Frequency,以本範例來說就是 40。

貼到您的 Arduino 範例中的  features[] 陣列中,這樣就可以了。

接著上傳程式到 wio termnial ,就可以從 serial monitor 看到每一次的推論結果,happy making!!

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *