TensorFlow Lite çıkarımı

Terimi, çıkarım giriş verilerine dayanarak tahminler yapmak için cihaz üzerinde bir TensorFlow Lite modeli yürütme işlemi belirtir. Bir TensorFlow Lite modeliyle bir çıkarım gerçekleştirmek için, bir tercüman aracılığıyla çalıştırmak zorundadır. TensorFlow Lite yorumlayıcı, yalın ve hızlı olacak şekilde tasarlanmıştır. Yorumlayıcı, minimum yük, başlatma ve yürütme gecikmesi sağlamak için statik bir grafik sıralaması ve özel (daha az dinamik) bir bellek ayırıcı kullanır.

Bu sayfa nasıl TensorFlow Lite tercüman erişmek için açıklanır ve her biri için diğer kaynaklara C ++, Java, ve Python artı bağlantıları kullanarak bir çıkarım yapmak desteklenen bir platform .

Önemli kavramlar

TensorFlow Lite çıkarımı tipik olarak aşağıdaki adımları takip eder:

  1. Model yükleme

    Sen yüklemek gerekir .tflite modelin yürütme grafiği içeren belleğe modeli.

  2. Verileri dönüştürme

    Model için ham girdi verileri genellikle model tarafından beklenen girdi verisi biçimiyle eşleşmez. Örneğin, modelle uyumlu olması için bir görüntüyü yeniden boyutlandırmanız veya görüntü biçimini değiştirmeniz gerekebilir.

  3. çalışan çıkarım

    Bu adım, modeli yürütmek için TensorFlow Lite API'sinin kullanılmasını içerir. Aşağıdaki bölümlerde açıklandığı gibi, yorumlayıcıyı oluşturmak ve tensörleri tahsis etmek gibi birkaç adımı içerir.

  4. çıktıyı yorumlama

    Model çıkarımından sonuçlar aldığınızda, tensörleri uygulamanızda faydalı olacak şekilde anlamlı bir şekilde yorumlamanız gerekir.

    Örneğin, bir model yalnızca bir olasılık listesi döndürebilir. Olasılıkları ilgili kategorilere haritalamak ve son kullanıcınıza sunmak size kalmıştır.

Desteklenen platformlar

TensorFlow çıkarım API'leri gibi en yaygın mobil / gömülü platformlar için verilmektedir Android , iOS ve Linux çoklu programlama dillerinde.

Çoğu durumda, API tasarımı, kullanım kolaylığı yerine performans tercihini yansıtır. TensorFlow Lite, küçük cihazlarda hızlı çıkarım için tasarlanmıştır, bu nedenle API'lerin kolaylık pahasına gereksiz kopyalardan kaçınmaya çalışması şaşırtıcı olmamalıdır. Benzer şekilde, TensorFlow API'leriyle tutarlılık açık bir hedef değildi ve diller arasında bazı farklılıklar olması bekleniyor.

TensorFlow Lite API, tüm kitaplıklarda modelleri yüklemenize, girdileri beslemenize ve çıkarım çıktılarını almanıza olanak tanır.

Android Platformu

Android'de TensorFlow Lite çıkarımı, Java veya C++ API'leri kullanılarak gerçekleştirilebilir. Java API'leri kolaylık sağlar ve doğrudan Android Activity sınıflarınızda kullanılabilir. C++ API'leri daha fazla esneklik ve hız sunar, ancak verileri Java ve C++ katmanları arasında taşımak için JNI sarmalayıcıları yazmayı gerektirebilir.

Kullanmayla ilgili ayrıntılar için aşağıya bakınız C ++ ve Java , veya takip Android quickstart bir öğretici ve örnek kodu için.

TensorFlow Lite Android sarmalayıcı kod üreteci

TensorFlow Lite modeli ile gelişmiş için meta veriler , geliştiriciler platforma özel sarıcı kodu oluşturmak için TensorFlow Lite Android sarıcı kod oluşturma aracını kullanabilirsiniz. Sarıcı kod doğrudan etkileşime ihtiyacını ortadan kaldırır ByteBuffer Android'de. Bunun yerine, geliştiriciler gibi yazılan nesnelerle TensorFlow Lite modeli ile etkileşime girebilir Bitmap ve Rect . Daha fazla bilgi için bakınız TensorFlow Lite Android sarıcı kod üreteci .

iOS Platformu

İOS'ta TensorFlow Lite yazılmış yerleşik iOS kütüphaneler mevcuttur Swift ve Objective-C . Ayrıca kullanabilirsiniz C API Objective-C kodları doğrudan.

