電子發(fā)燒友App

硬聲App

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示
創(chuàng)作
電子發(fā)燒友網(wǎng)>電子資料下載>電子資料>手勢(shì)識(shí)別:用于8位微控制器的TinyML

手勢(shì)識(shí)別:用于8位微控制器的TinyML

2022-10-24 | zip | 0.14 MB | 次下載 | 2積分

資料介紹

描述

介紹

在這個(gè)項(xiàng)目中,我將展示一種開(kāi)始使用 TinyML 的簡(jiǎn)單方法:在Arduino板上實(shí)現(xiàn)機(jī)器學(xué)習(xí)模型,同時(shí)創(chuàng)建一些很酷的東西:基于加速度計(jì)的手勢(shì)識(shí)別系統(tǒng)。

為了使實(shí)驗(yàn)更簡(jiǎn)單,該系統(tǒng)設(shè)計(jì)為僅識(shí)別兩種手勢(shì):出拳彎曲動(dòng)作(在數(shù)據(jù)科學(xué)領(lǐng)域,二元分類(lèi))。

打孔手勢(shì)
?
彈性手勢(shì)
?

這個(gè)實(shí)驗(yàn)的最大挑戰(zhàn)是試圖在一個(gè)非常小的設(shè)備上運(yùn)行預(yù)測(cè)模型:一個(gè) 8 位微控制器。為此,您可以使用Neuton。

Neuton是一個(gè) TinyML 框架。它允許在沒(méi)有任何編碼和一點(diǎn)機(jī)器學(xué)習(xí)經(jīng)驗(yàn)的情況下自動(dòng)構(gòu)建神經(jīng)網(wǎng)絡(luò),并將它們嵌入到小型計(jì)算設(shè)備中。它支持8位16位32 位微控制器。

實(shí)驗(yàn)分為三個(gè)步驟:

  • 捕獲訓(xùn)練數(shù)據(jù)集
  • 使用Neuton訓(xùn)練模型
  • 在Arduino上部署和運(yùn)行模型
pYYBAGNVjNGATKr9AABDotfqIG831.jpeg
實(shí)驗(yàn)流程
?

設(shè)置

手勢(shì)識(shí)別系統(tǒng)由以下部分組成:

GY-521 由Arduino Mega 電源部分的5VGND引腳供電,而對(duì)于數(shù)據(jù)通信,則使用I2C引腳(引腳 20 和引腳 21)。其余引腳是可選的,對(duì)于此應(yīng)用無(wú)用。

要驗(yàn)證 GY-521 模塊是否正確供電,請(qǐng)連接Arduino板的 USB 電纜并檢查安裝在傳感器板上的 LED 是否亮起。

poYBAGNVjNOASddQAAApwMlVnLQ740.png
GY-521:LED位置
?

驗(yàn)證傳感器電源后,通過(guò)下載Adafruit MPU6050 Arduino 庫(kù)并打開(kāi)“繪圖儀”示例檢查I2C通信是否正常工作。

將示例草圖上傳到Arduino板上,打開(kāi)Tools菜單中的“ Serial Plotter ” ,在baud下拉菜單中設(shè)置115200 ,然后“搖動(dòng)”sensor板。預(yù)期結(jié)果如下:

MPU6050繪圖儀串口繪圖儀示例
?

現(xiàn)在,系統(tǒng)已準(zhǔn)備好收集加速度計(jì)和陀螺儀數(shù)據(jù)。

1. 捕獲訓(xùn)練數(shù)據(jù)

構(gòu)建預(yù)測(cè)模型的第一步是收集足夠的運(yùn)動(dòng)測(cè)量值。這組測(cè)量值稱(chēng)為訓(xùn)練數(shù)據(jù)集,它將用于訓(xùn)練Neuton神經(jīng)網(wǎng)絡(luò)構(gòu)建器。

