使用 TensorFlow Lite for Microcontrollers 和 SparkFun Edge 的 AI 語音辨識功能

1. 簡介

建構項目

在本程式碼研究室中,我們將學習使用 TensorFlow Lite for Microcontrollers,在 SparkFun Edge 開發委員會上執行深度學習模型。我們將使用 Jamboard 的內建語音偵測模型,這個模型使用卷積類神經網路來偵測「是」字詞和「否」正透過海板的兩個麥克風說話

bf256d403a1821af.gif

微控制器的機器學習技術

機器學習技術可用於打造智慧工具,提供更便捷的生活,例如 Google 助理。不過,這類體驗需要大量的運算或資源,包括強大的雲端伺服器或桌上型電腦。不過,現在也能在微型低電的硬體 (例如微控制器) 上執行機器學習推論。

微控制器非常常見、成本低廉,需要的能源極少,而且十分可靠。這些元件屬於各式各樣的家庭裝置:電器、汽車和玩具。事實上,每年生產約 300 億部採用微控制器的裝置。

1360b61fbfa33657.jpeg

透過在極小的微控制器提供機器學習技術,我們得以為生活中數十億部 Google 裝置提供智慧功能,不必依賴昂貴的硬體或可靠的網路連線。想像一下,如果智慧家電可以依照您的日常作息調整,還有智慧型工業感測器可瞭解問題與正常操作之間的差異,而有魔法玩具可以幫助孩子以有趣且愉快的方式學習。

TensorFlow Lite for Microcontrollers (軟體)

358ffdb9eb758b90.png

TensorFlow 是 Google 的開放原始碼機器學習架構,用於訓練及執行模型。TensorFlow Lite 是一種軟體架構,此為 TensorFlow 的最佳化版本,專門用於在手機等低階裝置 (例如手機) 上執行 tensorflow 模型。

TensorFlow Lite For Microcontrollers 是一種軟體架構,是 TensorFlow 的最佳化版本,主要目標為在微弱的小型硬體 (例如微控制器) 上執行 Tensorflow 模型。它遵守這些內嵌環境中所需的限制,例如二進位檔大小較小、不需要作業系統支援,也不需要任何標準 C 或 C++ 程式庫,或是動態記憶體配置等。

SparkFun Edge (硬體)

SparkFun Edge 是以微控制器為基礎的平台:單一電路板上的小型電腦。搭載處理器、記憶體和 I/O 硬體,可傳送及接收數位訊號至其他裝置。搭載四種軟體控制 LED 燈,為你最愛的 Google 配色。

aa4493835a2338c6.png

有別於電腦,微控制器無法執行作業系統,而會直接在硬體上執行您撰寫的程式。您將電腦編寫程式碼,並透過名為程式設計師的裝置將程式碼下載至微控制器。

微控制器並非強大的電腦,這類電腦搭載小型處理器,記憶體容量不多。但因為在設計上盡可能簡單,微控制器只會耗用極少的能源。視程式的工作而定,使用一枚硬幣電池,SparkFun Edge 可以執行數週!

課程內容

  • 在電腦上編譯 SparkFun Edge 的範例程式
  • 將程式部署至裝置
  • 變更程式內容並再次部署

軟硬體需求

您需要具備下列硬體:

您需要下列軟體:

  • Git (透過指令列執行 git,藉此檢查是否已安裝 SDK)
  • Python 3 (透過指令列執行 python3python --version,即可檢查是否已安裝完成)
  • Python 3 適用的 Pip ( 實用的 StackOverflow 解答)
  • 推出 4.2.1 以上版本 (透過指令列執行 make --version,確認是否已安裝)
  • SparkFun Serial 基本驅動程式

2. 設定硬體

SparkFun Edge 微控制器隨附預先安裝的二進位檔,可用來執行語音模型。在我們以自己的版本覆寫之前,先執行這個模型。

以下做法可讓主機板節能:

  1. 將硬幣電池插入電板背面的電池連接器 (電池的「+」面朝上)。如果電板已插入電池,請取出塑膠片並推電池,確認電池已完全插入)。

