با میکروکنترلرها شروع کنید

این سند نحوه آموزش مدل و اجرای استنباط با استفاده از میکروکنترلر را توضیح می دهد.

نمونه سلام جهانی

سلام جهان به عنوان مثال طراحی شده است برای نشان دادن اصول ساده با استفاده از TensorFlow Lite برای میکروکنترلرها. ما به آموزش و اجرای یک مدل است که تکرار یک تابع سینوسی، به عنوان مثال، آن طول می کشد یک عدد به عنوان ورودی آن، و خروجی اعداد سینوسی ارزش. هنگامی که در میکروکنترلر مستقر می شود ، پیش بینی های آن برای چشمک زدن LED ها یا کنترل یک انیمیشن استفاده می شود.

گردش کار پایان به پایان شامل مراحل زیر است:

  1. آموزش یک مدل (در پایتون): یک نوت بوک jupyter به قطار، تبدیل و بهینه سازی یک مدل برای استفاده در دستگاه.
  2. استنتاج اجرا (در C ++ 11): یک تست واحد پایان به پایان است که قابل اجرا بر روی مدل استنباط با استفاده از کتابخانه C ++ .

دستگاه پشتیبانی شده را دریافت کنید

نمونه برنامه ای که از آن استفاده خواهیم کرد در دستگاه های زیر آزمایش شده است:

اطلاعات بیشتر در مورد سیستم عامل های پشتیبانی در TensorFlow Lite برای میکروکنترلرها .

یک مدل آموزش دهید

استفاده از گوگل Colaboratory به آموزش مدل خود را . برای جزئیات بیشتر، به مراجعه README.md :

سلام آموزش جهانی README.md

استنباط را اجرا کنید

برای اجرای مدل بر روی دستگاه شما، ما را از طریق دستورالعمل راه رفتن README.md :

سلام به جهان README.md

بخش های زیر از طریق مثال راه رفتن hello_world_test.cc آزمون، واحد که نشان می دهد که چگونه به اجرا استنتاج با استفاده از TensorFlow Lite برای میکروکنترلرها. این مدل را بارگیری می کند و استنباط را چندین بار اجرا می کند.

1. عناوین کتابخانه را وارد کنید

برای استفاده از کتابخانه TensorFlow Lite برای میکروکنترلرها ، باید فایل های هدر زیر را داشته باشیم:

#include "tensorflow/lite/micro/all_ops_resolver.h"
#include "tensorflow/lite/micro/micro_error_reporter.h"
#include "tensorflow/lite/micro/micro_interpreter.h"
#include "tensorflow/lite/schema/schema_generated.h"
#include "tensorflow/lite/version.h"
  • all_ops_resolver.h عملیات استفاده شده توسط مترجم برای اجرای مدل فراهم می کند.
  • micro_error_reporter.h خروجی اطلاعات اشکال زدایی.
  • micro_interpreter.h شامل کد به بار و مدل اجرا می شود.
  • schema_generated.h شامل طرح برای TensorFlow بازگشت به محتوا | FlatBuffer فرمت فایل مدل.
  • version.h اطلاعات نسخه برای شمای TensorFlow مطلب فراهم می کند.

2. سربرگ مدل را وارد کنید

مفسر TensorFlow Lite برای میکروکنترلرها انتظار دارد مدل به صورت آرایه C ++ ارائه شود. این مدل در تعریف model.h و model.cc فایل های. عنوان با خط زیر گنجانده شده است:

#include "tensorflow/lite/micro/examples/hello_world/model.h"

3. سربرگ چارچوب آزمون واحد را وارد کنید

برای ایجاد یک تست واحد ، ما شامل چارچوب آزمون واحد TensorFlow Lite برای میکروکنترلرها با اضافه کردن خط زیر هستیم:

#include "tensorflow/lite/micro/testing/micro_test.h"

آزمون با استفاده از ماکروهای زیر تعریف شده است:

TF_LITE_MICRO_TESTS_BEGIN

TF_LITE_MICRO_TEST(LoadModelAndPerformInference) {
  . // add code here
  .
}

TF_LITE_MICRO_TESTS_END

