Hari Komunitas ML adalah 9 November! Bergabung dengan kami untuk update dari TensorFlow, JAX, dan lebih Pelajari lebih lanjut

Inferensi TensorFlow Lite

Kesimpulan merujuk pada proses eksekusi model TensorFlow Lite on-perangkat untuk membuat prediksi berdasarkan data masukan. Untuk melakukan inferensi dengan model TensorFlow Lite, Anda harus menjalankannya melalui seorang penerjemah. Penerjemah TensorFlow Lite dirancang agar ramping dan cepat. Interpreter menggunakan pengurutan grafik statis dan pengalokasi memori khusus (kurang dinamis) untuk memastikan beban minimal, inisialisasi, dan latensi eksekusi.

Halaman ini menjelaskan cara akses ke juru TensorFlow Lite dan melakukan inferensi menggunakan C ++, Java, dan Python, ditambah link ke sumber informasi lainnya untuk setiap platform yang didukung .

Konsep penting

Inferensi TensorFlow Lite biasanya mengikuti langkah-langkah berikut:

  1. Memuat model

    Anda harus memuat .tflite model ke memori, yang berisi grafik eksekusi model.

  2. Mengubah data

    Data masukan mentah untuk model umumnya tidak sesuai dengan format data masukan yang diharapkan oleh model. Misalnya, Anda mungkin perlu mengubah ukuran gambar atau mengubah format gambar agar kompatibel dengan model.

  3. Menjalankan inferensi

    Langkah ini melibatkan penggunaan TensorFlow Lite API untuk menjalankan model. Ini melibatkan beberapa langkah seperti membangun interpreter, dan mengalokasikan tensor, seperti yang dijelaskan di bagian berikut.

  4. Menafsirkan keluaran

    Saat Anda menerima hasil dari inferensi model, Anda harus menginterpretasikan tensor dengan cara yang berarti yang berguna dalam aplikasi Anda.

    Misalnya, model mungkin hanya mengembalikan daftar probabilitas. Terserah Anda untuk memetakan probabilitas ke kategori yang relevan dan menyajikannya kepada pengguna akhir Anda.

Platform yang didukung

TensorFlow API inferensi yang disediakan untuk yang paling umum mobile / embedded platform seperti Android , iOS dan Linux , dalam beberapa bahasa pemrograman.

Dalam kebanyakan kasus, desain API mencerminkan preferensi kinerja daripada kemudahan penggunaan. TensorFlow Lite dirancang untuk inferensi cepat pada perangkat kecil, jadi tidak mengherankan jika API mencoba menghindari salinan yang tidak perlu dengan mengorbankan kenyamanan. Demikian pula, konsistensi dengan TensorFlow API bukanlah tujuan eksplisit dan beberapa perbedaan antar bahasa diharapkan.

Di semua library, TensorFlow Lite API memungkinkan Anda memuat model, memasukkan input, dan mengambil output inferensi.

Platform Android

Di Android, inferensi TensorFlow Lite dapat dilakukan menggunakan Java atau C++ API. Java API memberikan kemudahan dan dapat digunakan langsung dalam kelas Aktivitas Android Anda. C++ API menawarkan lebih banyak fleksibilitas dan kecepatan, tetapi mungkin memerlukan penulisan pembungkus JNI untuk memindahkan data antara lapisan Java dan C++.

Lihat di bawah untuk rincian tentang menggunakan C ++ dan Java , atau mengikuti quickstart Android untuk kode tutorial dan contoh.

Pembuat kode pembungkus Android TensorFlow Lite

Untuk model TensorFlow Lite ditingkatkan dengan metadata , pengembang dapat menggunakan TensorFlow Lite Android kode wrapper generator untuk membuat platform kode tertentu wrapper. Kode wrapper menghilangkan kebutuhan untuk berinteraksi langsung dengan ByteBuffer di Android. Sebaliknya, pengembang dapat berinteraksi dengan model TensorFlow Lite dengan objek diketik seperti Bitmap dan Rect . Untuk informasi lebih lanjut, silakan merujuk ke TensorFlow Lite Android kode wrapper pembangkit .

Platform iOS

Pada iOS, TensorFlow Lite tersedia dengan iOS perpustakaan asli ditulis dalam Swift dan Objective-C . Anda juga dapat menggunakan C API secara langsung dalam kode Objective-C.

Lihat di bawah untuk rincian tentang menggunakan Swift , Objective-C dan C API , atau mengikuti quickstart iOS untuk kode tutorial dan contoh.

Platform Linux

Pada platform Linux (termasuk Raspberry Pi ), Anda dapat menjalankan kesimpulan menggunakan TensorFlow Lite API yang tersedia di C ++ dan Python , seperti yang ditunjukkan pada bagian berikut.

