Çıkarım terimi, giriş verilerine dayalı tahminler yapmak için cihazda bir TensorFlow Lite modelinin yürütülmesi sürecini ifade eder. TensorFlow Lite modeliyle çıkarım yapmak için onu bir yorumlayıcı aracılığıyla çalıştırmanız gerekir. TensorFlow Lite yorumlayıcısı yalın ve hızlı olacak şekilde tasarlanmıştır. Yorumlayıcı, minimum yükleme, başlatma ve yürütme gecikmesini sağlamak için statik bir grafik sıralaması ve özel (daha az dinamik) bir bellek ayırıcı kullanır.
Bu sayfada TensorFlow Lite yorumlayıcısına nasıl erişileceği ve C++, Java ve Python kullanılarak çıkarımın nasıl gerçekleştirileceği ve ayrıca desteklenen her platform için diğer kaynaklara bağlantılar açıklanmaktadır.
Önemli kavramlar
TensorFlow Lite çıkarımı genellikle aşağıdaki adımları takip eder:
Bir model yükleniyor
.tflite
modelini, modelin yürütme grafiğini içeren belleğe yüklemelisiniz.Verileri dönüştürme
Modele ilişkin ham girdi verileri genellikle modelin beklediği girdi verisi formatıyla eşleşmez. Örneğin, bir görseli yeniden boyutlandırmanız veya görsel formatını modelle uyumlu olacak şekilde değiştirmeniz gerekebilir.
Çıkarım çalıştırma
Bu adım, modeli yürütmek için TensorFlow Lite API'nin kullanılmasını içerir. Aşağıdaki bölümlerde açıklandığı gibi yorumlayıcının oluşturulması ve tensörlerin tahsis edilmesi gibi birkaç adımı içerir.
Çıktıyı yorumlama
Model çıkarımından sonuçlar aldığınızda, tensörleri uygulamanızda yararlı olacak anlamlı bir şekilde yorumlamanız gerekir.
Örneğin bir model yalnızca olasılıkların bir listesini döndürebilir. Olasılıkları ilgili kategorilere haritalayıp son kullanıcıya sunmak size kalmış.
Desteklenen platformlar
TensorFlow çıkarım API'leri Android , iOS ve Linux gibi en yaygın mobil/gömülü platformlar için birden fazla programlama dilinde sağlanır.
Çoğu durumda API tasarımı, kullanım kolaylığı yerine performans tercihini yansıtır. TensorFlow Lite, küçük cihazlarda hızlı çıkarım yapmak üzere tasarlanmıştır; bu nedenle API'lerin kolaylıktan ödün vererek gereksiz kopyalardan kaçınmaya çalışması şaşırtıcı olmamalıdır. Benzer şekilde, TensorFlow API'leriyle tutarlılık da açık bir hedef değildi ve diller arasında bazı farklılıklar olması bekleniyordu.
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 Etkinlik 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ının yazılmasını gerektirebilir.
C++ ve Java kullanımına ilişkin ayrıntılar için aşağıya bakın veya bir eğitim ve örnek kod için Android hızlı başlangıcını izleyin.
TensorFlow Lite Android sarmalayıcı kod oluşturucu
Meta verilerle geliştirilmiş TensorFlow Lite modeli için geliştiriciler, platforma özel sarmalayıcı kod oluşturmak amacıyla TensorFlow Lite Android sarmalayıcı kod oluşturucuyu kullanabilir. Sarma kodu, Android'de ByteBuffer
ile doğrudan etkileşim kurma ihtiyacını ortadan kaldırır. Bunun yerine geliştiriciler TensorFlow Lite modeliyle Bitmap
ve Rect
gibi yazılan nesnelerle etkileşime girebilir. Daha fazla bilgi için lütfen TensorFlow Lite Android sarmalayıcı kod oluşturucuya bakın.
iOS Platformu
İOS'ta TensorFlow Lite, Swift ve Objective-C ile yazılmış yerel iOS kitaplıklarıyla kullanılabilir. C API'yi doğrudan Objective-C kodlarında da kullanabilirsiniz.
Swift , Objective-C ve C API'yi kullanmayla ilgili ayrıntılar için aşağıya bakın veya bir eğitim ve örnek kod için iOS hızlı başlangıcını izleyin.
Linux Platformu
Linux platformlarında ( Raspberry Pi dahil), aşağıdaki bölümlerde gösterildiği gibi C++ ve Python'da bulunan TensorFlow Lite API'lerini kullanarak çıkarımlar çalıştırabilirsiniz.
Bir modeli çalıştırma
TensorFlow Lite modelini çalıştırmak birkaç basit adımı içerir:
- Modeli belleğe yükleyin.
- Mevcut bir modele dayalı bir
Interpreter
oluşturun. - Giriş tensör değerlerini ayarlayın. (Önceden tanımlanmış boyutlar istenmiyorsa isteğe bağlı olarak giriş tensörlerini yeniden boyutlandırın.)
- Çıkarımı çağırın.
- Çı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
TensorFlow Lite ile çıkarım çalıştırmaya yönelik Java API, öncelikle Android ile kullanılmak üzere tasarlanmıştır, dolayısıyla bir Android kitaplığı bağımlılığı olarak mevcuttur: org.tensorflow:tensorflow-lite
.
Java'da, bir model yüklemek ve model çıkarımını yönlendirmek için Interpreter
sınıfını kullanacaksınız. Çoğu durumda ihtiyacınız olan tek API bu olabilir.
Bir .tflite
dosyasını kullanarak bir Interpreter
başlatabilirsiniz:
public Interpreter(@NotNull File modelFile);
Veya bir MappedByteBuffer
ile:
public Interpreter(@NotNull MappedByteBuffer mappedByteBuffer);
Her iki durumda da geçerli bir TensorFlow Lite modeli sağlamanız gerekir; aksi takdirde API, IllegalArgumentException
değerini atar. Bir Interpreter
başlatmak için MappedByteBuffer
kullanırsanız, Interpreter
kullanım ömrü boyunca değişmeden kalması gerekir.
Bir model üzerinde çı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 üç bağımsız değişken alır:
Girişler : imzadaki giriş adından bir giriş nesnesine kadar olan girişleri eşler.
Çıkışlar : İmzadaki çıkış adından çıkış verilerine çıkış eşlemesi için harita.
İmza Adı [isteğe bağlı]: İmza adı (Modelin tek imzası varsa boş bırakılabilir).
Modelin tanımlı imzaları olmadığında çıkarım yapmanın başka bir yolu. Interpreter.run()
çağırmanız yeterlidir. Örneğin:
try (Interpreter interpreter = new Interpreter(file_of_a_tensorflowlite_model)) {
interpreter.run(input, output);
}
run()
yöntemi yalnızca bir girdi alır ve yalnızca bir çıktı döndürür. Dolayısıyla, modelinizde birden fazla giriş veya birden fazla çıktı varsa bunun yerine şunu kullanın:
interpreter.runForMultipleInputsOutputs(inputs, map_of_indices_to_outputs);
Bu durumda, inputs
her giriş bir giriş tensörüne karşılık gelir ve map_of_indices_to_outputs
, çıkış tensörlerinin endekslerini karşılık gelen çıkış verilerine eşler.
Her iki durumda da tensör indeksleri, modeli oluşturduğunuzda TensorFlow Lite Converter'a verdiğiniz değerlere karşılık gelmelidir. input
tensörlerin sırasının TensorFlow Lite Dönüştürücüye verilen sırayla eşleşmesi gerektiğini unutmayın.
Interpreter
sınıfı ayrıca bir işlem adı kullanarak herhangi bir model girişinin veya çıkışının dizinini almanız için kullanışlı işlevler de sağlar:
public int getInputIndex(String opName);
public int getOutputIndex(String opName);
opName
modelde geçerli bir işlem değilse IllegalArgumentException
oluşturur.
Ayrıca Interpreter
kaynakların sahibi olduğuna dikkat edin. Bellek sızıntısını önlemek için kaynakların aşağıdakiler tarafından kullanıldıktan sonra serbest bırakılması gerekir:
interpreter.close();
Java ile örnek bir proje için Android görüntü sınıflandırma örneğine bakın.
Desteklenen veri türleri (Java'da)
TensorFlow Lite'ı kullanmak için giriş ve çıkış tensörlerinin veri türleri aşağıdaki temel türlerden biri olmalıdır:
-
float
-
int
-
long
-
byte
String
türleri de desteklenir ancak bunlar ilkel türlerden farklı şekilde kodlanır. Özellikle, bir Tensör dizisinin şekli Tensördeki dizelerin sayısını ve düzenini belirler; her öğenin kendisi değişken uzunlukta bir dizedir. Bu anlamda, Tensörün (bayt) boyutu yalnızca şekil ve türden hesaplanamaz ve sonuç olarak dizeler tek, düz bir ByteBuffer
argümanı olarak sağlanamaz. Bu sayfada bazı örnekleri görebilirsiniz.
Integer
ve Float
gibi kutulu türler de dahil olmak üzere başka veri türleri kullanılırsa bir IllegalArgumentException
oluşturulur.
Girişler
Her giriş, desteklenen temel türlerin bir dizisi veya çok boyutlu dizisi veya uygun boyutta ham bir ByteBuffer
olmalıdır. Giriş bir dizi veya çok boyutlu dizi ise, ilişkili giriş tensörü çıkarım zamanında dizinin boyutlarına göre dolaylı olarak yeniden boyutlandırılacaktır. Giriş bir ByteBuffer ise, arayan kişinin çıkarımı çalıştırmadan önce ilk olarak ilişkili giriş tensörünü ( Interpreter.resizeInput()
aracılığıyla) manuel olarak yeniden boyutlandırması gerekir.
ByteBuffer
kullanırken, doğrudan bayt arabelleklerini kullanmayı tercih edin, çünkü bu, Interpreter
gereksiz kopyalardan kaçınmasına olanak tanır. ByteBuffer
doğrudan bayt arabelleğiyse sırası ByteOrder.nativeOrder()
olmalıdır. Model çıkarımı için kullanıldıktan sonra model çıkarımı bitene kadar değişmeden kalmalıdır.
Çıkışlar
Her çıktı, desteklenen temel türlerin bir dizisi veya çok boyutlu dizisi veya uygun boyutta bir ByteBuffer olmalıdır. Bazı modellerin, çıkış tensörlerinin şeklinin girişe bağlı olarak değişebileceği dinamik çıkışlara sahip olduğunu unutmayın. Bunu mevcut Java çıkarım API'si ile halletmenin doğrudan 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, Cocoapods'un TensorFlowLiteSwift
Pod'unda mevcuttur.
Öncelikle TensorFlowLite
modülünü içe aktarmanız gerekir.
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ükleme ve çalıştırma
Platform: iOS
Objective-C API, Cocoapods'un TensorFlowLiteObjC
Pod'unda mevcuttur.
Öncelikle TensorFlowLite
modülünü içe aktarmanız gerekir.
@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'yi kullanma
Şu anda Objective-C API delegeleri desteklemiyor. Temsilcileri Objective-C koduyla kullanmak için doğrudan temel C API'sini çağırmanız gerekir.
#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);
C++'da bir model yükleme ve çalıştırma
Platformlar: Android, iOS ve Linux
C++'da model FlatBufferModel
sınıfında saklanır. Bir TensorFlow Lite modelini kapsar ve modelin nerede saklandığına bağlı olarak bunu birkaç farklı yolla 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 modeli FlatBufferModel
nesnesi olarak aldığınıza göre, onu bir Interpreter
ile çalıştırabilirsiniz. Tek bir FlatBufferModel
birden fazla Interpreter
tarafından aynı anda kullanılabilir.
Interpreter
API'nin önemli kısımları aşağıdaki kod parçacığında gösterilmektedir. Şuna dikkat edilmelidir:
- Tensörler, dize karşılaştırmalarını (ve dize kitaplıklarına herhangi bir sabit bağımlılığı) önlemek için tamsayılarla temsil edilir.
- Bir tercümana eşzamanlı iş parçacıklarından erişilmemelidir.
- Giriş ve çıkış tensörleri için bellek ayırma, tensörleri yeniden boyutlandırdıktan hemen sonra
AllocateTensors()
çağrılarak tetiklenmelidir.
TensorFlow Lite'ın C++ ile en basit kullanımı şuna benzer:
// 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 minimal.cc
ve label_image.cc
bakın.
Python'da bir model yükleyin ve çalıştırın
Platform: Linux
Çıkarım çalıştırmaya yönelik Python API'si tf.lite
modülünde sağlanır. Buradan, bir model yüklemek ve çıkarım yapmak için çoğunlukla yalnızca tf.lite.Interpreter
ihtiyacınız vardır.
Aşağıdaki örnek, bir .tflite
dosyasını yüklemek ve rastgele giriş verileriyle çıkarım yapmak için Python yorumlayıcısının nasıl kullanılacağını gösterir:
Tanımlı bir SignatureDef ile SavedModel'den dönüştürme yapıyorsanız bu örnek önerilir. TensorFlow 2.5'ten itibaren mevcuttur
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)
Modeli önceden dönüştürülmüş bir .tflite
dosyası olarak yüklemeye alternatif olarak kodunuzu TensorFlow Lite Converter Python API ( tf.lite.TFLiteConverter
) ile birleştirerek Keras modelinizi TensorFlow Lite formatına dönüştürmenize ve ardından çıkarımı çalıştır:
import numpy as np
import tensorflow as tf
img = tf.keras.Input(shape=(64, 64, 3), name="img")
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
converter = tf.lite.TFLiteConverter.from_keras_model(tf.keras.models.Model(inputs=[img], outputs=[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 fazla Python örnek kodu için bkz. label_image.py
.
Dinamik şekil modeliyle çıkarımı çalıştırma
Dinamik giriş şekline sahip bir model çalıştırmak istiyorsanız çıkarımı çalıştırmadan önce giriş şeklini yeniden boyutlandırın . Aksi takdirde Tensorflow modellerindeki None
şekli, TFLite modellerinde 1
yer tutucusu ile değiştirilecektir.
Aşağıdaki örnekler, farklı dillerde çıkarımı çalıştırmadan önce giriş şeklinin nasıl yeniden boyutlandırılacağını gösterir. Tüm örneklerde giriş şeklinin [1/None, 10]
olarak tanımlandığı ve [3, 10]
olarak yeniden boyutlandırılması gerektiği varsayılmaktadır.
C++ örneği:
// Resize input tensors before allocate tensors
interpreter->ResizeInputTensor(/*tensor_index=*/0, std::vector<int>{3,10});
interpreter->AllocateTensors();
Python örneği:
# Load the TFLite model in TFLite Interpreter
interpreter = tf.lite.Interpreter(model_path=TFLITE_FILE_PATH)
# Resize input shape for dynamic shape model and allocate tensor
interpreter.resize_tensor_input(interpreter.get_input_details()[0]['index'], [3, 10])
interpreter.allocate_tensors()
# Get input and output tensors.
input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()
Desteklenen işlemler
TensorFlow Lite, bazı sınırlamalarla TensorFlow işlemlerinin bir alt kümesini destekler. İşlemlerin ve sınırlamaların tam listesi için TF Lite Ops sayfasına bakın.