Kullanmayla ilgili ayrıntılar için aşağıya bakın Swift , Objective-C ve C API , veya takip iOS hızlı başlangıç bir öğretici ve örnek kodu için.

Linux Platformu

(Dahil Linux platformlarında Ahududu Pi ) kullanarak, mevcut TensorFlow Lite API'leri kullanarak çıkarımlar çalıştırabilir C ++ ve Python aşağıdaki bölümlerde gösterildiği gibi,.

Model çalıştırma

Bir TensorFlow Lite modelini çalıştırmak birkaç basit adımı içerir:

  1. Modeli belleğe yükleyin.
  2. Bir İnşa Interpreter varolan modeline dayalı.
  3. Giriş tensör değerlerini ayarlayın. (Önceden tanımlanmış boyutlar istenmiyorsa, isteğe bağlı olarak giriş tensörlerini yeniden boyutlandırın.)
  4. Çıkarımı çağırın.
  5. Çıkış tensör değerlerini okuyun.

Aşağıdaki bölümlerde bu adımların her dilde nasıl yapılabileceği açıklanmaktadır.

Java'da bir model yükleyin ve çalıştırın

Platform: Android

: Bir robot kütüphane bağımlılık olarak kullanılabilir yani TensorFlow Lite ile bir çıkarım çalıştırmak için Java API öncelikle Android ile kullanılmak üzere tasarlanmıştır org.tensorflow:tensorflow-lite .

Java'da, kullanacağınız Interpreter model ve tahrik modeli çıkarım yüklemek için sınıf. Çoğu durumda, ihtiyacınız olan tek API bu olabilir.

Bir sunabilmesi Interpreter bir kullanarak .tflite dosyası:

public Interpreter(@NotNull File modelFile);

Ya da sahip MappedByteBuffer :

public Interpreter(@NotNull MappedByteBuffer mappedByteBuffer);

Her iki durumda da, geçerli bir TensorFlow Lite modeli sağlaması gerekir veya API atar IllegalArgumentException . Eğer kullanırsanız MappedByteBuffer bir başlatmak için Interpreter , bu bütün ömrü boyunca değişmeden kalmalıdır Interpreter .

Bir modelde çıkarım yapmanın tercih edilen yolu imza kullanmaktır - Tensorflow 2.5'ten başlayarak dönüştürülen modeller için kullanılabilir

try (Interpreter interpreter = new Interpreter(file_of_tensorflowlite_model)) {
  Map<String, Object> inputs = new HashMap<>();
  inputs.put("input_1", input1);
  inputs.put("input_2", input2);
  Map<String, Object> outputs = new HashMap<>();
  outputs.put("output_1", output1);
  interpreter.runSignature(inputs, outputs, "mySignature");
}

runSignature yöntemi üç argüman alır:

  • Girişler: Bir giriş nesnesine imza giriş adından girişler için harita.

  • Çıkışlar: çıkış verilerine imza çıktı adından çıkış haritalama için harita.

  • İmza Adı [isteğe bağlı]: İmza adı (model tek imza varsa boş bırakılabilir Can).

Modelin tanımlı imzaları olmadığında çıkarım yapmanın başka bir yolu. Basitçe çağrı Interpreter.run() . Örneğin:

try (Interpreter interpreter = new Interpreter(file_of_a_tensorflowlite_model)) {
  interpreter.run(input, output);
}

run() metodu sadece bir çıkış tek bir giriş ve döner alır. Bu nedenle, modelinizin birden çok girdisi veya birden çok çıktısı varsa, bunun yerine şunu kullanın:

interpreter.runForMultipleInputsOutputs(inputs, map_of_indices_to_outputs);

Bu durumda, her bir giriş inputs bir giriş tensörü ve tekabül map_of_indices_to_outputs karşılık gelen çıkış verileri çıkışı tensörlerinin endeksleri alır.

Her iki durumda da, tensör endeksleri sen verdiğin değerlere karşılık gelmelidir TensorFlow Lite Dönüştürücü , modeli oluştururken. İçinde Tensörlerin sırası unutmayın input TensorFlow Lite Converter verilen emri aynı olmalıdır.

Interpreter Eğer bir operasyon adını kullanarak herhangi bir model girdi ya da çıktı endeksini almak için sınıfı da uygun fonksiyonları sunar:

public int getInputIndex(String opName);
public int getOutputIndex(String opName);

Eğer opName modelinde geçerli bir işlem değildir, bir atar IllegalArgumentException .

Ayrıca bu dikkat Interpreter kaynaklarını sahibi. Bellek sızıntısını önlemek için kaynaklar aşağıdakiler tarafından kullanıldıktan sonra serbest bırakılmalıdır:

interpreter.close();

Java ile örnek bir proje için bkz Android görüntü sınıflandırma örneği .

Desteklenen veri türleri (Java'da)

TensorFlow Lite'ı kullanmak için giriş ve çıkış tensörlerinin veri türleri aşağıdaki ilkel türlerden biri olmalıdır:

  • float
  • int
  • long
  • byte

String türleri de desteklenir, ama temel tür farklı kodlanır. Özellikle, bir dizi Tensörünün şekli, her bir elemanın kendisi değişken uzunlukta bir dizi olacak şekilde, Tensördeki dizilerin sayısını ve düzenini belirler. Bu anlamda, Tensörünün (bayt) boyutlu şeklinden hesaplanır ve tek başına tip, ve sonuç olarak şeritler tek bir düz olarak temin edilemez edilemez ByteBuffer argüman.

Gibi kutulu türleri de dahil diğer veri tipleri, varsa Integer ve Float kullanılır, bir IllegalArgumentException atılacaktır.

Girişler

Her bir giriş desteklenen ilkel türde bir dizi ya da çok-boyutlu bir dizi veya bir ham olmalıdır ByteBuffer uygun boyutta. Girdi bir dizi veya çok boyutlu diziyse, ilişkili girdi tensörü, çıkarım zamanında dizinin boyutlarına dolaylı olarak yeniden boyutlandırılacaktır. Girdi bir ByteBuffer ise, arayan ilk manuel (aracılığıyla ilişkili giriş tensörünü boyutlandırmak gerekir Interpreter.resizeInput() çıkarımlar çalıştırmadan önce).

Kullanırken ByteBuffer bu verdiğinden, doğrudan bayt tampon kullanmayı tercih Interpreter gereksiz kopyalarını önlemek için. Eğer ByteBuffer doğrudan bayt tamponudur, siparişinin olmalıdır ByteOrder.nativeOrder() . Model çıkarımı için kullanıldıktan sonra model çıkarımı bitene kadar değişmeden kalmalıdır.

çıktılar

Her çıktı, desteklenen ilkel türlerin bir dizisi veya çok boyutlu dizisi veya uygun boyutta bir ByteBuffer olmalıdır. Bazı modellerin dinamik çıktılara sahip olduğunu ve çıktı tensörlerinin şeklinin girdiye bağlı olarak değişebildiğini unutmayın. Bunu mevcut Java çıkarım API'si ile ele almanın kolay bir yolu yoktur, ancak planlanan uzantılar bunu mümkün kılacaktır.

Swift'de bir model yükleyin ve çalıştırın

Platform: iOS

Swift API mevcuttur TensorFlowLiteSwift Cocoapods gelen Pod.

Öncelikle, ithalat gerekir TensorFlowLite modülü.

import TensorFlowLite
// Getting model path
guard
  let modelPath = Bundle.main.path(forResource: "model", ofType: "tflite")
else {
  // Error handling...
}

do {
  // Initialize an interpreter with the model.
  let interpreter = try Interpreter(modelPath: modelPath)

  // Allocate memory for the model's input `Tensor`s.
  try interpreter.allocateTensors()

  let inputData: Data  // Should be initialized

  // input data preparation...

  // Copy the input data to the input `Tensor`.
  try self.interpreter.copy(inputData, toInputAt: 0)

  // Run inference by invoking the `Interpreter`.
  try self.interpreter.invoke()

  // Get the output `Tensor`
  let outputTensor = try self.interpreter.output(at: 0)

  // Copy output to `Data` to process the inference results.
  let outputSize = outputTensor.shape.dimensions.reduce(1, {x, y in x * y})
  let outputData =
        UnsafeMutableBufferPointer<Float32>.allocate(capacity: outputSize)
  outputTensor.data.copyBytes(to: outputData)

  if (error != nil) { /* Error handling... */ }
} catch error {
  // Error handling...
}

Objective-C'de bir model yükleyin ve çalıştırın

Platform: iOS

Objective-C API mevcuttur TensorFlowLiteObjC Cocoapods gelen Pod.

Öncelikle, ithalat gerekir TensorFlowLite modülü.

@import TensorFlowLite;
NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"model"
                                                      ofType:@"tflite"];
NSError *error;

// Initialize an interpreter with the model.
TFLInterpreter *interpreter = [[TFLInterpreter alloc] initWithModelPath:modelPath
                                                                  error:&error];
if (error != nil) { /* Error handling... */ }

// Allocate memory for the model's input `TFLTensor`s.
[interpreter allocateTensorsWithError:&error];
if (error != nil) { /* Error handling... */ }