Menjalankan model

Menjalankan model TensorFlow Lite melibatkan beberapa langkah sederhana:

  1. Muat model ke dalam memori.
  2. Membangun Interpreter berdasarkan model yang sudah ada.
  3. Tetapkan nilai tensor masukan. (Secara opsional, ubah ukuran tensor input jika ukuran yang ditentukan sebelumnya tidak diinginkan.)
  4. Panggil inferensi.
  5. Baca nilai tensor keluaran.

Bagian berikut menjelaskan bagaimana langkah-langkah ini dapat dilakukan dalam setiap bahasa.

Muat dan jalankan model di Java

Platform: Android

API Java untuk menjalankan inferensi dengan TensorFlow Lite terutama dirancang untuk digunakan dengan Android, sehingga tersedia sebagai perpustakaan ketergantungan Android: org.tensorflow:tensorflow-lite .

Di Jawa, Anda akan menggunakan Interpreter kelas untuk memuat kesimpulan Model dan dorongan Model. Dalam banyak kasus, ini mungkin satu-satunya API yang Anda butuhkan.

Anda dapat menginisialisasi Interpreter menggunakan .tflite berkas:

public Interpreter(@NotNull File modelFile);

Atau dengan MappedByteBuffer :

public Interpreter(@NotNull MappedByteBuffer mappedByteBuffer);

Dalam kedua kasus, Anda harus menyediakan model TensorFlow Lite valid atau API melempar IllegalArgumentException . Jika Anda menggunakan MappedByteBuffer untuk menginisialisasi Interpreter , harus tetap tidak berubah untuk seluruh seumur hidup dari Interpreter .

Cara yang lebih disukai untuk menjalankan inferensi pada model adalah dengan menggunakan tanda tangan - Tersedia untuk model yang dikonversi mulai Tensorflow 2.5

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");
}

The runSignature Metode mengambil tiga argumen:

  • Input: map untuk masukan dari nama masukan dalam tanda tangan untuk sebuah objek masukan.

  • Output: Peta untuk output pemetaan dari nama output dalam signature data output.

  • Tanda tangan Nama [opsional]: Nama Tanda tangan (Bisa dibiarkan kosong jika model memiliki tanda tangan tunggal).

Cara lain untuk menjalankan inferensi ketika model tidak memiliki tanda tangan yang ditentukan. Hanya memanggil Interpreter.run() . Sebagai contoh:

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

The run() metode hanya membutuhkan waktu satu masukan dan kembali hanya satu output. Jadi, jika model Anda memiliki banyak input atau beberapa output, gunakan:

interpreter.runForMultipleInputsOutputs(inputs, map_of_indices_to_outputs);

Dalam hal ini, setiap entri di inputs berkorespondensi ke tensor input dan map_of_indices_to_outputs peta indeks tensor output ke output data yang sesuai.

Dalam kedua kasus, indeks tensor harus sesuai dengan nilai-nilai yang Anda berikan kepada TensorFlow Lite Converter saat membuat model. Sadarilah bahwa urutan tensor input harus sesuai dengan perintah yang diberikan kepada TensorFlow Lite Converter.

The Interpreter kelas juga menyediakan fungsi yang mudah bagi Anda untuk mendapatkan indeks dari setiap masukan Model atau output menggunakan nama operasi:

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

Jika opName bukan operasi yang sah dalam model, melempar IllegalArgumentException .

Juga berhati-hatilah bahwa Interpreter memiliki sumber daya. Untuk menghindari kebocoran memori, sumber daya harus dilepaskan setelah digunakan oleh:

interpreter.close();

Untuk contoh proyek dengan Java, lihat contoh klasifikasi citra Android .

Tipe data yang didukung (dalam Java)

Untuk menggunakan TensorFlow Lite, tipe data tensor input dan output harus salah satu dari tipe primitif berikut:

  • float
  • int
  • long
  • byte

String jenis juga didukung, tetapi mereka dikodekan berbeda dari tipe primitif. Secara khusus, bentuk string Tensor menentukan jumlah dan susunan string di Tensor, dengan setiap elemen itu sendiri menjadi string dengan panjang variabel. Dalam pengertian ini, (byte) ukuran Tensor tidak dapat dihitung dari bentuk dan jenis saja, dan akibatnya string tidak dapat diberikan sebagai tunggal, datar ByteBuffer argumen.

Jika jenis data lainnya, termasuk jenis kotak seperti Integer dan Float , digunakan, sebuah IllegalArgumentException akan dilempar.

Masukan