實(shí)現(xiàn)這一點(diǎn)的最簡(jiǎn)單方法是通過(guò)捕獲加速度和陀螺儀測(cè)量并將結(jié)果存儲(chǔ)在文件中來(lái)重復(fù)多次相同的兩個(gè)動(dòng)作(沖壓彎曲)。為此,您創(chuàng)建一個(gè)專(zhuān)用于傳感器數(shù)據(jù)采集的Arduino草圖。該程序?qū)@取每個(gè)運(yùn)動(dòng)的測(cè)量值,并將在串行端口控制臺(tái)上打印傳感器測(cè)量值輸出。

您將執(zhí)行至少 60 個(gè)動(dòng)作:第一個(gè)動(dòng)作 ( punch ) 30 個(gè),第二個(gè)動(dòng)作 ( flex ) 30 個(gè)。對(duì)于每個(gè)動(dòng)作,您將在 1 秒的時(shí)間窗口內(nèi)獲得 50 個(gè)加速度和 50 個(gè)陀螺儀測(cè)量值(采樣時(shí)間:20ms —50Hz )。在這個(gè)實(shí)驗(yàn)中,60 個(gè)動(dòng)作就足夠了。通過(guò)增加運(yùn)動(dòng)測(cè)量的數(shù)量,您可以提高模型的預(yù)測(cè)能力。但是,大型數(shù)據(jù)集可能會(huì)導(dǎo)致模型過(guò)擬合。沒(méi)有“正確”的數(shù)據(jù)集大小,但建議采用“反復(fù)試驗(yàn)”的方法。

Arduino草圖的串行端口輸出將根據(jù)Neutontraining 數(shù)據(jù)集要求進(jìn)行格式化。

下面,用于創(chuàng)建數(shù)據(jù)集的Arduino程序:

  • IMU 傳感器初始化和 CSV 標(biāo)頭生成:
#define NUM_SAMPLES 50

Adafruit_MPU6050 mpu;

void setup() {
  // init serial port
  Serial.begin(115200);
  while (!Serial) {
    delay(10);
  }
  // init IMU sensor
  if (!mpu.begin()) {
    while (1) {
      delay(10);
    }
  }
  
  // configure IMU sensor
  // [...]

  // print the CSV header (ax0,ay0,az0,...,gx49,gy49,gz49,target)
  for (int i=0; i
    Serial.print("aX");
    Serial.print(i);
    Serial.print(",aY");
    Serial.print(i);
    Serial.print(",aZ");
    Serial.print(i);
    Serial.print(",gX");
    Serial.print(i);
    Serial.print(",gY");
    Serial.print(i);
    Serial.print(",gZ");
    Serial.print(i);
    Serial.print(",");
  }
  Serial.println("target");
}
  • 采集 30 個(gè)連續(xù)動(dòng)作。如果加速度總和高于某個(gè)閾值(例如,2.5 G ),則檢測(cè)到運(yùn)動(dòng)的開(kāi)始。
#define NUM_GESTURES    30
#define GESTURE_0       0
#define GESTURE_1       1
#define GESTURE_TARGET  GESTURE_0 
//#define GESTURE_TARGET  GESTURE_1

void loop() {
  sensors_event_t a, g, temp;
  
  while(gesturesRead < NUM_GESTURES) {
    // wait for significant motion
    while (samplesRead == NUM_SAMPLES) {
      // read the acceleration data
      mpu.getEvent(&a, &g, &temp);
      
      // sum up the absolutes
      float aSum = fabs(a.acceleration.x) + 
                   fabs(a.acceleration.y) + 
                   fabs(a.acceleration.z);
      
      // check if it's above the threshold
      if (aSum >= ACC_THRESHOLD) {
        // reset the sample read count
        samplesRead = 0;
        break;
      }
    }
  
    // read samples of the detected motion
    while (samplesRead < NUM_SAMPLES) {
        // read the acceleration and gyroscope data
        mpu.getEvent(&a, &g, &temp);
  
        samplesRead++;
  
        // print the sensor data in CSV format
        Serial.print(a.acceleration.x, 3);
        Serial.print(',');
        Serial.print(a.acceleration.y, 3);
        Serial.print(',');
        Serial.print(a.acceleration.z, 3);
        Serial.print(',');
        Serial.print(g.gyro.x, 3);
        Serial.print(',');
        Serial.print(g.gyro.y, 3);
        Serial.print(',');
        Serial.print(g.gyro.z, 3);
        Serial.print(',');
        
        // print target at the end of samples acquisition
        if (samplesRead == NUM_SAMPLES) {
          Serial.println(GESTURE_TARGET);
        }
        
        delay(10);
    }
    gesturesRead++;
  }
}