NSMutableData *inputData;  // Should be initialized
// input data preparation...

// Get the input `TFLTensor`
TFLTensor *inputTensor = [interpreter inputTensorAtIndex:0 error:&error];
if (error != nil) { /* Error handling... */ }

// Copy the input data to the input `TFLTensor`.
[inputTensor copyData:inputData error:&error];
if (error != nil) { /* Error handling... */ }

// Run inference by invoking the `TFLInterpreter`.
[interpreter invokeWithError:&error];
if (error != nil) { /* Error handling... */ }

// Get the output `TFLTensor`
TFLTensor *outputTensor = [interpreter outputTensorAtIndex:0 error:&error];
if (error != nil) { /* Error handling... */ }

// Copy output to `NSData` to process the inference results.
NSData *outputData = [outputTensor dataWithError:&error];
if (error != nil) { /* Error handling... */ }

Objective-C kodunda C API kullanma

Şu anda Objective-C API, temsilcileri desteklemiyor. Objective-C kodu ile kullanım delegeler için, doğrudan yatan çağırmanız gerekir C API .

#include "tensorflow/lite/c/c_api.h"
TfLiteModel* model = TfLiteModelCreateFromFile([modelPath UTF8String]);
TfLiteInterpreterOptions* options = TfLiteInterpreterOptionsCreate();

// Create the interpreter.
TfLiteInterpreter* interpreter = TfLiteInterpreterCreate(model, options);

// Allocate tensors and populate the input tensor data.
TfLiteInterpreterAllocateTensors(interpreter);
TfLiteTensor* input_tensor =
    TfLiteInterpreterGetInputTensor(interpreter, 0);
TfLiteTensorCopyFromBuffer(input_tensor, input.data(),
                           input.size() * sizeof(float));

// Execute inference.
TfLiteInterpreterInvoke(interpreter);

// Extract the output tensor data.
const TfLiteTensor* output_tensor =
    TfLiteInterpreterGetOutputTensor(interpreter, 0);
TfLiteTensorCopyToBuffer(output_tensor, output.data(),
                         output.size() * sizeof(float));

// Dispose of the model and interpreter objects.
TfLiteInterpreterDelete(interpreter);
TfLiteInterpreterOptionsDelete(options);
TfLiteModelDelete(model);

Bir modeli C++ ile yükleyin ve çalıştırın

Platformlar: Android, iOS ve Linux

C ++, model, depolanan FlatBufferModel sınıfı. Bir TensorFlow Lite modelini kapsar ve modelin nerede saklandığına bağlı olarak onu birkaç farklı şekilde oluşturabilirsiniz:

class FlatBufferModel {
  // Build a model based on a file. Return a nullptr in case of failure.
  static std::unique_ptr<FlatBufferModel> BuildFromFile(
      const char* filename,
      ErrorReporter* error_reporter);

  // Build a model based on a pre-loaded flatbuffer. The caller retains
  // ownership of the buffer and should keep it alive until the returned object
  // is destroyed. Return a nullptr in case of failure.
  static std::unique_ptr<FlatBufferModel> BuildFromBuffer(
      const char* buffer,
      size_t buffer_size,
      ErrorReporter* error_reporter);
};

Artık bir şekilde modele sahip olduğunu FlatBufferModel nesnesi, bir ile yürütebileceği Interpreter . Tek bir FlatBufferModel birden fazla aynı anda kullanılabilir Interpreter .

Önemli bölümleri Interpreter kodunda gösterilmiştir API aşağıda pasajı. Bu not alınmalı:

  • Tensörler, dize karşılaştırmalarından (ve dize kitaplıklarına herhangi bir sabit bağımlılıktan) kaçınmak için tamsayılarla temsil edilir.
  • Bir yorumlayıcıya eşzamanlı iş parçacıklarından erişilmemelidir.
  • Giriş ve çıkış tensörlerle için bellek ayırma arayarak tetiklenen gerekir AllocateTensors() doğru tensörleri boyutlandırma sonra.

TensorFlow Lite'ın C++ ile en basit kullanımı şöyle görünür:

// Load the model
std::unique_ptr<tflite::FlatBufferModel> model =
    tflite::FlatBufferModel::BuildFromFile(filename);

// Build the interpreter
tflite::ops::builtin::BuiltinOpResolver resolver;
std::unique_ptr<tflite::Interpreter> interpreter;
tflite::InterpreterBuilder(*model, resolver)(&interpreter);

// Resize input tensors, if desired.
interpreter->AllocateTensors();

float* input = interpreter->typed_input_tensor<float>(0);
// Fill `input`.

interpreter->Invoke();