Setiap masukan harus array atau multi-dimensi array tipe primitif yang didukung, atau mentah ByteBuffer dengan ukuran yang sesuai. Jika inputnya adalah array atau array multidimensi, tensor input terkait akan diubah ukurannya secara implisit ke dimensi array pada waktu inferensi. Jika input adalah ByteBuffer, pemanggil harus pertama secara manual mengubah ukuran input tensor terkait (melalui Interpreter.resizeInput() ) sebelum menjalankan inferensi.

Bila menggunakan ByteBuffer , lebih suka menggunakan buffer byte langsung, karena hal ini memungkinkan Interpreter untuk menghindari salinan yang tidak perlu. Jika ByteBuffer adalah byte penyangga langsung, order harus ByteOrder.nativeOrder() . Setelah digunakan untuk inferensi model, itu harus tetap tidak berubah sampai inferensi model selesai.

Keluaran

Setiap keluaran harus berupa larik atau larik multidimensi dari tipe primitif yang didukung, atau ByteBuffer dengan ukuran yang sesuai. Perhatikan bahwa beberapa model memiliki keluaran dinamis, di mana bentuk tensor keluaran dapat bervariasi tergantung pada masukannya. Tidak ada cara langsung untuk menangani ini dengan API inferensi Java yang ada, tetapi ekstensi yang direncanakan akan memungkinkan hal ini.

Muat dan jalankan model di Swift

Platform: iOS

The Swift API tersedia dalam TensorFlowLiteSwift Pod dari Cocoapods.

Pertama, Anda perlu impor TensorFlowLite modul.

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...
}

Muat dan jalankan model di Objective-C

Platform: iOS

The Objective-C API tersedia di TensorFlowLiteObjC Pod dari Cocoapods.

Pertama, Anda perlu impor TensorFlowLite modul.

@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... */ }

Menggunakan C API dalam kode Objective-C

Saat ini Objective-C API tidak mendukung delegasi. Dalam rangka untuk delegasi digunakan dengan kode Objective-C, Anda perlu langsung memanggil mendasari 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);

Muat dan jalankan model di C++

Platform: Android, iOS, dan Linux

Dalam C ++, model disimpan dalam FlatBufferModel kelas. Ini merangkum model TensorFlow Lite dan Anda dapat membuatnya dalam beberapa cara berbeda, tergantung di mana model disimpan:

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);
};

Sekarang bahwa Anda memiliki model sebagai FlatBufferModel objek, Anda dapat jalankan dengan Interpreter . Sebuah single FlatBufferModel dapat digunakan secara bersamaan oleh lebih dari satu Interpreter .

Bagian-bagian penting dari Interpreter API ditunjukkan dalam potongan kode di bawah ini. Perlu dicatat bahwa:

  • Tensor diwakili oleh bilangan bulat, untuk menghindari perbandingan string (dan ketergantungan tetap pada pustaka string).
  • Penerjemah tidak boleh diakses dari utas bersamaan.
  • Alokasi memori untuk input dan output tensor harus dipicu dengan memanggil AllocateTensors() setelah mengubah ukuran tensor.

Penggunaan TensorFlow Lite dengan C++ yang paling sederhana terlihat seperti ini:

// 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);

Misalnya kode lebih lanjut, lihat minimal.cc dan label_image.cc .

Muat dan jalankan model dengan Python

Platform: Linux

API Python untuk menjalankan sebuah kesimpulan disediakan di tf.lite modul. Dari yang, sebagian besar Anda hanya perlu tf.lite.Interpreter memuat model dan menjalankan inferensi.

Contoh berikut menunjukkan bagaimana menggunakan interpreter Python untuk memuat .tflite berkas dan menjalankan inferensi dengan input data acak:

Contoh ini direkomendasikan jika Anda mengonversi dari SavedModel dengan SignatureDef yang ditentukan. Tersedia mulai dari TensorFlow 2.5

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'])

Contoh lain jika model tidak memiliki SignatureDefs yang ditentukan.

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)

Sebagai alternatif untuk memuat model sebagai pra-dikonversi .tflite file, Anda dapat menggabungkan kode Anda dengan API TensorFlow Lite Converter Python ( tf.lite.TFLiteConverter ), yang memungkinkan Anda untuk mengkonversi Model TensorFlow Anda ke format TensorFlow Lite dan kemudian menjalankan inferensi:

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...

Untuk lebih Python kode contoh, lihat label_image.py .

Tip: Jalankan help(tf.lite.Interpreter) di terminal Python untuk mendapatkan dokumentasi rinci tentang penerjemah.

Operasi yang didukung

TensorFlow Lite mendukung subset operasi TensorFlow dengan beberapa batasan. Untuk daftar lengkap operasi dan keterbatasan melihat halaman Ops TF Lite .