Istilah inferensi mengacu pada proses eksekusi model TensorFlow Lite di perangkat untuk membuat prediksi berdasarkan data masukan. Untuk melakukan inferensi dengan model TensorFlow Lite, Anda harus menjalankannya melalui juru bahasa . Interpreter 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 mengakses juru bahasa TensorFlow Lite dan melakukan inferensi menggunakan C++, Java, dan Python, plus tautan ke sumber daya lain untuk setiap platform yang didukung .
Konsep penting
Inferensi TensorFlow Lite biasanya mengikuti langkah-langkah berikut:
Memuat model
Anda harus memuat model
.tflite
ke dalam memori, yang berisi grafik eksekusi model.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.
Menjalankan inferensi
Langkah ini melibatkan penggunaan TensorFlow Lite API untuk mengeksekusi model. Ini melibatkan beberapa langkah seperti membangun juru bahasa, dan mengalokasikan tensor, seperti yang dijelaskan di bagian berikut.
Menafsirkan keluaran
Saat Anda menerima hasil dari inferensi model, Anda harus menginterpretasikan tensor dengan cara bermakna yang berguna dalam aplikasi Anda.
Misalnya, model mungkin hanya menampilkan daftar probabilitas. Terserah Anda untuk memetakan probabilitas ke kategori yang relevan dan menyajikannya kepada pengguna akhir Anda.
Platform yang didukung
API inferensi TensorFlow disediakan untuk sebagian besar platform seluler/tersemat seperti Android , iOS , dan Linux , dalam berbagai 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 API TensorFlow bukanlah tujuan eksplisit dan beberapa perbedaan antar bahasa diharapkan.
Di semua pustaka, TensorFlow Lite API memungkinkan Anda memuat model, memasukkan masukan, dan mengambil keluaran inferensi.
Platform Android
Di Android, inferensi TensorFlow Lite dapat dilakukan menggunakan Java atau C++ API. API Java 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 detail tentang penggunaan C++ dan Java , atau ikuti panduan memulai Android untuk tutorial dan kode contoh.
Pembuat kode pembungkus Android TensorFlow Lite
Untuk model TensorFlow Lite yang disempurnakan dengan metadata , developer dapat menggunakan pembuat kode pembungkus Android TensorFlow Lite untuk membuat kode pembungkus khusus platform. Kode pembungkus menghilangkan kebutuhan untuk berinteraksi langsung dengan ByteBuffer
di Android. Sebagai gantinya, developer dapat berinteraksi dengan model TensorFlow Lite dengan objek yang diketik seperti Bitmap
dan Rect
. Untuk informasi selengkapnya, lihat pembuat kode pembungkus Android TensorFlow Lite .
Platform iOS
Di iOS, TensorFlow Lite tersedia dengan pustaka iOS asli yang ditulis dalam Swift dan Objective-C . Anda juga dapat menggunakan C API secara langsung dalam kode Objective-C.
Lihat di bawah untuk detail tentang penggunaan Swift , Objective-C , dan C API , atau ikuti panduan memulai iOS untuk tutorial dan kode contoh.
Platform Linux
Di platform Linux (termasuk Raspberry Pi ), Anda bisa menjalankan inferensi menggunakan TensorFlow Lite API yang tersedia di C++ dan Python , seperti yang ditampilkan di bagian berikut.
Menjalankan model
Menjalankan model TensorFlow Lite melibatkan beberapa langkah sederhana:
- Muat model ke dalam memori.
- Bangun
Interpreter
berdasarkan model yang ada. - Tetapkan nilai tensor input. (Opsional mengubah ukuran tensor input jika ukuran yang telah ditentukan tidak diinginkan.)
- Memanggil inferensi.
- Baca nilai tensor keluaran.
Bagian berikut menjelaskan bagaimana langkah-langkah ini dapat dilakukan dalam setiap bahasa.
Muat dan jalankan model di Java
Platform: Android
Java API untuk menjalankan inferensi dengan TensorFlow Lite terutama dirancang untuk digunakan dengan Android, sehingga tersedia sebagai dependensi library Android: org.tensorflow:tensorflow-lite
.
Di Java, Anda akan menggunakan kelas Interpreter
untuk memuat model dan mendorong inferensi model. Dalam banyak kasus, ini mungkin satu-satunya API yang Anda butuhkan.
Anda dapat menginisialisasi Interpreter
menggunakan file .tflite
:
public Interpreter(@NotNull File modelFile);
Atau dengan MappedByteBuffer
:
public Interpreter(@NotNull MappedByteBuffer mappedByteBuffer);
Dalam kedua kasus tersebut, Anda harus menyediakan model TensorFlow Lite yang valid atau API akan melontarkan IllegalArgumentException
. Jika Anda menggunakan MappedByteBuffer
untuk menginisialisasi Interpreter
, itu harus tetap tidak berubah seumur hidup Interpreter
.
Cara yang 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");
}
Metode runSignature
membutuhkan tiga argumen:
Inputs : memetakan input dari nama input dalam tanda tangan ke objek input.
Keluaran : peta untuk pemetaan keluaran dari nama keluaran dalam tanda tangan ke data keluaran.
Nama Tanda Tangan [opsional]: Nama tanda tangan (Dapat dikosongkan jika model memiliki satu tanda tangan).
Cara lain untuk menjalankan inferensi saat model tidak memiliki tanda tangan yang ditentukan. Cukup panggil Interpreter.run()
. Misalnya:
try (Interpreter interpreter = new Interpreter(file_of_a_tensorflowlite_model)) {
interpreter.run(input, output);
}
Metode run()
hanya mengambil satu input dan mengembalikan hanya satu output. Jadi, jika model Anda memiliki banyak masukan atau banyak keluaran, sebagai gantinya gunakan:
interpreter.runForMultipleInputsOutputs(inputs, map_of_indices_to_outputs);
Dalam hal ini, setiap entri dalam inputs
sesuai dengan tensor input dan map_of_indices_to_outputs
memetakan indeks tensor output ke data output yang sesuai.
Dalam kedua kasus tersebut, indeks tensor harus sesuai dengan nilai yang Anda berikan ke TensorFlow Lite Converter saat membuat model. Ketahuilah bahwa urutan tensor di input
harus sesuai dengan urutan yang diberikan ke TensorFlow Lite Converter.
Kelas Interpreter
juga menyediakan fungsi yang mudah bagi Anda untuk mendapatkan indeks input atau output model apa pun menggunakan nama operasi:
public int getInputIndex(String opName);
public int getOutputIndex(String opName);
Jika opName
bukan operasi yang valid dalam model, ia akan melontarkan IllegalArgumentException
.
Berhati-hatilah juga karena Interpreter
memiliki sumber daya. Untuk menghindari kebocoran memori, sumber daya harus dilepaskan setelah digunakan oleh:
interpreter.close();
Untuk contoh project dengan Java, lihat contoh klasifikasi gambar Android .
Tipe data yang didukung (di Jawa)
Untuk menggunakan TensorFlow Lite, tipe data tensor input dan output harus salah satu dari tipe primitif berikut:
-
float
-
int
-
long
-
byte
Tipe String
juga didukung, tetapi dikodekan secara berbeda dari tipe primitif. Secara khusus, bentuk Tensor string menentukan jumlah dan susunan string dalam Tensor, dengan setiap elemen itu sendiri menjadi string dengan panjang variabel. Dalam hal ini, ukuran (byte) Tensor tidak dapat dihitung dari bentuk dan jenis saja, dan akibatnya string tidak dapat diberikan sebagai argumen ByteBuffer
datar tunggal. Anda dapat melihat beberapa contoh di halaman ini.
Jika tipe data lain, termasuk tipe kotak seperti Integer
dan Float
, digunakan, IllegalArgumentException
akan dilempar.
Input
Setiap masukan harus berupa larik atau larik multidimensi dari tipe primitif yang didukung, atau ByteBuffer
mentah dengan ukuran yang sesuai. Jika masukannya adalah larik atau larik multidimensi, tensor masukan terkait akan secara implisit diubah ukurannya ke dimensi larik pada waktu inferensi. Jika inputnya adalah ByteBuffer, pemanggil harus terlebih dahulu mengubah ukuran tensor input terkait secara manual (melalui Interpreter.resizeInput()
) sebelum menjalankan inferensi.
Saat menggunakan ByteBuffer
, sebaiknya gunakan buffer byte langsung, karena hal ini memungkinkan Interpreter
menghindari salinan yang tidak perlu. Jika ByteBuffer
adalah buffer byte langsung, urutannya harus ByteOrder.nativeOrder()
. Setelah digunakan untuk inferensi model, ia harus tetap tidak berubah hingga 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 bergantung pada masukan. Tidak ada cara langsung untuk menangani hal ini dengan API inferensi Java yang ada, tetapi ekstensi terencana akan memungkinkan hal ini.
Muat dan jalankan model di Swift
Platform: iOS
Swift API tersedia di TensorFlowLiteSwift
Pod dari Cocoapods.
Pertama, Anda perlu mengimpor modul TensorFlowLite
.
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
API Objective-C tersedia di TensorFlowLiteObjC
Pod dari Cocoapods.
Pertama, Anda perlu mengimpor modul TensorFlowLite
.
@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. Untuk menggunakan delegasi dengan kode Objective-C, Anda harus langsung memanggil C API yang mendasarinya.
#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 dalam C++
Platform: Android, iOS, dan Linux
Di C++, model disimpan di kelas FlatBufferModel
. Ini merangkum model TensorFlow Lite dan Anda dapat membangunnya 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 setelah Anda memiliki model sebagai objek FlatBufferModel
, Anda dapat menjalankannya dengan Interpreter
. Satu FlatBufferModel
dapat digunakan secara bersamaan oleh lebih dari satu Interpreter
.
Bagian penting dari Interpreter
API ditunjukkan pada cuplikan kode di bawah ini. Perlu dicatat bahwa:
- Tensor diwakili oleh bilangan bulat, untuk menghindari perbandingan string (dan ketergantungan tetap apa pun pada pustaka string).
- Penerjemah tidak boleh diakses dari utas bersamaan.
- Alokasi memori untuk tensor input dan output harus dipicu dengan memanggil
AllocateTensors()
tepat setelah mengubah ukuran tensor.
Penggunaan paling sederhana dari TensorFlow Lite dengan C++ 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);
Untuk kode contoh lainnya, lihat minimal.cc
dan label_image.cc
.
Muat dan jalankan model dengan Python
Platform: Linux
API Python untuk menjalankan inferensi disediakan dalam modul tf.lite
. Dari situ, Anda hanya perlu tf.lite.Interpreter
untuk memuat model dan menjalankan inferensi.
Contoh berikut menunjukkan cara menggunakan interpreter Python untuk memuat file .tflite
dan menjalankan inferensi dengan input data acak:
Contoh ini disarankan 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 file .tflite
yang telah dikonversi sebelumnya, Anda dapat menggabungkan kode Anda dengan TensorFlow Lite Converter Python API ( tf.lite.TFLiteConverter
), yang memungkinkan Anda mengonversi model TensorFlow Anda ke dalam format TensorFlow Lite lalu 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 contoh kode Python lainnya, lihat label_image.py
.
Jalankan inferensi dengan model bentuk dinamis
Jika Anda ingin menjalankan model dengan bentuk masukan dinamis, ubah ukuran bentuk masukan sebelum menjalankan inferensi. Jika tidak, bentuk None
dalam model Tensorflow akan diganti dengan placeholder 1
dalam model TFLite.
Contoh berikut menunjukkan cara mengubah ukuran bentuk masukan sebelum menjalankan inferensi dalam berbagai bahasa. Semua contoh mengasumsikan bahwa bentuk input didefinisikan sebagai [1/None, 10]
, dan perlu diubah ukurannya menjadi [3, 10]
.
Operasi yang didukung
TensorFlow Lite mendukung subset operasi TensorFlow dengan beberapa batasan. Untuk daftar lengkap operasi dan batasan, lihat halaman TF Lite Ops .