首先,在打開(kāi)串行監(jiān)視器并將GESTURE_TARGET設(shè)置為GESTURE_0的情況下運(yùn)行上述草圖。然后,將GESTURE_TARGET設(shè)置為GESTURE_1運(yùn)行。對(duì)于每次執(zhí)行,執(zhí)行相同的動(dòng)作 30 次,盡可能確保以相同的方式執(zhí)行動(dòng)作。

將兩個(gè)運(yùn)動(dòng)的串行監(jiān)視器輸出復(fù)制到一個(gè)文本文件中,并將其重命名為“trainingdata.txt”。.csv ”。

2. 使用 Neuton TinyML 訓(xùn)練模型

Neuton自動(dòng)執(zhí)行訓(xùn)練,無(wú)需任何用戶交互。使用Neuton訓(xùn)練神經(jīng)網(wǎng)絡(luò)既快速又簡(jiǎn)單,分為三個(gè)階段:

  • 數(shù)據(jù)集:上傳和驗(yàn)證
  • 培訓(xùn):自動(dòng)機(jī)器學(xué)習(xí)
  • 預(yù)測(cè):結(jié)果分析和模型下載

2.1。數(shù)據(jù)集:上傳和驗(yàn)證

  • 首先,創(chuàng)建一個(gè)新的Neuton解決方案并將其命名(例如Gesture Recognition )。
pYYBAGNVjNaAcDF1AADWvNnM2A0221.png
Neuton:添加新的解決方案
?
  • 上傳 CSV 訓(xùn)練數(shù)據(jù)集文件。
poYBAGNVjNiAcK1GAABg6RnmmUg979.png
Neuton:上傳 CSV 文件
?
  • Neuton根據(jù)數(shù)據(jù)集要求驗(yàn)證 CSV 文件。
pYYBAGNVjN2AJLHEAABgM5D3sd8219.png
Neuton:數(shù)據(jù)集驗(yàn)證
?
  • 如果 CSV 文件符合要求,將出現(xiàn)綠色對(duì)勾,否則將顯示錯(cuò)誤消息。
poYBAGNVjN-AD5rFAABlAok_RhU489.png
Neuton:經(jīng)過(guò)驗(yàn)證的數(shù)據(jù)集
?
  • 選擇目標(biāo)變量的列名(例如,目標(biāo)),然后單擊“下一步”。
pYYBAGNVjOKAAgurAABz2lu5Phg359.png
Neuton:目標(biāo)變量
?
poYBAGNVjOSARLEqAACcWwbcuaI248.png
Neuton:數(shù)據(jù)集內(nèi)容預(yù)覽
?

2.2. 培訓(xùn):汽車(chē)機(jī)器學(xué)習(xí)

現(xiàn)在,讓我們進(jìn)入訓(xùn)練的核心!

  • Neuton分析訓(xùn)練數(shù)據(jù)集的內(nèi)容并定義 ML 任務(wù)類(lèi)型。使用此數(shù)據(jù)集,可以自動(dòng)檢測(cè)二進(jìn)制分類(lèi)任務(wù)。
pYYBAGNVjOaACKUrAACI2X3A4nU755.png
Neuton:任務(wù)類(lèi)型
?
  • Metric用于在訓(xùn)練期間監(jiān)控和衡量模型的性能。對(duì)于此實(shí)驗(yàn),您使用準(zhǔn)確度指標(biāo):它表示預(yù)測(cè)類(lèi)別的準(zhǔn)確度。值越高,模型越好。
poYBAGNVjOmAFVm9AACHothjTzk802.png
Neuton:公制
?
  • 啟用TinyML選項(xiàng)以允許Neuton為微控制器構(gòu)建微型模型。
