Bu belgede, bir modelin nasıl eğitileceği ve kontrol edebilirsiniz.
Hello World örneği
İlgili içeriği oluşturmak için kullanılan Hello World örneği, LiteRT kullanmanın mutlak temellerini göstermek için tasarlanmıştır kontrol edebilirsiniz. Sinüs fonksiyonunu çoğaltan bir model eğitiyor ve çalıştırıyoruz, Örneğin, giriş olarak tek bir sayı alır ve ilgili sayının çıktısını verir. sinüs değerine ayarlayın. içerdiği tahminler, LED'leri yakıp söndürmek veya bir cihazı kontrol etmek için kullanılır. animasyon ekler.
Uçtan uca iş akışı aşağıdaki adımları içerir:
- Model eğitme (Python'da): Eğitmek, dönüştürmek için bir python dosyası ve bir modeli cihazda kullanım için optimize edebilirsiniz.
- Çıkarım yapma (C++ 17'de): Benzersiz bir çözüm oluşturan uçtan uca C++ kitaplığını kullanarak model üzerinde çıkarım çalıştırır.
Desteklenen bir cihaz edinin
Kullanacağımız örnek uygulama aşağıdaki cihazlarda test edilmiştir:
- Arduino Nano 33 BLE Sense (Arduino IDE kullanılarak)
- SparkFun Edge (doğrudan bina kaynaktan)
- STM32F746 Keşif Kiti (Mbed kullanılıyor)
- Adafruit EdgeBadge (Arduino kullanarak) IDE)
- Mikrodenetleyiciler için Adafruit LiteRT Kiti (Arduino IDE kullanılarak)
- Adafruit Circuit Playground Bluefruit (Arduino IDE kullanılarak)
- Espressif ESP32-DevKitC (ESP IDF kullanılarak)
- Espressif: ESP-EYE (ESP IDF kullanılarak)
Desteklenen platformlar hakkında daha fazla bilgiyi şurada bulabilirsiniz: Mikrodenetleyiciler için LiteRT.
Model eğitin
Tekliflerinizi otomatikleştirmek ve optimize etmek için train.py sinwave tanıma için hello dünya modeli eğitimine yönelik
Çalıştırma: 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/
Çıkarım yap
Modeli cihazınızda çalıştırmak için
README.md
:
Aşağıdaki bölümlerde bu örnekte
evaluate_test.cc
için LiteRT kullanarak çıkarım
yapıldığını gösteren birim testi
Mikrodenetleyiciler Modeli yükler ve çıkarımı birkaç kez çalıştırır.
1. Kitaplık başlıklarını dahil et
Mikrodenetleyiciler için LiteRT kitaplığını kullanmak istiyorsanız şu başlık dosyalarını kullanabilirsiniz:
#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
modeli çalıştırmak için yorumlayıcı tarafından kullanılan işlemleri sağlar.micro_error_reporter.h
hata ayıklama bilgileri verir.micro_interpreter.h
modelleri yüklemek ve çalıştırmak için kod içerir.schema_generated.h
LiteRT şemasını içerirFlatBuffer
model dosya biçimi.version.h
LiteRT şeması için sürüm oluşturma bilgileri sağlar.
2. Model başlığını dahil et
Mikrodenetleyiciler için LiteRT yorumlayıcısı, modelin
C++ dizisi olarak sağlanır. Model, model.h
ve model.cc
dosyalarında tanımlanmıştır.
Üstbilgi, aşağıdaki satırla birlikte eklenir:
#include "tensorflow/lite/micro/examples/hello_world/model.h"
3. Birim testi çerçevesi başlığını dahil et
Birim testi oluşturmak için her bir birim için LiteRT'i Mikrodenetleyiciler birim test çerçevesi için aşağıdaki satırı ekleyin:
#include "tensorflow/lite/micro/testing/micro_test.h"
Test aşağıdaki makrolar kullanılarak tanımlanır:
TF_LITE_MICRO_TESTS_BEGIN
TF_LITE_MICRO_TEST(LoadModelAndPerformInference) {
. // add code here
.
}
TF_LITE_MICRO_TESTS_END
Şimdi, yukarıdaki makroda yer alan kodu ele alacağız.
4. Günlük kaydını ayarlama
Günlük kaydını ayarlamak için işaretçi kullanılarak bir tflite::ErrorReporter
işaretçisi oluşturulur.
tflite::MicroErrorReporter
örneğine ekleme:
tflite::MicroErrorReporter micro_error_reporter;
tflite::ErrorReporter* error_reporter = µ_error_reporter;
Bu değişken, yorumcuya iletilerek yazmasına olanak tanır
günlükler. Mikrodenetleyiciler genellikle günlük kaydı için çeşitli mekanizmalara sahip olduğundan,
tflite::MicroErrorReporter
uygulaması, dönüşüm hunisinin üst kısmındaki
emin olmanız gerekir.
5. Model yükleme
Aşağıdaki kodda model, bir char
dizisindeki veriler kullanılarak örneklendirilir.
g_model
, model.h
dilinde tanımlanır. Daha sonra modeli kontrol ederek
kullandığımız sürümle uyumlu olduğunu varsayalım:
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. İşlem çözümleyicisini örneklendirme
CEVAP
MicroMutableOpResolver
olduğunu varsayalım. Bu bilgi, çevirmen tarafından kayıt ve
model tarafından kullanılan işlemlere erişin:
using HelloWorldOpResolver = tflite::MicroMutableOpResolver<1>;
TfLiteStatus RegisterOps(HelloWorldOpResolver& op_resolver) {
TF_LITE_ENSURE_STATUS(op_resolver.AddFullyConnected());
return kTfLiteOk;
MicroMutableOpResolver
, değeri belirten bir şablon parametresi gerektirir
pek çok işlem vardır. RegisterOps
işlevi, işlemleri kaydeder
çözmek için kullanılabilmesidir.
HelloWorldOpResolver op_resolver;
TF_LITE_ENSURE_STATUS(RegisterOps(op_resolver));
7. Bellek ayır
Belli bir miktarda bellek miktarını
giriş, çıkış ve kontrol için önceden ayırmamız gerekiyor.
emin olmaktır. Bu, uint8_t
boyut dizisi olarak sağlanır
tensor_arena_size
:
const int tensor_arena_size = 2 * 1024;
uint8_t tensor_arena[tensor_arena_size];
Gereken boyut, kullandığınız modele bağlıdır ve denemeyle belirlenir.
8. Çevirmen gösterme
Değişkenleri ileten bir tflite::MicroInterpreter
örneği oluştururuz
daha önce oluşturulan:
tflite::MicroInterpreter interpreter(model, resolver, tensor_arena,
tensor_arena_size, error_reporter);
9. Tensör ayırma
Çevirmene, tensor_arena
cihazından bellek ayırmasını söyleriz.
modelin tensörleri:
interpreter.AllocateTensors();
10. Giriş şeklini doğrula
MicroInterpreter
örneği, modelin temel durumunu göstermek için
.input(0)
çağrısıyla giriş tensörü; burada 0
, ilk (ve tek) değeri temsil eder
giriş tensörü:
// Obtain a pointer to the model's input tensor
TfLiteTensor* input = interpreter.input(0);
Ardından, şeklinin ve türünün neye benzediğini göstermek için bu tensörü inceleriz. beklenen:
// 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
numaralandırma değeri, LiteRT'lerden birine referans
ve aşağıdaki koşullarda tanımlanmıştır:
common.h
11. Giriş değeri girin
Modele bir giriş sağlamak için giriş tensörünün içeriğini şu şekilde ayarlarız: şöyle olur:
input->data.f[0] = 0.;
Bu örnekte, 0
değerini temsil eden bir kayan nokta değeri giriyoruz.
12. Modeli çalıştırma
Modeli çalıştırmak için tflite::MicroInterpreter
numaralı telefondan Invoke()
adlı kuruluşu arayabiliriz
örnek:
TfLiteStatus invoke_status = interpreter.Invoke();
if (invoke_status != kTfLiteOk) {
TF_LITE_REPORT_ERROR(error_reporter, "Invoke failed\n");
}
Çalıştırmanın başarılı olup olmadığını belirlemek için TfLiteStatus
döndürme değerini kontrol edebiliriz.
işidir. Şurada tanımlanan olası TfLiteStatus
değerleri:
common.h
,
kTfLiteOk
ve kTfLiteError
.
Aşağıdaki kod, değerin kTfLiteOk
olduğunu doğrular. Çıkarım,
yardımcı olabilir.
TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, invoke_status);
13. Çıktı alma
Modelin çıkış tensörü,output(0)
0
burada ilk (ve tek) çıkışı temsil eder. tflite::MicroInterpreter
tensördür.
Örnekte, modelin çıkışı, hedef değerde 2D tensör içinde:
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);
Değeri doğrudan çıkış tensöründen okuyabilir ve bunun, kendisinde beklentilerimiz:
// 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. Çıkarımı tekrar çalıştır
Kodun geri kalanı çıkarımı birkaç kez daha çalıştırır. Her örnekte giriş tensörüne bir değer atar, yorumlayıcıyı çağırır ve şu çıkış tensöründen elde edilir:
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);