資料介紹
描述
介紹
手勢(shì)分類是機(jī)器學(xué)習(xí)可以做的一個(gè)簡(jiǎn)單但同時(shí)也是很好的例子。它使用大量“雜亂”的數(shù)據(jù)對(duì)事物進(jìn)行分類。
在這個(gè)項(xiàng)目中,我們將制作一個(gè)有 4 個(gè)類的分類器,idle、up_down、left_right 和 circle。該項(xiàng)目將使用Esp32 板(8 美元)制作,因?yàn)榕c使用Arduino Nano 33 BLE Sense (35 美元)的“經(jīng)典”示例相比,它非常便宜。
數(shù)據(jù)采集
要將數(shù)據(jù)上傳到 Edge Impulse,我們需要使用 Edge Impulse CLI,按照本教程了解如何安裝它。
我們要使用的工具是Data Forwarder ,該工具將串行中可用的數(shù)據(jù)上傳到 Edge Impulse。我們需要使用 Arduino Sketch 以一定的采樣頻率將數(shù)據(jù)上傳到串行,并用“,”分隔數(shù)據(jù),在這種情況下,我們將發(fā)送加速度數(shù)據(jù)。
#include
#include
#include
#define FREQUENCY_HZ 60
#define INTERVAL_MS (1000 / (FREQUENCY_HZ + 1))
// objeto da classe Adafruit_MPU6050
Adafruit_MPU6050 mpu;
static unsigned long last_interval_ms = 0;
void setup() {
Serial.begin(115200);
Serial.println("Classificador de gestos com TinyML");
// Try to initialize!
if (!mpu.begin()) {
Serial.println("Failed to find MPU6050 chip");
while (1) {
delay(10);
}
}
Serial.println("MPU6050 Found!");
mpu.setAccelerometerRange(MPU6050_RANGE_8_G);
Serial.print("Accelerometer range set to: ");
switch (mpu.getAccelerometerRange()) {
case MPU6050_RANGE_2_G:
Serial.println("+-2G");
break;
case MPU6050_RANGE_4_G:
Serial.println("+-4G");
break;
case MPU6050_RANGE_8_G:
Serial.println("+-8G");
break;
case MPU6050_RANGE_16_G:
Serial.println("+-16G");
break;
}
mpu.setGyroRange(MPU6050_RANGE_500_DEG);
Serial.print("Gyro range set to: ");
switch (mpu.getGyroRange()) {
case MPU6050_RANGE_250_DEG:
Serial.println("+- 250 deg/s");
break;
case MPU6050_RANGE_500_DEG:
Serial.println("+- 500 deg/s");
break;
case MPU6050_RANGE_1000_DEG:
Serial.println("+- 1000 deg/s");
break;
case MPU6050_RANGE_2000_DEG:
Serial.println("+- 2000 deg/s");
break;
}
mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);
Serial.print("Filter bandwidth set to: ");
switch (mpu.getFilterBandwidth()) {
case MPU6050_BAND_260_HZ:
Serial.println("260 Hz");
break;
case MPU6050_BAND_184_HZ:
Serial.println("184 Hz");
break;
case MPU6050_BAND_94_HZ:
Serial.println("94 Hz");
break;
case MPU6050_BAND_44_HZ:
Serial.println("44 Hz");
break;
case MPU6050_BAND_21_HZ:
Serial.println("21 Hz");
break;
case MPU6050_BAND_10_HZ:
Serial.println("10 Hz");
break;
case MPU6050_BAND_5_HZ:
Serial.println("5 Hz");
break;
}
Serial.println("");
delay(100);
}
void loop() {
sensors_event_t a, g, temp;
if (millis() > last_interval_ms + INTERVAL_MS) {
last_interval_ms = millis();
mpu.getEvent(&a, &g, &temp);
Serial.print(a.acceleration.x);
Serial.print(",");
Serial.print(a.acceleration.y);
Serial.print(",");
Serial.println(a.acceleration.z);
}
}
在 Esp32 板準(zhǔn)備好發(fā)送數(shù)據(jù)后,我們需要將 Edge Impulse 帳戶與 CLI 連接起來,它應(yīng)該是這樣的:
- 了解這種方法的局限性很重要,例如,我們不能用它來上傳音頻數(shù)據(jù),因?yàn)椴蓸宇l率應(yīng)該至少是信號(hào)最大頻率的兩倍(奈奎斯特采樣定理),我們可以不要使用串行以如此高的頻率傳輸數(shù)據(jù)。
之后你可以開始收集一些數(shù)據(jù),你可以做很多動(dòng)作,只要確保它們不太相似(稍后你可以在特征瀏覽器中決定)。
設(shè)計(jì)沖動(dòng)
脈沖是一組采集、處理和推理數(shù)據(jù)。
頻譜分析為 Keras 模型創(chuàng)建了要使用的特征,在這個(gè)階段,信號(hào)被過濾并生成兩個(gè)頻譜,一個(gè)是頻率(使用 FFT),另一個(gè)是能量(PSD )
我們可以使用特征資源管理器看到我們的類是如何分離的:
它們看起來非常不同,所以我們應(yīng)該用模型得到一個(gè)很好的結(jié)果。
這些數(shù)據(jù)進(jìn)入神經(jīng)網(wǎng)絡(luò),因?yàn)檫@是一項(xiàng)簡(jiǎn)單的任務(wù),神經(jīng)網(wǎng)絡(luò)也應(yīng)該很簡(jiǎn)單。
在我們訓(xùn)練模型之后,我們可以在混淆矩陣中看到性能:
它看起來不錯(cuò),但性能可能會(huì)隨著測(cè)試數(shù)據(jù)而降低。
對(duì)模型感到滿意后,您可以使用 de Arduino IDE 和 Edge Impulse 中生成的庫(kù)將其嵌入。
就像 Arduino 中的另一個(gè)庫(kù)一樣,我們需要包含它并使用它們的函數(shù)進(jìn)行推理。
#include
#include
#include
#include
#define FREQUENCY_HZ 60
#define INTERVAL_MS (1000 / (FREQUENCY_HZ + 1))
#define RED 16
#define GREEN 17
#define BLUE 18
// objeto da classe Adafruit_MPU6050
Adafruit_MPU6050 mpu;
float features[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE];
size_t feature_ix = 0;
static unsigned long last_interval_ms = 0;
void setup() {
Serial.begin(115200);
ledcSetup(0, 5000, 8);
/*
ledcAttachPin(RED, 0);
ledcAttachPin(GREEN, 1);
ledcAttachPin(BLUE, 2);
*/
pinMode(RED, OUTPUT);
pinMode(GREEN, OUTPUT);
pinMode(BLUE, OUTPUT);
if (!mpu.begin()) {
Serial.println("Failed to find MPU6050 chip");
while (1) {
delay(10);
}
}
Serial.println("MPU6050 Found!");
mpu.setAccelerometerRange(MPU6050_RANGE_8_G);
Serial.print("Accelerometer range set to: ");
switch (mpu.getAccelerometerRange()) {
case MPU6050_RANGE_2_G:
Serial.println("+-2G");
break;
case MPU6050_RANGE_4_G:
Serial.println("+-4G");
break;
case MPU6050_RANGE_8_G:
Serial.println("+-8G");
break;
case MPU6050_RANGE_16_G:
Serial.println("+-16G");
break;
}
mpu.setGyroRange(MPU6050_RANGE_500_DEG);
Serial.print("Gyro range set to: ");
switch (mpu.getGyroRange()) {
case MPU6050_RANGE_250_DEG:
Serial.println("+- 250 deg/s");
break;
case MPU6050_RANGE_500_DEG:
Serial.println("+- 500 deg/s");
break;
case MPU6050_RANGE_1000_DEG:
Serial.println("+- 1000 deg/s");
break;
case MPU6050_RANGE_2000_DEG:
Serial.println("+- 2000 deg/s");
break;
}
mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);
Serial.print("Filter bandwidth set to: ");
switch (mpu.getFilterBandwidth()) {
case MPU6050_BAND_260_HZ:
Serial.println("260 Hz");
break;
case MPU6050_BAND_184_HZ:
Serial.println("184 Hz");
break;
case MPU6050_BAND_94_HZ:
Serial.println("94 Hz");
break;
case MPU6050_BAND_44_HZ:
Serial.println("44 Hz");
break;
case MPU6050_BAND_21_HZ:
Serial.println("21 Hz");
break;
case MPU6050_BAND_10_HZ:
Serial.println("10 Hz");
break;
case MPU6050_BAND_5_HZ:
Serial.println("5 Hz");
break;
}
Serial.println("");
delay(100);
Serial.print("Features: ");
Serial.println(EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE);
Serial.print("Label count: ");
Serial.println(EI_CLASSIFIER_LABEL_COUNT);
}
void loop() {
sensors_event_t a, g, temp;
if (millis() > last_interval_ms + INTERVAL_MS) {
last_interval_ms = millis();
mpu.getEvent(&a, &g, &temp);
features[feature_ix++] = a.acceleration.x;
features[feature_ix++] = a.acceleration.y;
features[feature_ix++] = a.acceleration.z;
if (feature_ix == EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE) {
Serial.println("Running the inference...");
signal_t signal;
ei_impulse_result_t result;
int err = numpy::signal_from_buffer(features, EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE, &signal);
if (err != 0) {
ei_printf("Failed to create signal from buffer (%d)\n", err);
return;
}
EI_IMPULSE_ERROR res = run_classifier(&signal, &result, true);
if (res != 0) return;
ei_printf("Predictions ");
ei_printf("(DSP: %d ms., Classification: %d ms.)",
result.timing.dsp, result.timing.classification);
ei_printf(": \n");
for (size_t ix = 0; ix < EI_CLASSIFIER_LABEL_COUNT; ix++) {
ei_printf(" %s: %.5f\n", result.classification[ix].label, result.classification[ix].value);
if (result.classification[ix].value > 0.6) {
if (result.classification[ix].label == "up_down")
{
/*// color code #00C9CC (R = 0, G = 201, B = 204)
//analogWrite(RED, 0);
ledcWrite(0, 0);
//analogWrite(GREEN, 201);
ledcWrite(1, 201);
//analogWrite(BLUE, 204);
ledcWrite(2, 204);
Serial.println("up and down");*/
digitalWrite(RED, HIGH);
digitalWrite(GREEN, LOW);
digitalWrite(BLUE, LOW);
} else if (result.classification[ix].label == "left_right")
{
digitalWrite(RED, LOW);
digitalWrite(GREEN, HIGH);
digitalWrite(BLUE, LOW);
} else if (result.classification[ix].label == "circle")
{
digitalWrite(RED, LOW);
digitalWrite(GREEN, LOW);
digitalWrite(BLUE, HIGH);
} else
{
digitalWrite(RED, LOW);
digitalWrite(GREEN, LOW);
digitalWrite(BLUE, LOW);
}
}
}
feature_ix = 0;
}
}
}
void ei_printf(const char *format, ...) {
static char print_buf[1024] = { 0 };
va_list args;
va_start(args, format);
int r = vsnprintf(print_buf, sizeof(print_buf), format, args);
va_end(args);
if (r > 0) {
Serial.write(print_buf);
}
}
在這個(gè)應(yīng)用程序中,我使用 RGB LED 來顯示檢測(cè)到的類,您也可以在串行監(jiān)視器中看到。
?
- ESP32到ESP32通過Internet進(jìn)行通信
- TinyML:ESP32 CAM和TFT上的實(shí)時(shí)圖像分類
- 樂鑫ESP32-MINI-1參考設(shè)計(jì)
- 樂鑫ESP32-MINI-1U參考設(shè)計(jì)
- 樂鑫ESP32-SenseKit參考設(shè)計(jì)
- 樂鑫ESP32-WROOM-32UE參考設(shè)計(jì)
- 樂鑫ESP32-DevKitS-V1.1參考設(shè)計(jì)
- 樂鑫ESP32-PICO-MINI-02參考設(shè)計(jì)
- 樂鑫ESP32-LyraTD-SYNA_用戶手冊(cè)
- 樂鑫ESP32-PICO-MINI-02U參考設(shè)計(jì)
- 樂鑫ESP32-MeshKit-Light_使用指南
- esp32-s3_datasheet
- ESP32 SDIO 使用教程
- esp32s下載電路原理圖下載 27次下載
- 使用ESP32-CAM板訪問網(wǎng)絡(luò) 43次下載
- ESP32能取代STM32嗎?哪個(gè)更好? 2383次閱讀
- 淺析ESP32運(yùn)行MQTT客戶端進(jìn)行主題的發(fā)布和訂閱的方法 2752次閱讀
- 基于ESP32-S3的高性能開發(fā)板介紹 8718次閱讀
- ESP32-C3 WIFI的工作模式 4478次閱讀
- 什么是ESP32-CAM攝像頭? 2.1w次閱讀
- 基于ESP32的簡(jiǎn)易web服務(wù)器設(shè)計(jì) 3305次閱讀
- 基于ESP32-CAM的RSTP協(xié)議的網(wǎng)絡(luò)攝像頭 3150次閱讀
- 使用ESP32連接騰訊云實(shí)現(xiàn)遠(yuǎn)程控制 3240次閱讀
- 使用ESP32實(shí)現(xiàn)UDP通信的方法 5727次閱讀
- ESP32使用MiroPython編程環(huán)境搭建 2690次閱讀
- 基于ESP32制造有趣的超級(jí)馬里奧主題時(shí)鐘 4021次閱讀
- ESP8266/ESP32自動(dòng)下載原理 4249次閱讀
- 基于ESP-WROOM-32E專為IoT設(shè)計(jì)的FireBeetle ESP32-E主控板介紹 4608次閱讀
- ESP32的數(shù)字遙測(cè)實(shí)現(xiàn) 1521次閱讀
- dfrobotBeetle-ESP32控制器簡(jiǎn)介 2695次閱讀
下載排行
本周
- 1山景DSP芯片AP8248A2數(shù)據(jù)手冊(cè)
- 1.06 MB | 532次下載 | 免費(fèi)
- 2RK3399完整板原理圖(支持平板,盒子VR)
- 3.28 MB | 339次下載 | 免費(fèi)
- 3TC358743XBG評(píng)估板參考手冊(cè)
- 1.36 MB | 330次下載 | 免費(fèi)
- 4DFM軟件使用教程
- 0.84 MB | 295次下載 | 免費(fèi)
- 5元宇宙深度解析—未來的未來-風(fēng)口還是泡沫
- 6.40 MB | 227次下載 | 免費(fèi)
- 6迪文DGUS開發(fā)指南
- 31.67 MB | 194次下載 | 免費(fèi)
- 7元宇宙底層硬件系列報(bào)告
- 13.42 MB | 182次下載 | 免費(fèi)
- 8FP5207XR-G1中文應(yīng)用手冊(cè)
- 1.09 MB | 178次下載 | 免費(fèi)
本月
- 1OrCAD10.5下載OrCAD10.5中文版軟件
- 0.00 MB | 234315次下載 | 免費(fèi)
- 2555集成電路應(yīng)用800例(新編版)
- 0.00 MB | 33566次下載 | 免費(fèi)
- 3接口電路圖大全
- 未知 | 30323次下載 | 免費(fèi)
- 4開關(guān)電源設(shè)計(jì)實(shí)例指南
- 未知 | 21549次下載 | 免費(fèi)
- 5電氣工程師手冊(cè)免費(fèi)下載(新編第二版pdf電子書)
- 0.00 MB | 15349次下載 | 免費(fèi)
- 6數(shù)字電路基礎(chǔ)pdf(下載)
- 未知 | 13750次下載 | 免費(fèi)
- 7電子制作實(shí)例集錦 下載
- 未知 | 8113次下載 | 免費(fèi)
- 8《LED驅(qū)動(dòng)電路設(shè)計(jì)》 溫德爾著
- 0.00 MB | 6656次下載 | 免費(fèi)
總榜
- 1matlab軟件下載入口
- 未知 | 935054次下載 | 免費(fèi)
- 2protel99se軟件下載(可英文版轉(zhuǎn)中文版)
- 78.1 MB | 537798次下載 | 免費(fèi)
- 3MATLAB 7.1 下載 (含軟件介紹)
- 未知 | 420027次下載 | 免費(fèi)
- 4OrCAD10.5下載OrCAD10.5中文版軟件
- 0.00 MB | 234315次下載 | 免費(fèi)
- 5Altium DXP2002下載入口
- 未知 | 233046次下載 | 免費(fèi)
- 6電路仿真軟件multisim 10.0免費(fèi)下載
- 340992 | 191187次下載 | 免費(fèi)
- 7十天學(xué)會(huì)AVR單片機(jī)與C語(yǔ)言視頻教程 下載
- 158M | 183279次下載 | 免費(fèi)
- 8proe5.0野火版下載(中文版免費(fèi)下載)
- 未知 | 138040次下載 | 免費(fèi)
評(píng)論
查看更多