यह दस्तावेज़ बताता है कि माइक्रोकंट्रोलर.
नमस्ते दुनिया का उदाहरण
कॉन्टेंट बनाने सभी को नमस्ते उदाहरण को LiteRT का इस्तेमाल करने की बुनियादी बातों को दिखाने के लिए डिज़ाइन किया गया है का इस्तेमाल किया जा सकता है. हम साइन फ़ंक्शन को कॉपी करने वाले मॉडल को ट्रेनिंग देते हैं, इसका मतलब है कि यह इनपुट के तौर पर किसी एक संख्या को लेता है और आउटपुट के तौर पर किसी संख्या को sine मान से तय होता है. डिप्लॉय किए जाने पर, इसके अलावा, इसके अनुमान का इस्तेमाल एलईडी लाइट को ब्लिंक करने या ऐनिमेशन.
शुरू से आखिर तक वर्कफ़्लो में ये चरण शामिल होते हैं:
- किसी मॉडल को ट्रेनिंग देना (Python में): ट्रेनिंग देने, फ़ॉर्मैट बदलने के लिए Python फ़ाइल साथ ही, मॉडल को डिवाइस पर इस्तेमाल करने के लिए ऑप्टिमाइज़ किया जा सके.
- रन अनुमान (C++ 17 में): यह एंड-टू-एंड यूनिट टेस्ट है, जो C++ लाइब्रेरी का इस्तेमाल करके, मॉडल पर अनुमान लगाता है.
एक समर्थित डिवाइस पाएं
हम जिस ऐप्लिकेशन का इस्तेमाल करेंगे, उसकी जांच इन डिवाइसों पर की जा चुकी है:
- आर्दूइनो नैनो 33 BLE Sense (Arduino IDE का इस्तेमाल करके)
- SparkFun Edge (सीधे तौर पर बनाना) स्रोत से)
- STM32F746 डिस्कवरी किट (Mbed का इस्तेमाल करके)
- Adafruit EdgeBadge (Arduino का इस्तेमाल किया जा रहा है आईडीई)
- माइक्रोकंट्रोलर्स किट के लिए Adafruit LiteRT (Arduino IDE का इस्तेमाल करके)
- ऐडफ़्रूट सर्किट प्लेग्राउंड ब्लूफ़्रूट (Arduino IDE का इस्तेमाल करके)
- Espressif ESP32-DevKitC (ईएसपी आईडीएफ़ का इस्तेमाल करके)
- एस्प्रेसिफ़ ईएसपी-ईवाईई (ईएसपी आईडीएफ़ का इस्तेमाल करके)
इस सुविधा के साथ काम करने वाले प्लैटफ़ॉर्म के बारे में ज़्यादा जानने के लिए, यहां जाएं माइक्रोकंट्रोलर के लिए LiteRT.
मॉडल को ट्रेनिंग दें
इस्तेमाल की जाने वाली चीज़ें train.py साइनवेव रिकग्निशन के लिए हैलो वर्ल्ड मॉडल ट्रेनिंग के लिए
दौड़ें: bazel build tensorflow/lite/micro/examples/hello_world:train
bazel-bin/tensorflow/lite/micro/examples/hello_world/train --save_tf_model
--save_dir=/tmp/model_created/
रन का अनुमान
मॉडल को अपने डिवाइस पर चलाने के लिए, हम
README.md
:
नीचे दिए सेक्शन में, उदाहरण के तौर पर
evaluate_test.cc
,
यूनिट टेस्ट की मदद से यह पता चलता है कि LiteRT का इस्तेमाल करके, अनुमान कैसे लगाया जाता है
माइक्रोकंट्रोलर. यह मॉडल को लोड करता है और कई बार अनुमान लगाता है.
1. लाइब्रेरी हेडर शामिल करना
माइक्रोकंट्रोलर्स की लाइब्रेरी के लिए LiteRT का इस्तेमाल करने के लिए, हमें हेडर फ़ाइलें नीचे दी गई हैं:
#include "tensorflow/lite/micro/micro_mutable_op_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"
micro_mutable_op_resolver.h
मॉडल को चलाने के लिए, इंटरप्रेटर की ओर से इस्तेमाल की जाने वाली कार्रवाइयां उपलब्ध कराता है.micro_error_reporter.h
डीबग की जानकारी देता है.micro_interpreter.h
मॉडल लोड करने और चलाने के लिए कोड शामिल है.schema_generated.h
इसमें LiteRT के लिए स्कीमा मौजूद हैFlatBuffer
मॉडल फ़ाइल फ़ॉर्मैट.version.h
LiteRT स्कीमा के लिए वर्शन की जानकारी देता है.
2. मॉडल हेडर शामिल करना
माइक्रोकंट्रोलर्स के लिए तय की गई LiteRT की मदद से, यह मॉडल
C++ कलेक्शन के तौर पर दिया जाएगा. मॉडल की जानकारी model.h
और model.cc
फ़ाइलों में दी गई है.
हेडर को इस लाइन में शामिल किया जाता है:
#include "tensorflow/lite/micro/examples/hello_world/model.h"
3. यूनिट टेस्ट फ़्रेमवर्क हेडर शामिल करना
यूनिट टेस्ट करने के लिए, हम LiteRT को नीचे दी गई लाइन को शामिल करके, माइक्रोकंट्रोलर्स यूनिट टेस्ट फ़्रेमवर्क:
#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 = µ_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. ऑपरेशन रिज़ॉल्वर को तुरंत चालू करें
ऐप्लिकेशन
MicroMutableOpResolver
इंस्टेंस तय नहीं किया गया है. अनुवादक इसे रजिस्टर करने के लिए इस्तेमाल करेगा और
उन कार्रवाइयों को ऐक्सेस करें जिनका इस्तेमाल मॉडल में किया गया है:
using HelloWorldOpResolver = tflite::MicroMutableOpResolver<1>;
TfLiteStatus RegisterOps(HelloWorldOpResolver& op_resolver) {
TF_LITE_ENSURE_STATUS(op_resolver.AddFullyConnected());
return kTfLiteOk;
MicroMutableOpResolver
के लिए, संख्या बताने वाला टेंप्लेट पैरामीटर होना ज़रूरी है
जिन्हें रजिस्टर किया जाएगा. RegisterOps
फ़ंक्शन, ऑपरेशन को रजिस्टर करता है
रिज़ॉल्वर के साथ काम करता है.
HelloWorldOpResolver op_resolver;
TF_LITE_ENSURE_STATUS(RegisterOps(op_resolver));
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
, LiteRT में से किसी एक का रेफ़रंस है
है और इसकी जानकारी इसमें दी गई है
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);