اکنون ما درباره کد موجود در ماکرو بالا بحث می کنیم.

4. ورود به سیستم را تنظیم کنید

برای تنظیم ورود به سیستم، یک tflite::ErrorReporter اشاره گر با استفاده از یک اشاره گر به یک ایجاد شده است tflite::MicroErrorReporter به عنوان مثال:

tflite::MicroErrorReporter micro_error_reporter;
tflite::ErrorReporter* error_reporter = &micro_error_reporter;

این متغیر به مفسر منتقل می شود ، که به آن امکان می دهد سیاهههای مربوط را بنویسد. از آنجا که میکروکنترلرها اغلب از انواع مکانیسم برای ورود به سیستم، اجرای tflite::MicroErrorReporter طراحی شده است که برای دستگاه های خاص خود سفارشی شود.

5. یک مدل را بارگیری کنید

در کد زیر، مدل با استفاده از داده ها از یک نمونه است char آرایه، g_model است، که در اعلام model.h . سپس مدل را بررسی می کنیم تا مطمئن شویم نسخه طرح آن با نسخه مورد استفاده ما سازگار است:

const tflite::Model* model = ::tflite::GetModel(g_model);
if (model->version() != TFLITE_SCHEMA_VERSION) {
  TF_LITE_REPORT_ERROR(error_reporter,
      "Model provided is schema version %d not equal "
      "to supported version %d.\n",
      model->version(), TFLITE_SCHEMA_VERSION);
}

6. حل و فصل عملیات

AllOpsResolver عنوان مثال اعلام شده است. مفسر از این برای دستیابی به عملیاتی که توسط مدل استفاده می شود استفاده خواهد کرد:

tflite::AllOpsResolver resolver;

AllOpsResolver بارهای تمام عملیات موجود در TensorFlow Lite برای میکروکنترلرها، که با استفاده از یک مقدار زیادی از حافظه. از آنجا که در یک مدل داده شده فقط از زیر مجموعه این عملیات استفاده می شود ، توصیه می شود برنامه های دنیای واقعی فقط عملیات مورد نیاز را بارگیری کنند.

این کار با استفاده کلاس های مختلف، انجام MicroMutableOpResolver . شما می توانید ببینید که چگونه به استفاده از آن در مثال سخنرانی میکرو micro_speech_test.cc .

7. حافظه را تخصیص دهید

ما باید مقدار مشخصی از حافظه را برای آرایه های ورودی ، خروجی و میانی اختصاص دهیم. این به عنوان یک ارائه uint8_t مجموعه ای از اندازه tensor_arena_size :

const int tensor_arena_size = 2 * 1024;
uint8_t tensor_arena[tensor_arena_size];

اندازه مورد نیاز به مدلی که استفاده می کنید بستگی دارد و ممکن است لازم باشد با آزمایش تعیین شود.

8. مترجم فوری

ما ایجاد یک tflite::MicroInterpreter عنوان مثال، عبور در متغیرهای پیش از این ساخته:

tflite::MicroInterpreter interpreter(model, resolver, tensor_arena,
                                     tensor_arena_size, error_reporter);

9. تانسورها را اختصاص دهید

ما در مترجم برای تخصیص حافظه از tensor_arena برای تانسورها مدل:

interpreter.AllocateTensors();

10. اعتبارسنجی شکل ورودی

MicroInterpreter عنوان مثال می توانید ما را با یک اشاره گر به تانسور ورودی مدل با تماس با ارائه .input(0) ، که در آن 0 نشان دهنده اولین (و تنها) ورودی تانسور:

  // Obtain a pointer to the model's input tensor
  TfLiteTensor* input = interpreter.input(0);

سپس این تانسور را بازرسی می کنیم تا تأیید کنیم شکل و نوع آن چیزی است که انتظار داریم:

// Make sure the input has the properties we expect
TF_LITE_MICRO_EXPECT_NE(nullptr, input);
// The property "dims" tells us the tensor's shape. It has one element for
// each dimension. Our input is a 2D tensor containing 1 element, so "dims"
// should have size 2.
TF_LITE_MICRO_EXPECT_EQ(2, input->dims->size);
// The value of each element gives the length of the corresponding tensor.
// We should expect two single element tensors (one is contained within the
// other).
TF_LITE_MICRO_EXPECT_EQ(1, input->dims->data[0]);
TF_LITE_MICRO_EXPECT_EQ(1, input->dims->data[1]);
// The input is a 32 bit floating point value
TF_LITE_MICRO_EXPECT_EQ(kTfLiteFloat32, input->type);

ارزش شمارشی kTfLiteFloat32 اشاره به یکی از انواع داده TensorFlow Lite است، و در تعریف common.h .

11. مقدار ورودی را ارائه دهید

برای تهیه ورودی به مدل ، محتویات سنسور ورودی را به صورت زیر تنظیم می کنیم:

input->data.f[0] = 0.;

در این مورد، ما یک ورودی مقدار نقطه به نمایندگی شناور 0 .

12. مدل را اجرا کنید

برای اجرای این مدل، ما می توانیم پاسخ Invoke() در ما tflite::MicroInterpreter به عنوان مثال:

TfLiteStatus invoke_status = interpreter.Invoke();
if (invoke_status != kTfLiteOk) {
  TF_LITE_REPORT_ERROR(error_reporter, "Invoke failed\n");
}

ما می توانیم مقدار بازگشتی، یک بررسی TfLiteStatus ، برای تعیین اینکه آیا اجرای موفقیت آمیز بود. مقادیر ممکن TfLiteStatus ، تعریف شده در common.h ، می kTfLiteOk و kTfLiteError .

کد زیر را بیان می کند که ارزش است kTfLiteOk ، به این معنی استنتاج با موفقیت اجرا شد.

TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, invoke_status);

13. خروجی را بدست آورید

تانسور خروجی مدل می تواند با تماس به دست آمده output(0) در tflite::MicroInterpreter ، که در آن 0 نشان دهنده اولین (و تنها) خروجی تانسور.

در مثال ، خروجی مدل یک مقدار واحد شناور است که در یک سنسور 2D موجود است:

TfLiteTensor* output = interpreter.output(0);
TF_LITE_MICRO_EXPECT_EQ(2, output->dims->size);
TF_LITE_MICRO_EXPECT_EQ(1, input->dims->data[0]);
TF_LITE_MICRO_EXPECT_EQ(1, input->dims->data[1]);
TF_LITE_MICRO_EXPECT_EQ(kTfLiteFloat32, output->type);

ما می توانیم مقدار را مستقیماً از سنسور خروجی بخوانیم و ادعا کنیم که همان چیزی است که انتظار داریم:

// Obtain the output value from the tensor
float value = output->data.f[0];
// Check that the output value is within 0.05 of the expected value
TF_LITE_MICRO_EXPECT_NEAR(0., value, 0.05);

14. دوباره استنباط را اجرا کنید

باقیمانده کد چندین بار دیگر نتیجه گیری می کند. در هر نمونه ، مقداری را به سنسور ورودی اختصاص می دهیم ، مفسر را فراخوانی می کنیم و نتیجه را از سنسور خروجی می خوانیم:

input->data.f[0] = 1.;
interpreter.Invoke();
value = output->data.f[0];
TF_LITE_MICRO_EXPECT_NEAR(0.841, value, 0.05);

input->data.f[0] = 3.;
interpreter.Invoke();
value = output->data.f[0];
TF_LITE_MICRO_EXPECT_NEAR(0.141, value, 0.05);

input->data.f[0] = 5.;
interpreter.Invoke();
value = output->data.f[0];
TF_LITE_MICRO_EXPECT_NEAR(-0.959, value, 0.05);

15. کد برنامه را بخوانید

هنگامی که شما از طریق این واحد آزمون راه می رفت، شما باید قادر به درک کد برنامه به عنوان مثال، واقع در شود main_functions.cc . این فرایند مشابهی را دنبال می کند ، اما بر اساس تعداد استنباط انجام شده مقدار ورودی ایجاد می کند و عملکردی خاص دستگاه را فراخوانی می کند که خروجی مدل را به کاربر نشان می دهد.