pYYBAGNVjOuANk8yAABkguol5Tc090.png
Neuton:TinyML 選項(xiàng)
?
  • 在 TinyML 設(shè)置頁(yè)面中,在下拉菜單中選擇“ 8-bit ”并啟用“ Float datatype support”選項(xiàng)。這是因?yàn)閷?shí)驗(yàn)中使用的微控制器是支持浮點(diǎn)數(shù)的 8 位 MCU。
poYBAGNVjO2APkH9AADFZuKdeTg326.png
Neuton:TinyML 設(shè)置
?
  • 按下“開(kāi)始訓(xùn)練”按鈕后,您將看到過(guò)程進(jìn)度條和完成百分比。
pYYBAGNVjO-AfMy4AACiGm1puDw143.png
Neuton:培訓(xùn)開(kāi)始
?
  • 第一步是數(shù)據(jù)預(yù)處理這是準(zhǔn)備(清理、組織、轉(zhuǎn)換等)原始數(shù)據(jù)集以使其適合訓(xùn)練和構(gòu)建 ML 模型的過(guò)程。
  • 數(shù)據(jù)預(yù)處理完成后,模型訓(xùn)練開(kāi)始。該過(guò)程可能需要很長(zhǎng)時(shí)間;您可以關(guān)閉窗口并在該過(guò)程完成后返回。在訓(xùn)練期間,您可以通過(guò)觀察模型狀態(tài)(“一致”或“不一致”)和目標(biāo)指標(biāo)來(lái)監(jiān)控實(shí)時(shí)模型性能。
poYBAGNVjPKAH1oBAADP6q4mOz4739.png
Neuton:數(shù)據(jù)預(yù)處理完成
?
  • 培訓(xùn)完成后,“狀態(tài)”將變?yōu)椤?/font>培訓(xùn)完成” 。模型是一致的并且已經(jīng)達(dá)到了最好的預(yù)測(cè)能力。
pYYBAGNVjPSAXmqAAACvROKnzAc380.png
Neuton:訓(xùn)練完成
?

2.3. 預(yù)測(cè):結(jié)果分析和模型下載

poYBAGNVjPeAAo0YAACoucN7HHg882.png
Neuton:訓(xùn)練完成
?

訓(xùn)練過(guò)程完成后,您將被重定向到?預(yù)測(cè)?部分。在本次實(shí)驗(yàn)中,模型的準(zhǔn)確率達(dá)到了98% 。這意味著從 100 條預(yù)測(cè)記錄中,有 98 條被分配到了正確的類(lèi)別……這令人印象深刻!

此外,要嵌入的模型大小小于3KB 。這是一個(gè)非常小的尺寸,考慮到使用的Arduino板的內(nèi)存大小為256KB ,而 8 位微控制器的典型內(nèi)存大小為64KB÷256KB 。

pYYBAGNVjPmAEXhxAACwgwhOv5o325.png
Neuton:指標(biāo)
?

要下載模型存檔,請(qǐng)單擊“下載”按鈕。

poYBAGNVjPyALXn3AADHV3a0cO4624.png
Neuton:預(yù)測(cè)選項(xiàng)卡
?

3.在Arduino上部署模型

從Neuton下載的模型存檔包括以下文件和文件夾:

  • /模型:緊湊形式(十六進(jìn)制和二進(jìn)制)的神經(jīng)網(wǎng)絡(luò)模型。
  • / neuton :一組用于執(zhí)行預(yù)測(cè)、計(jì)算、數(shù)據(jù)傳輸、結(jié)果管理等的函數(shù)。
  • user_app.c :一個(gè)文件,您可以在其中設(shè)置應(yīng)用程序的邏輯以管理預(yù)測(cè)。

首先,修改user_app.c文件,添加函數(shù)以初始化模型并運(yùn)行推理。

/*
 * Function: model_init
 * ----------------------------
 *
 *   returns: result of initialization (bool)
 */
uint8_t model_init() {
   uint8_t res;

   res = CalculatorInit(&neuralNet, NULL);

   return (ERR_NO_ERROR == res);
}