25a6cc6b208e8a4e.png

  1. 如果您沒有硬幣電池,可以使用 SparkFun USB-C 序列基本程式設計師裝置為 Jamboard 供電。如要將這部裝置連接至 Jamboard,請按照下列步驟操作:
  • 找出 SparkFun Edge 側邊的六個圖釘標頭。
  • 將 SparkFun USB-C 序列基本插頭插入這些接腳,確保標示「BLK」的針腳和「GRN」並確認各個裝置的排列順序均正確無誤
  • 在 SparkFun USB-C 序列基本級和電腦之間連接 USB-C 傳輸線。

b140822f0019f92a.png

裝上電池或連接 USB 程式設計師將電板開機後,電路板會喚醒,並開始透過麥克風聆聽音訊。藍燈應該會開始閃爍。

開發板上的機器學習模型經過訓練,可辨識「是」字詞偵測和偵測結果是否存在這個模式會透過燈號閃爍的 LED 燈傳達測試結果。下表列出各個 LED 顏色的含義:

偵測結果

LED 顏色

「是」

黃色

「否」

紅色

不明語音

綠色

偵測不到語音

LED 燈未亮起

歡迎體驗

將白板舉到嘴巴上,然後說「好」數次你會看到黃色的 LED 閃光燈。說出「是」後,如果系統仍未回應,請嘗試下列做法:

  • 將遊戲板維持在約 10 英寸你的嘴巴
  • 避免背景噪音過多
  • 再說一次「是」連續幾次 (試著說「是,是」)

3. 設定軟體

現在要自行下載、安裝及執行微控制器上的語音模型。為了達到這個目的,我們先下載這個程式的原始碼,以及建構此程式所需的依附元件。程式是以 C++ 語言編寫,必須先編譯為「二進位檔」,才能下載至主面板。二進位檔是包含程式的檔案,該形式可由 SparkFun Edge 硬體直接執行。

以下是適用於 Linux 或 MacOS 的操作說明。

下載 TensorFlow 存放區

您可以在 GitHub 的 TensorFlow 存放區中找到程式碼,位置如下:

https://github.com/tensorflow/tensorflow/tree/master/tensorflow/lite/micro

在電腦上開啟終端機,變更為您平常儲存程式設計專案的目錄,下載 TensorFlow 存放區,然後輸入建立的目錄,如下所示:

cd ~  # change into your home (or any other) directory
git clone --depth 1 https://github.com/tensorflow/tensorflow.git
cd tensorflow

下載 Python 依附元件

我們將使用 Python 3 準備二進位檔,並將二進位檔刷新到裝置上。Python 指令碼取決於可用的特定程式庫。執行下列指令來安裝這些依附元件:

pip3 install pycrypto pyserial --user

4. 建構及準備二進位檔

我們正在建構二進位檔,並執行指令準備將檔案下載到裝置上。

建構二進位檔

如要下載所有必要的依附元件並建立二進位檔,請執行下列指令:

make -f tensorflow/lite/micro/tools/make/Makefile TARGET=sparkfun_edge micro_speech_bin

如果建構成功,輸出內容的最後一行應如下所示:

arm-none-eabi-objcopy tensorflow/lite/micro/tools/make/gen/sparkfun_edge_cortex-m4/bin/micro_speech tensorflow/lite/micro/tools/make/gen/sparkfun_edge_cortex-m4/bin/micro_speech.bin -O binary

如要確認二進位檔已成功建立,請執行下列指令:

test -f \
tensorflow/lite/micro/tools/make/gen/sparkfun_edge_cortex-m4/bin/micro_speech.bin && \
 echo "Binary was successfully created" || echo "Binary is missing"

控制台應該會顯示 Binary was successfully created!如果您看到 Binary is missing,表示建構程序發生問題,需要偵錯。

準備二進位檔

二進位檔必須使用加密編譯金鑰簽署,才能部署至裝置。我們現在要執行一些指令來簽署二進位檔,以便將二進位檔下載至 SparkFun Edge。

輸入下列指令,設定可供開發使用的一些虛擬加密編譯金鑰:

cp tensorflow/lite/micro/tools/make/downloads/AmbiqSuite-Rel2.2.0/tools/apollo3_scripts/keys_info0.py tensorflow/lite/micro/tools/make/downloads/AmbiqSuite-Rel2.2.0/tools/apollo3_scripts/keys_info.py

接著執行下列指令,建立已簽署的二進位檔:

python3 tensorflow/lite/micro/tools/make/downloads/AmbiqSuite-Rel2.2.0/tools/apollo3_scripts/create_cust_image_blob.py \
--bin tensorflow/lite/micro/tools/make/gen/sparkfun_edge_cortex-m4/bin/micro_speech.bin \
--load-address 0xC000 \
--magic-num 0xCB \
-o main_nonsecure_ota \
--version 0x0

這會建立 main_nonsecure_ota.bin 檔案。現在我們會執行另一個指令來建立最終版本的檔案,讓您以系統啟動載入程式指令碼刷新裝置,我們將在下一個步驟中使用:

python3 tensorflow/lite/micro/tools/make/downloads/AmbiqSuite-Rel2.2.0/tools/apollo3_scripts/create_cust_wireupdate_blob.py \
--load-address 0x20000 \
--bin main_nonsecure_ota.bin \
-i 6 \
-o main_nonsecure_wire \
--options 0x1

現在執行指令的目錄中應有一個名為 main_nonsecure_wire.bin 的檔案。我們將刷新到裝置上的檔案。

5. 準備好刷新二進位檔

什麼是閃爍?

SparkFun Edge 會將目前執行的程式儲存在 512 KB 快閃記憶體中。如果您希望 Jamboard 執行新程式,我們必須將新程式傳送到主面板,其中會儲存至快閃記憶體中,並覆寫先前儲存的任何程式。

這項程序稱為「刷新」,我們會用它將程式送到董事會上。

將程式設計師固定到 Jamboard 上

將使用 SparkFun USB-C 系列基本序列程式設計師下載新程式到 Jamboard 上。這部裝置允許您的電腦透過 USB 與微控制器通訊。

如要將這部裝置連接至 Jamboard,請按照下列步驟操作:

  1. 找出 SparkFun Edge 側邊的六個圖釘標頭。
  2. 將 SparkFun USB-C 序列基本插頭插入這些接腳,確保標示「BLK」的針腳和「GRN」並確認各個裝置的排列順序均正確無誤

b140822f0019f92a.png

將程式設計師連接至電腦

我們將透過 USB 將主機板連接到電腦。如要編寫主機板,我們需要知道電腦為裝置提供的名稱。最佳做法是列出這部電腦在連接前後的所有裝置,然後看看哪一部是新裝置。

透過 USB 連接裝置前,請執行下列指令:

If you are using Linux: ls /dev/tty*
If you are using MacOS: ls /dev/cu*

這會輸出已連接的裝置清單,如下所示:

/dev/cu.Bluetooth-Incoming-Port
/dev/cu.MALS
/dev/cu.SOC

接著,將程式設計師連接到電腦的 USB 連接埠。再次輸入下列指令:

If you are using Linux: ls /dev/tty*
If you are using MacOS: ls /dev/cu*

輸出內容應會顯示一個額外項目,如下例所示。新項目的名稱可能有所不同。這個新項目是裝置名稱。

/dev/cu.Bluetooth-Incoming-Port
/dev/cu.MALS
/dev/cu.SOC
/dev/cu.wchusbserial-1450

首先,建立一個環境變數來識別裝置名稱:

export DEVICENAME=put your device name here

接下來,我們會建立環境變數來指定傳輸速率,也就是資料傳送到裝置的速度:

export BAUD_RATE=921600

6. 刷新二進位檔

執行指令碼來刷新白板

如要刷新遊戲板,必須放到特殊的「系統啟動載入程式」中狀態,準備好用來接收新的二進位檔我們會執行指令碼,將二進位檔傳送至主機板。

讓我們熟悉以下開發板上的按鈕:

64c620570b9d2f83.png

請按照下列步驟重設並刷新板:

  1. 確認主機板已接上程式設計師,且整個設定程序已透過 USB 連接至電腦。
  2. 開始:按住主機板上標示 14 的按鈕。直到步驟 6 為止。
  3. 仍在按住標示為 14 的按鈕,如要將遊戲板重設為系統啟動載入程式狀態,請按一下標示為 RST 的按鈕重設面板。
  4. 仍然按住標示 14 的按鈕,將下列指令貼到終端機中,然後按下 Enter 鍵執行 (為了方便起見,您可以先將這個指令貼到終端機,再開始按住按鈕,但在執行這個步驟之前,請勿按 Enter 鍵)
python3 tensorflow/lite/micro/tools/make/downloads/AmbiqSuite-Rel2.2.0/tools/apollo3_scripts/uart_wired_update.py -b ${BAUD_RATE} ${DEVICENAME} -r 1 -f main_nonsecure_wire.bin -i 6
  1. 仍在按住標示 14 的按鈕,畫面上現在應會顯示如下圖所示:
Connecting with Corvette over serial port /dev/cu.usbserial-1440...
Sending Hello.
Received response for Hello
Received Status
length =  0x58
version =  0x3
Max Storage =  0x4ffa0
Status =  0x2
State =  0x7
AMInfo =
0x1
0xff2da3ff
0x55fff
0x1
0x49f40003
0xffffffff
[...lots more 0xffffffff...]
Sending OTA Descriptor =  0xfe000
Sending Update Command.
number of updates needed =  1
Sending block of size  0x158b0  from  0x0  to  0x158b0
Sending Data Packet of length  8180
Sending Data Packet of length  8180
[...lots more Sending Data Packet of length  8180...]
  1. 在看到 Sending Data Packet of length 8180停止在白板上按住標示 14 的按鈕 (但按住這個按鈕也可以)。程式會繼續在終端機列印路線。最終看起來會像這樣:
[...lots more Sending Data Packet of length  8180...]
Sending Data Packet of length  8180
Sending Data Packet of length  6440
Sending Reset Command.
Done.

如果看到 Done,表示成功閃爍。如果程式輸出內容的結尾發生錯誤,請檢查是否已列印 Sending Reset Command。如果是的話,雖然發生錯誤,但刷卡可能成功。

在 Linux 電腦上,您可能會遇到 NoResponse Error。這是因為一併安裝 ch34x 序列驅動程式和現有序列驅動程式,可以按照以下方式解析:

步驟 1:重新安裝正確的 ch34x 程式庫版本。在安裝過程中,確保裝置從電腦拔除。

git clone https://github.com/juliagoda/CH341SER.git
cd CH341SER/
make
sudo insmod ch34x.ko
sudo rmmod ch341

步驟 2:將主機板 USB 插入並執行:

dmesg | grep "ch34x"

畫面上應會顯示類似下方的訊息:

[ 1299.444724]  ch34x_attach+0x1af/0x280 [ch34x]
[ 1299.445386] usb 2-13.1: ch34x converter now attached to ttyUSB0

如果使用的驅動程式不是「ch34x」(例如:ch341),請執行以下指令,停用其他驅動程式:

rmmod <non-ch34x driver name>

拔除並重新插上裝置,並確認使用的驅動程式為「ch34x」。

7. 展示模式

試用程式

成功閃爍白板後,按下標示為

RST 可重新啟動遊戲板並啟動程式。如果藍色 LED 燈開始閃爍,表示已成功閃爍。如果沒有,請向下捲動至下方的「如果失敗時該怎麼辦?」部分。

bf256d403a1821af.gif

開發板上的機器學習模型經過訓練,可辨識「是」字詞偵測和偵測結果是否存在這個模式會透過燈號閃爍的 LED 燈傳達測試結果。下表列出各個 LED 顏色的含義:

偵測結果

LED 顏色

「是」

黃色

「否」

紅色

不明語音

綠色

偵測不到語音

LED 燈未亮起

歡迎體驗

將白板舉到嘴巴上,然後說「好」數次你會看到黃色的 LED 閃光燈。說出「是」後,如果系統仍未回應,請嘗試下列做法:

  • 將遊戲板維持在約 10 英寸你的嘴巴
  • 避免背景噪音過多
  • 再說一次「是」連續幾次 (試著說「是,是」)

如果失敗會怎麼樣?

以下列舉幾個可能的問題和偵錯方式:

問題:閃爍後,LED 燈並未亮起。

解決方法:請嘗試按下 RST 按鈕,或中斷 Jamboard 與程式設計師的連線後再重新接上,如果以上方法都無效,請再次嘗試刷新遊戲板。

問題:藍色 LED 燈亮起,但非常昏暗。

解決方法:請在電量不足時更換電池。你也可以使用電腦內建的程式設計師和傳輸線為主機板開機。

8. 讀取偵錯輸出內容 (選用)

如果您遇到問題且需要詳細偵錯程式碼,請參閱本節說明。如要瞭解程式碼執行時微控制器內發生的情況,您可以透過主機板的序列連線顯示偵錯資訊。您可以使用電腦連線至 Jamboard,並顯示主面板傳送的資料。

開啟序列連線