float* output = interpreter->typed_output_tensor<float>(0);

Daha fazla örnek kod için bkz minimal.cc ve label_image.cc .

Python'da bir model yükleyin ve çalıştırın

Platform: Linux

Bir çıkarım çalıştırmak için Python API sağlanır tf.lite modülü. Buradan da, çoğunlukla sadece ihtiyaç tf.lite.Interpreter bir model yüklemek ve bir çıkarım çalıştırmak için.

Bir yüklemek için Python yorumlayıcısı nasıl kullanılacağını Aşağıdaki örnek gösterir .tflite rastgele girdi verileri ile dosya ve çalıştırın çıkarım:

Bu örnek, tanımlanmış bir SignatureDef ile SavedModel'den dönüştürme yapıyorsanız önerilir. TensorFlow 2.5'ten itibaren kullanılabilir

class TestModel(tf.Module):
  def __init__(self):
    super(TestModel, self).__init__()

  @tf.function(input_signature=[tf.TensorSpec(shape=[1, 10], dtype=tf.float32)])
  def add(self, x):
    '''
    Simple method that accepts single input 'x' and returns 'x' + 4.
    '''
    # Name the output 'result' for convenience.
    return {'result' : x + 4}


SAVED_MODEL_PATH = 'content/saved_models/test_variable'
TFLITE_FILE_PATH = 'content/test_variable.tflite'

# Save the model
module = TestModel()
# You can omit the signatures argument and a default signature name will be
# created with name 'serving_default'.
tf.saved_model.save(
    module, SAVED_MODEL_PATH,
    signatures={'my_signature':module.add.get_concrete_function()})

# Convert the model using TFLiteConverter
converter = tf.lite.TFLiteConverter.from_saved_model(SAVED_MODEL_PATH)
tflite_model = converter.convert()
with open(TFLITE_FILE_PATH, 'wb') as f:
  f.write(tflite_model)

# Load the TFLite model in TFLite Interpreter
interpreter = tf.lite.Interpreter(TFLITE_FILE_PATH)
# There is only 1 signature defined in the model,
# so it will return it by default.
# If there are multiple signatures then we can pass the name.
my_signature = interpreter.get_signature_runner()

# my_signature is callable with input as arguments.
output = my_signature(x=tf.constant([1.0], shape=(1,10), dtype=tf.float32))
# 'output' is dictionary with all outputs from the inference.
# In this case we have single output 'result'.
print(output['result'])

Modelde SignatureDefs tanımlı değilse başka bir örnek.

import numpy as np
import tensorflow as tf

# Load the TFLite model and allocate tensors.
interpreter = tf.lite.Interpreter(model_path="converted_model.tflite")
interpreter.allocate_tensors()

# Get input and output tensors.
input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()

# Test the model on random input data.
input_shape = input_details[0]['shape']
input_data = np.array(np.random.random_sample(input_shape), dtype=np.float32)
interpreter.set_tensor(input_details[0]['index'], input_data)

interpreter.invoke()

# The function `get_tensor()` returns a copy of the tensor data.
# Use `tensor()` in order to get a pointer to the tensor.
output_data = interpreter.get_tensor(output_details[0]['index'])
print(output_data)

Önceden dönüştürülmüş olarak modelini yükleme alternatif olarak .tflite dosyası, sen kodunuzu birleştirebilirsiniz TensorFlow Lite Dönüştürücü Python API ( tf.lite.TFLiteConverter sonra TensorFlow Lite biçime TensorFlow modeli dönüştürmek ve izin) çıkarımı çalıştır:

import numpy as np
import tensorflow as tf

img = tf.placeholder(name="img", dtype=tf.float32, shape=(1, 64, 64, 3))
const = tf.constant([1., 2., 3.]) + tf.constant([1., 4., 4.])
val = img + const
out = tf.identity(val, name="out")

# Convert to TF Lite format
with tf.Session() as sess:
  converter = tf.lite.TFLiteConverter.from_session(sess, [img], [out])
  tflite_model = converter.convert()

# Load the TFLite model and allocate tensors.
interpreter = tf.lite.Interpreter(model_content=tflite_model)
interpreter.allocate_tensors()

# Continue to get tensors and so forth, as shown above...

Daha Python örnek kod için bkz label_image.py .

İpucu: Run help(tf.lite.Interpreter) Python terminalde tercüman hakkında detaylı belgeler elde etmek.

Desteklenen işlemler

TensorFlow Lite, bazı sınırlamalarla birlikte TensorFlow işlemlerinin bir alt kümesini destekler. Operasyon ve sınırlamaları tam listesi için bkz TF Lite Ops sayfasını .