/*
 * Function: model_run_inference
 * ----------------------------
 *
 *   sample: input array to make prediction
 *   size_in: size of input array
 *   size_out: size of result array
 *
 *   returns: result of prediction
 */
float* model_run_inference(float* sample, 
                           uint32_t size_in, 
                           uint32_t *size_out) {
   if (!sample || !size_out)
      return NULL;
   if (size_in != neuralNet.inputsDim)
      return NULL;

   *size_out = neuralNet.outputsDim;

   return CalculatorRunInference(&neuralNet, sample);
}

之后,您創(chuàng)建user_app.h頭文件以允許主應(yīng)用程序使用用戶函數(shù)。

uint8_t model_init();
float*  model_run_inference(float* sample, 
                            uint32_t size_in, 
                            uint32_t* size_out);

下面是主要應(yīng)用程序的Arduino草圖:

  • 模型初始化
#include "src/Gesture Recognition_v1/user_app.h"

void setup() {
   // init serial port and IMU sensor
   // [...]
   
   // init Neuton neural network model
   if (!model_init()) {
      Serial.print("Failed to initialize Neuton model!");
      while (1) {
        delay(10);
      }
   }
}
  • 模型推斷
#define GESTURE_ARRAY_SIZE  (6*NUM_SAMPLES+1)

void loop() {
   sensors_event_t a, g, temp;
   float gestureArray[GESTURE_ARRAY_SIZE]  = {0};
   
   // wait for significant motion
   // [...]
   
   // read samples of the detected motion
   while (samplesRead < NUM_SAMPLES) {
      // read the acceleration and gyroscope data
      mpu.getEvent(&a, &g, &temp);
      
      // fill gesture array (model input)
      gestureArray[samplesRead*6 + 0] = a.acceleration.x;
      gestureArray[samplesRead*6 + 1] = a.acceleration.y;
      gestureArray[samplesRead*6 + 2] = a.acceleration.z;
      gestureArray[samplesRead*6 + 3] = g.gyro.x;
      gestureArray[samplesRead*6 + 4] = g.gyro.y;
      gestureArray[samplesRead*6 + 5] = g.gyro.z;
    
      samplesRead++;
    
      delay(10);
   
      // check the end of gesture acquisition
      if (samplesRead == NUM_SAMPLES) {
         uint32_t size_out = 0;
      
         // run model inference
         float* result = model_run_inference(gestureArray,  
                                             GESTURE_ARRAY_SIZE, 
                                             &size_out);
         // check if model inference result is valid
         if (result && size_out) {
            // check if problem is binary classification
            if (size_out >= 2) { 
               // check if one of the result has >50% of accuracy
               if (result[0] > 0.5) {
                  Serial.print("Detected gesture: 0"); 
                  // [...]
               } else if (result[1] > 0.5) {
                  Serial.print("Detected gesture: 1"); 
                  // [...]
               } else { 
                  // solution is not reliable
                  Serial.println("Detected gesture: NONE");
               } 
            }
         }
     }
   }
}

模型在行動(dòng)!

/neuton_gesturerecognition
 |- /src
 | |- /Gesture Recognition_v1
 |   |- /model
 |   |- /neuton
 |   |- user_app.c
 |   |- user_app.h
 |- neuton_gesturerecognition.ino

現(xiàn)在,是時(shí)候看看預(yù)測(cè)模型的實(shí)際應(yīng)用了!

  • 驗(yàn)證硬件系統(tǒng)是否正確設(shè)置
  • 打開(kāi)主應(yīng)用程序文件
  • 單擊“驗(yàn)證”按鈕,然后單擊“上傳”一個(gè)
  • 打開(kāi)串行監(jiān)視器
  • 抓住你的硬件系統(tǒng)并執(zhí)行一些動(dòng)作。

對(duì)于每個(gè)檢測(cè)到的運(yùn)動(dòng),模型將嘗試猜測(cè)運(yùn)動(dòng)是什么類(lèi)型(0 -punch或 1 -flex )以及預(yù)測(cè)的準(zhǔn)確度。如果預(yù)測(cè)的準(zhǔn)確度較低(0.5 ),則模型不會(huì)做出決定。