根據預設,SparkFun Edge 程式碼範例會記錄所有語音指令和信心。如要查看 Jamboard 的輸出內容,您可以執行下列指令:

screen ${DEVICENAME} 115200

一開始,您可能會看到類似如下所示的輸出內容:(只有在連線板經過重設後,您才會開始看到偵錯資訊時,才會顯示這個輸出內容)

Apollo3 Burst Mode is Available

                               Apollo3 operating in Burst Mode (96MHz)

試著說出「是」來下達指令或「否」。您應該會看到各指令的主機板列印偵錯資訊:

 Heard yes (202) @65536ms

在上述記錄中,yes 是指指令。數字 202 是指偵測到指令的信賴水準 (下限為 200)。最後,65536ms 是指微控制器上次重設後經過的時間。

如要停止查看偵錯輸出內容,請點選 Ctrl+A,後面緊接著 K 鍵,然後按 Y 鍵。

寫入偵錯記錄檔

您可以在剛剛使用的 command_responseer.cc 檔案中,查看記錄此資訊的程式碼:

tensorflow/lite/micro/examples/micro_speech/sparkfun_edge/command_responder.cc

如要記錄資料,您可以呼叫 error_reporter->Report() 方法。支援使用標準 printf 符記插入字串,您可以在記錄中加入重要資訊:

error_reporter->Report("Heard %s (%d) @%dms", found_command, score, current_time);

當您在下一節中自行變更程式碼時,此方法非常實用。

9. 擴充程式碼 (選用)

現在您已經瞭解如何建構及刷新 SparkFun Edge,可以開始試用程式碼並將其部署至裝置來檢視結果。

讀取程式碼

下列檔案是開始讀取程式碼的絕佳位置:command_responder.cc.

tensorflow/lite/micro/examples/micro_speech/sparkfun_edge/command_responder.cc

您可以在這裡查看 GitHub 的檔案。

偵測到語音指令時,系統會呼叫這個檔案中的方法 RespondToCommand。系統會根據聽到的「是」、「否」或不明指令,開啟不同的 LED 燈。以下程式碼片段說明運作方式:

if (found_command[0] == 'y') {
  am_hal_gpio_output_set(AM_BSP_GPIO_LED_YELLOW);
}
if (found_command[0] == 'n') {
  am_hal_gpio_output_set(AM_BSP_GPIO_LED_RED);
}
if (found_command[0] == 'u') {
  am_hal_gpio_output_set(AM_BSP_GPIO_LED_GREEN);
}

found_command 引數包含偵測到的指令名稱。查看第一個字元時,這組 if 陳述式會決定哪個 LED 燈要亮起。

使用多個引數呼叫 ResponseToCommand 方法:

void RespondToCommand(tflite::ErrorReporter* error_reporter,
    int32_t current_time, const char* found_command,
    uint8_t score, bool is_new_command) {
  • error_reporter 是用來記錄偵錯資訊 (稍後會詳細說明)。
  • current_time 代表偵測到指令的時間。
  • found_command 會說明偵測到的指令。
  • score 能讓我們瞭解系統偵測到指令的信心程度。
  • 請問這是第一次聽到指令時,is_new_command 能通知我們。

score 是介於 0 到 255 之間的整數,代表偵測到指令的機率。範例程式碼只有在分數大於 200 時,才會將指令視為有效。根據我們的測試,最有效的命令在 200-210 之間。

修改程式碼

SparkFun Edge 遊戲板有四個 LED 燈。這是因為藍色的 LED 燈會閃爍,這表示裝置已開始辨識。您可以在 command_responder.cc 檔案中查看這項資訊:

static int count = 0;

// Toggle the blue LED every time an inference is performed.
++count;
if (count & 1) {
  am_hal_gpio_output_set(AM_BSP_GPIO_LED_BLUE);
} else {
  am_hal_gpio_output_clear(AM_BSP_GPIO_LED_BLUE);
}

我們的銀行有四個 LED 燈,因此要修改程式,將其做為指定指令 score 的視覺指標。如果分數較低,就會發出一個照明 LED 燈;如果高分,則會發出多個燈號。

為了確保我們能夠知道程式正在執行,我們會持續進行紅色的 LED 閃光燈,而非藍色。相鄰的藍色、綠色和黃色的 LED 燈將用於顯示最近 score 的強度。為了方便起見,只有在關鍵字「是」時,我們才會亮起 LED 燈語音。如果偵測到其他字詞,LED 燈就會清除。

如要進行這項變更,請將 command_responder.cc 檔案中的所有程式碼,替換成以下程式碼片段

#include "tensorflow/lite/micro/examples/micro_speech/command_responder.h"

#include "am_bsp.h"

// This implementation will light up the LEDs on the board in response to different commands.
void RespondToCommand(tflite::ErrorReporter* error_reporter,
                      int32_t current_time, const char* found_command,
                      uint8_t score, bool is_new_command) {
  static bool is_initialized = false;
  if (!is_initialized) {
    // Setup LEDs as outputs
    am_hal_gpio_pinconfig(AM_BSP_GPIO_LED_RED, g_AM_HAL_GPIO_OUTPUT_12);
    am_hal_gpio_pinconfig(AM_BSP_GPIO_LED_BLUE, g_AM_HAL_GPIO_OUTPUT_12);
    am_hal_gpio_pinconfig(AM_BSP_GPIO_LED_GREEN, g_AM_HAL_GPIO_OUTPUT_12);
    am_hal_gpio_pinconfig(AM_BSP_GPIO_LED_YELLOW, g_AM_HAL_GPIO_OUTPUT_12);
    // Ensure all pins are cleared
    am_hal_gpio_output_clear(AM_BSP_GPIO_LED_RED);
    am_hal_gpio_output_clear(AM_BSP_GPIO_LED_BLUE);
    am_hal_gpio_output_clear(AM_BSP_GPIO_LED_GREEN);
    am_hal_gpio_output_clear(AM_BSP_GPIO_LED_YELLOW);
    is_initialized = true;
  }
  static int count = 0;

   // Toggle the red LED every time an inference is performed.
   ++count;
   if (count & 1) {
     am_hal_gpio_output_set(AM_BSP_GPIO_LED_RED);
   } else {
     am_hal_gpio_output_clear(AM_BSP_GPIO_LED_RED);
   }

  if (is_new_command) {
    // Clear the last three LEDs
    am_hal_gpio_output_clear(AM_BSP_GPIO_LED_BLUE);
    am_hal_gpio_output_clear(AM_BSP_GPIO_LED_GREEN);
    am_hal_gpio_output_clear(AM_BSP_GPIO_LED_YELLOW);
    error_reporter->Report("Heard %s (%d) @%dms", found_command, score,
                           current_time);
    // Only indicate a 'yes'
    if (found_command[0] == 'y') {
      // Always light the blue LED
      am_hal_gpio_output_set(AM_BSP_GPIO_LED_BLUE);
      // Light the other LEDs depending on score
      if (score >= 205) {
        am_hal_gpio_output_set(AM_BSP_GPIO_LED_GREEN);
      }
      if(score >= 210) {
        am_hal_gpio_output_set(AM_BSP_GPIO_LED_YELLOW);
      }
    }
  }
}

如果偵測到新指令,is_new_command 的值為 true。請先清除藍色、綠色和黃色的 LED 燈,再根據 found_commandscore 的值再次亮起。

重建並刷新

變更程式碼後,請執行建構並準備二進位檔中的所有步驟來進行測試。

10. 後續步驟

恭喜,您已成功在微控制器上建構第一個語音偵測工具!

希望你喜歡這份簡短的簡介,瞭解如何使用 TensorFlow Lite for Microcontrollers 進行開發作業。在微控制器中,深度學習的構想是新點子,令人感到振奮,建議您去嘗試看看!

參考文件

  • 訓練自己的模型瞭解各種指令,您現在已有使用基本程式的經驗。注意:訓練作業需要幾個小時才能完成!
  • 進一步瞭解 TensorFlow Lite for Microcontrollers ( 網站GitHub)。
  • 請嘗試其他範例,並嘗試在 SparkFun Edge 上執行這些範例 (如果支援的話)。
  • 請參閱 O'Reilly 一書的《TinyML: Machine Learning with TensorFlow on Arduino and Ultra-Low Power Micro-Controllers》(TinyML:在 Arduino 和超低功率微控制器上運用機器學習的機器),這個單元會介紹機器學習,並逐步完成幾項有趣的專案。本程式碼研究室是以書籍第 7 章和第 8 章為基礎。

26699b18f2b199f.png

謝謝,祝一切順利!