هذه المقالة عبارة عن مقتطف من كتابي TinyML Cookbook, Second Edition. يمكنك العثور على الكود المستخدم في المقالة هنا.
التحضير
التطبيق الذي سنصممه في هذه المقالة يهدف إلى تسجيل مقطع صوتي مستمر بمدة 1 ثانية وتشغيل استدلال النموذج، كما هو موضح في الصورة التالية:
الشكل 1: عمليات التسجيل والمعالجة التوالية
من خط الوقت لتنفيذ المهام الموضح في الصورة السابقة، يمكنك ملاحظة أن استخراج الميزات واستدلال النموذج دائمًا يتم بعد تسجيل الصوت وليس بشكل متزامن. ومن ثم، من الواضح أننا لا نعالج بعض أجزاء التيار الصوتي الحي.
على عكس تطبيق الكشف الفوري عن الكلمات المفتاحية (KWS)، الذي يجب أن يلتقط ويعالج جميع قطع التيار الصوتي لعدم تعرضه لأي كلمة منطوقة، هنا، يمكننا تخفيف هذا المتطلب لأنه لا يهدد فعالية التطبيق.
كما نعلم، إدخال استخراج ميزات MFCCs هو الصوت الأولي لمدة 1 ثانية في تنسيق Q15. ومع ذلك، العينات التي يتم الحصول عليها بواسطة الميكروفون ممثلة بقيم عدد صحيح 16 بت. ومن ثم، كيف نحول القيم العدد الصحيح 16 بت إلى Q15؟ الحل أبسط مما قد تظن: لا داعي لتحويل عينات الصوت.
لفهم ذلك، فكر في تنسيق Q15 الثابت للنقطة. يمكن لهذا التنسيق تمثيل القيم العائمة داخل النطاق [-1, 1]. التحويل من النقطة العائمة إلى Q15 يتضمن ضرب القيم العائمة في 32,768 (2^15). ومع ذلك، نظرًا لأن تمثيل النقطة العائمة ينشأ من قسمة نموذج العدد صحيح 16 بت على 32,768 (2^15)، فهذا يعني أن قيم العدد الصحيح 16 بت متمثلة بطبيعتها في تنسيق Q15.
كيفية القيام بذلك…
خذ اللوحة النارية مع الميكروفون المرتبط بـ Raspberry Pi Pico. قم بفصل كابل البيانات عن الميكروكنترولر، وأزل الزر الضغط والسلاسل المرتبطة به من اللوحة النارية، حيث لا تلزم لهذه الوصفة. الشكل 2 يوضح ما يجب أن يكون على اللوحة النارية:
الشكل 2: الدائرة الإلكترونية المبنية على اللوحة النارية
بعد إزالة الزر الضغط من اللوحة النارية، افتح برنامج Arduino IDE وأنشئ إطار عملٍ جديد.
الآن، اتبع الخطوات التالية لتطوير تطبيق التعرف على صنف الموسيقى على Raspberry Pi Pico:
الخطوة 1
قم بتنزيل مكتبة Arduino TensorFlow Lite من مستودع GitHub TinyML-Cookbook_2E
المستودع.
بعد تنزيل ملف ZIP، استيراده إلى IDE Arduino.
الخطوة 2
استيراد جميع ملفات الرأس C المولدة المطلوبة لخوارزمية إستخراج ميزات MFCCs في IDE Arduino، مع استثناء test_src.h
و test_dst.h
.
الخطوة 3
انسخ الرسم البياني الذي تم تطويره في الفصل 6، نشر خوارزمية إستخراج ميزات MFCCs على Raspberry Pi Pico لتنفيذ خوارزمية إستخراج ميزات MFCCs، مع استثناء الوظائف setup()
و loop()
.
أزل ادراج ملفات الرأس test_src.h
و test_dst.h
. ثم، أزل تخصيص المصفوفة dst، حيث سيتم تخزين MFCCs مباشرة في مدخلات النموذج.
الخطوة 4
انسخ الرسم البياني الذي تم تطويره في الفصل 5، التعرف على أساليب الموسيقى باستخدام TensorFlow و Raspberry Pi Pico – الجزء 1، لتسجيل عينات الصوت باستخدام الميكروفون، مع استثناء الوظائف setup()
و loop()
.
بمجرد استيراد الكود، أزل أي إشارة إلى المصباح الضوئي والزر، حيث لم يعد هناك حاجة لهما. ثم، قم بتغيير تعريف AUDIO_LENGTH_SEC
لتسجيل الصوت لمدة 1 ثانية:
#define AUDIO_LENGTH_SEC 1
الخطوة 5
استيراد ملف الرأس الذي يحتوي على نموذج TensorFlow Lite (model.h
) إلى مشروع Arduino.
بمجرد استيراد الملف، أدرج ملف الرأس model.h
في الرسم البياني:
#include "model.h"
يشمل الملفات الرأسية الضرورية لـ tflite-micro:
#include
#include
#include
#include
#include
#include
الخطوة 6
تعريف المتغيرات العالمية لنموذج tflite-micro والمحلل:
const tflite::Model* tflu_model = nullptr;
tflite::MicroInterpreter* tflu_interpreter = nullptr;
ثم، قم بتعريف كائنات TensorFlow Lite tensor (TfLiteTensor
) للوصول إلى الموديل المدخلات والمخرجات:
TfLiteTensor* tflu_i_tensor = nullptr;
TfLiteTensor* tflu_o_tensor = nullptr;
الخطوة 7
تعريف مخزن (حلقة الموديل) لتخزين الموديل المتوسطة المستخدمة في تنفيذ النموذج:
constexpr int tensor_arena_size = 16384;
uint8_t tensor_arena[tensor_arena_size] __attribute__((aligned(16)));
تم تحديد حجم حلقة الموديل من خلال الاختبار التجريبي، حيث يختلف الذاكرة اللازمة للموديل المتوسطة بناءً على كيفية تنفيذ عامل LSTM تحتها. أظهرت تجاربنا على Raspberry Pi Pico أن النموذج يتطلب فقط 16 كيلو بايت من ذاكرة الوصول العشوائي للاستدلال.
الخطوة 8
في دالة setup()
، قم بتهيئة الهدف التسلسلي بمعدل 115200
باود:
Serial.begin(115200);
while (!Serial);
سيتم استخدام الهدف التسلسلي لبث الصنف المعترف به من الموسيقى عبر الاتصال التسلسلي.
الخطوة 9
في دالة setup()
، قم بتحميل نموذج TensorFlow Lite المخزن في ملف رأسي model.h
:
tflu_model = tflite::GetModel(model_tflite);
ثم، تسجيل جميع عمليات DNN المدعومة من قبل tflite-micro، وتهيئة تفسير tflite-micro:
tflite::AllOpsResolver tflu_ops_resolver;
static tflite::MicroInterpreter static_interpreter(
tflu_model,
tflu_ops_resolver,
tensor_arena,
tensor_arena_size);
tflu_interpreter = &static_interpreter;
الخطوة 10
في الدالة setup()
، تخصيص الذاكرة اللازمة للنموذج، والحصول على مؤشر الذاكرة للموترات المدخلة والمخرجة:
tflu_interpreter->AllocateTensors();
tflu_i_tensor = tflu_interpreter->input(0);
tflu_o_tensor = tflu_interpreter->output(0);
الخطوة 11
في الدالة setup()
، استخدام برنامج تطوير Raspberry Pi Pico لتهيئة وحدة ADC:
adc_init();
adc_gpio_init(26);
adc_select_input(0);
الخطوة 12
في دالة loop()
، إعداد مدخلات النموذج. للقيام بذلك، تسجيل مقطع صوتي لمدة 1 ثانية:
// إعادة تعيين مخزن الصوت
buffer.cur_idx = 0;
buffer.is_ready = false;
constexpr uint32_t sr_us = 1000000 / SAMPLE_RATE;
timer.attach_us(&timer_ISR, sr_us);
while(!buffer.is_ready);
timer.detach();
بعد تسجيل الصوت، استخراج MFCCs:
mfccs.run((const q15_t*)&buffer.data[0],
(float *)&tflu_i_tensor->data.f[0]);
كما ترون من مقتطف الكود السابق، سيتم تخزين MFCCs مباشرة في مدخلات النموذج.
الخطوة 13
تشغيل استدعاء النموذج وإرجاع نتيجة التصنيف عبر الاتصال التسلسلي:
tflu_interpreter->Invoke();
size_t ix_max = 0;
float pb_max = 0;
for (size_t ix = 0; ix < 3; ix++) {
if(tflu_o_tensor->data.f[ix] > pb_max) {
ix_max = ix;
pb_max = tflu_o_tensor->data.f[ix];
}
}
const char *label[] = {"disco", "jazz", "metal"};
Serial.println(label[ix_max]);
الآن، قم بتوصيل سلك البيانات micro-USB بـ Raspberry Pi Pico. بمجرد توصيله، قم بالتجميع وتحميل الرسم البياني على المتحكم.
بعد ذلك، فتح مراقب التسلسل في محرر Arduino IDE ووضع هاتفك الذكي بالقرب من الميكروفون لتشغيل أغنية ديسكو، چاز أو ميتال. يجب أن يتعرف التطبيق الآن على نوعية الموسيقى للأغنية وعرض نتيجة التصنيف في مراقب التسلسل!
الخاتمة
في هذا المقال، تعلمت كيفية عملية توضيح نموذج مدرب لتصنيف أسلوب الموسيقى على Raspberry Pi Pico باستخدام tflite-micro.
Source:
https://dzone.com/articles/recognizing-music-genres-with-the-raspberry-pi-pic