下面是模型推理執(zhí)行的示例:

pYYBAGNVjP6AbGqKAAE05uN1yiY311.png
Neuton 手勢(shì)識(shí)別系統(tǒng)的串口監(jiān)視器輸出
?

而且..僅此而已!


下載該資料的人也在下載 下載該資料的人還在閱讀
更多 >

評(píng)論

查看更多

下載排行

本周

  1. 1使用單片機(jī)實(shí)現(xiàn)七人表決器的程序和仿真資料免費(fèi)下載
  2. 2.96 MB   |  44次下載  |  免費(fèi)
  3. 2聯(lián)想E46L DAOLL6筆記本電腦圖紙
  4. 1.10 MB   |  2次下載  |  5 積分
  5. 3MATLAB繪圖合集
  6. 27.12 MB   |  2次下載  |  5 積分
  7. 4PR735,使用UCC28060的600W交錯(cuò)式PFC轉(zhuǎn)換器
  8. 540.03KB   |  1次下載  |  免費(fèi)
  9. 5UCC38C42 30W同步降壓轉(zhuǎn)換器參考設(shè)計(jì)
  10. 428.07KB   |  1次下載  |  免費(fèi)
  11. 6DV2004S1/ES1/HS1快速充電開(kāi)發(fā)系統(tǒng)
  12. 2.08MB   |  1次下載  |  免費(fèi)
  13. 7模態(tài)分解合集matlab代碼
  14. 3.03 MB   |  1次下載  |  2 積分
  15. 8美的電磁爐維修手冊(cè)大全
  16. 1.56 MB   |  1次下載  |  5 積分

本月

  1. 1使用單片機(jī)實(shí)現(xiàn)七人表決器的程序和仿真資料免費(fèi)下載
  2. 2.96 MB   |  44次下載  |  免費(fèi)
  3. 2UC3842/3/4/5電源管理芯片中文手冊(cè)
  4. 1.75 MB   |  15次下載  |  免費(fèi)
  5. 3DMT0660數(shù)字萬(wàn)用表產(chǎn)品說(shuō)明書(shū)
  6. 0.70 MB   |  13次下載  |  免費(fèi)
  7. 4TPS54202H降壓轉(zhuǎn)換器評(píng)估模塊用戶指南
  8. 1.02MB   |  8次下載  |  免費(fèi)
  9. 5STM32F101x8/STM32F101xB手冊(cè)
  10. 1.69 MB   |  8次下載  |  1 積分
  11. 6HY12P65/HY12P66數(shù)字萬(wàn)用表芯片規(guī)格書(shū)
  12. 0.69 MB   |  6次下載  |  免費(fèi)
  13. 7華瑞昇CR216芯片數(shù)字萬(wàn)用表規(guī)格書(shū)附原理圖及校正流程方法
  14. 0.74 MB   |  6次下載  |  3 積分
  15. 8華瑞昇CR215芯片數(shù)字萬(wàn)用表原理圖
  16. 0.21 MB   |  5次下載  |  3 積分

總榜

  1. 1matlab軟件下載入口
  2. 未知  |  935119次下載  |  10 積分
  3. 2開(kāi)源硬件-PMP21529.1-4 開(kāi)關(guān)降壓/升壓雙向直流/直流轉(zhuǎn)換器 PCB layout 設(shè)計(jì)
  4. 1.48MB  |  420061次下載  |  10 積分
  5. 3Altium DXP2002下載入口
  6. 未知  |  233084次下載  |  10 積分
  7. 4電路仿真軟件multisim 10.0免費(fèi)下載
  8. 340992  |  191367次下載  |  10 積分
  9. 5十天學(xué)會(huì)AVR單片機(jī)與C語(yǔ)言視頻教程 下載
  10. 158M  |  183335次下載  |  10 積分
  11. 6labview8.5下載
  12. 未知  |  81581次下載  |  10 積分
  13. 7Keil工具M(jìn)DK-Arm免費(fèi)下載
  14. 0.02 MB  |  73807次下載  |  10 積分
  15. 8LabVIEW 8.6下載
  16. 未知  |  65987次下載  |  10 積分