احفظ التاريخ! يعود مؤتمر Google I / O من 18 إلى 20 مايو. سجل الآن
ترجمت واجهة Cloud Translation API‏ هذه الصفحة.
Switch to English

استنتاج TensorFlow Lite

يشير مصطلح الاستدلال إلى عملية تنفيذ نموذج TensorFlow Lite على الجهاز لعمل تنبؤات بناءً على بيانات الإدخال. لإجراء استنتاج باستخدام نموذج TensorFlow Lite ، يجب عليك تشغيله من خلال مترجم . تم تصميم مترجم TensorFlow Lite ليكون خفيفًا وسريعًا. يستخدم المترجم الفوري ترتيبًا بيانيًا ثابتًا ومخصص ذاكرة مخصصًا (أقل ديناميكية) لضمان الحد الأدنى من التحميل والتهيئة وزمن انتقال التنفيذ.

تصف هذه الصفحة كيفية الوصول إلى مترجم TensorFlow Lite وإجراء استنتاج باستخدام C ++ و Java و Python ، بالإضافة إلى روابط لمصادر أخرى لكل نظام أساسي مدعوم .

مفاهيم مهمة

عادةً ما يتبع استنتاج TensorFlow Lite الخطوات التالية:

  1. تحميل نموذج

    يجب عليك تحميل نموذج .tflite في الذاكرة ، والتي تحتوي على الرسم البياني لتنفيذ النموذج.

  2. تحويل البيانات

    لا تتطابق بيانات الإدخال الأولية للنموذج بشكل عام مع تنسيق بيانات الإدخال الذي يتوقعه النموذج. على سبيل المثال ، قد تحتاج إلى تغيير حجم صورة أو تغيير تنسيق الصورة لتتوافق مع النموذج.

  3. تشغيل الاستدلال

    تتضمن هذه الخطوة استخدام TensorFlow Lite API لتنفيذ النموذج. يتضمن خطوات قليلة مثل بناء المترجم الفوري ، وتخصيص الموترات ، كما هو موضح في الأقسام التالية.

  4. تفسير الإخراج

    عندما تتلقى نتائج من الاستدلال النموذجي ، يجب عليك تفسير الموترات بطريقة مفيدة مفيدة في تطبيقك.

    على سبيل المثال ، قد يعرض النموذج قائمة بالاحتمالات فقط. الأمر متروك لك لتعيين الاحتمالات للفئات ذات الصلة وتقديمها للمستخدم النهائي.

المنصات المدعومة

يتم توفير واجهات برمجة تطبيقات الاستدلال TensorFlow لمعظم الأنظمة الأساسية للجوال / المضمنة الشائعة مثل Android و iOS و Linux بلغات برمجة متعددة.

في معظم الحالات ، يعكس تصميم واجهة برمجة التطبيقات (API) تفضيلًا للأداء على سهولة الاستخدام. تم تصميم TensorFlow Lite للاستدلال السريع على الأجهزة الصغيرة ، لذلك لا ينبغي أن يكون مفاجئًا أن تحاول واجهات برمجة التطبيقات تجنب النسخ غير الضرورية على حساب الراحة. وبالمثل ، فإن الاتساق مع TensorFlow APIs لم يكن هدفًا واضحًا ومن المتوقع حدوث بعض التباين بين اللغات.

عبر جميع المكتبات ، تمكّنك TensorFlow Lite API من تحميل النماذج ومدخلات التغذية واسترداد مخرجات الاستدلال.

منصة أندرويد

على نظام Android ، يمكن إجراء استدلال TensorFlow Lite باستخدام واجهات برمجة تطبيقات Java أو C ++. توفر Java APIs الراحة ويمكن استخدامها مباشرة داخل فصول نشاط Android. توفر واجهات برمجة تطبيقات C ++ مزيدًا من المرونة والسرعة ، ولكنها قد تتطلب كتابة أغلفة JNI لنقل البيانات بين طبقات Java و C ++.

انظر أدناه للحصول على تفاصيل حول استخدام C ++ و Java ، أو اتبع Android Quickstart للحصول على برنامج تعليمي ومثال على التعليمات البرمجية.

مولد رمز المجمع TensorFlow Lite Android

بالنسبة لنموذج TensorFlow Lite المُحسَّن بالبيانات الوصفية ، يمكن للمطورين استخدام مُنشئ رمز المجمع TensorFlow Lite Android لإنشاء كود غلاف خاص بالنظام الأساسي. يزيل رمز المجمع الحاجة إلى التفاعل مباشرة مع ByteBuffer على Android. بدلاً من ذلك ، يمكن للمطورين التفاعل مع نموذج TensorFlow Lite باستخدام كائنات مكتوبة مثل Bitmap و Rect . لمزيد من المعلومات ، يرجى الرجوع إلى منشئ أكواد المجمّع TensorFlow Lite Android .

منصة iOS

على نظام iOS ، يتوفر TensorFlow Lite مع مكتبات iOS أصلية مكتوبة بلغة Swift و Objective-C . يمكنك أيضًا استخدام C API مباشرة في أكواد Objective-C.

انظر أدناه للحصول على تفاصيل حول استخدام Swift و Objective-C وواجهة برمجة تطبيقات C أو اتبع بدء التشغيل السريع لنظام iOS للحصول على برنامج تعليمي ومثال على التعليمات البرمجية

منصة لينوكس

على منصات Linux (بما في ذلك Raspberry Pi ) ، يمكنك تشغيل الاستنتاجات باستخدام TensorFlow Lite APIs المتاحة في C ++ و Python ، كما هو موضح في الأقسام التالية.

تشغيل نموذج

يتضمن تشغيل نموذج TensorFlow Lite بضع خطوات بسيطة:

  1. قم بتحميل النموذج في الذاكرة.
  2. قم ببناء Interpreter بناءً على نموذج موجود.
  3. تعيين قيم موتر الإدخال. (قم بتغيير حجم موتر الإدخال اختياريًا إذا كانت الأحجام المحددة مسبقًا غير مرغوبة.)
  4. استدعاء الاستدلال.
  5. قراءة قيم موتر الإخراج.

تصف الأقسام التالية كيف يمكن تنفيذ هذه الخطوات في كل لغة.

قم بتحميل وتشغيل نموذج في Java

النظام الأساسي: Android

تم تصميم Java API لتشغيل الاستدلال باستخدام TensorFlow Lite بشكل أساسي للاستخدام مع Android ، لذا فهي متاحة org.tensorflow:tensorflow-lite مكتبة Android: org.tensorflow:tensorflow-lite .

في Java ، ستستخدم فئة Interpreter الفوري لتحميل نموذج واستدلال نموذج محرك الأقراص. في كثير من الحالات ، قد يكون هذا هو API الوحيد الذي تحتاجه.

يمكنك تهيئة Interpreter .tflite باستخدام ملف .tflite :

public Interpreter(@NotNull File modelFile);

أو باستخدام MappedByteBuffer :

public Interpreter(@NotNull MappedByteBuffer mappedByteBuffer);

في كلتا الحالتين ، يجب عليك تقديم نموذج TensorFlow Lite صالح أو تقوم API بإلقاء IllegalArgumentException . إذا كنت تستخدم MappedByteBuffer لتهيئة Interpreter MappedByteBuffer ، فيجب أن يظل بدون تغيير طوال عمر Interpreter MappedByteBuffer .

الطريقة المفضلة لتشغيل الاستدلال على نموذج هي استخدام التوقيعات - متوفر للنماذج المحولة بدءًا من 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");
}

تأخذ طريقة runSignature ثلاث وسائط:

  • المدخلات : تعيين المدخلات من اسم الإدخال في التوقيع إلى كائن الإدخال.

  • المخرجات : تعيين لتعيين الإخراج من اسم الإخراج في التوقيع إلى بيانات الإخراج.

  • اسم التوقيع [اختياري]: اسم التوقيع (يمكن تركه فارغًا إذا كان للنموذج توقيع واحد).

طريقة أخرى لتشغيل استنتاج عندما لا يحتوي النموذج على توقيعات محددة. ما عليك سوى الاتصال بـ Interpreter.run() . على سبيل المثال:

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

تأخذ طريقة run() مدخلاً واحدًا فقط وتُرجع ناتجًا واحدًا فقط. لذلك إذا كان النموذج الخاص بك يحتوي على مدخلات متعددة أو مخرجات متعددة ، فاستخدم بدلاً من ذلك:

03 ديب 3 e0

في هذه الحالة ، يتوافق كل إدخال في inputs مع موتر الإدخال و map_of_indices_to_outputs خرائط مؤشرات موتر الإخراج إلى بيانات الإخراج المقابلة.

في كلتا الحالتين ، يجب أن تتوافق مؤشرات الموتر مع القيم التي أعطيتها لمحول TensorFlow Lite عند إنشاء النموذج. اعلم أن ترتيب الموترات في input يجب أن يتطابق مع الترتيب المعطى لمحول TensorFlow Lite.

توفر فئة Interpreter الفوري أيضًا وظائف مناسبة لك للحصول على فهرس لأي نموذج إدخال أو إخراج باستخدام اسم العملية:

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

إذا لم يكن opName عملية صالحة في النموذج ، فإنه يطرح IllegalArgumentException .

احذر أيضًا من أن Interpreter يمتلك الموارد. لتجنب حدوث تسرب للذاكرة ، يجب تحرير الموارد بعد استخدامها من خلال:

interpreter.close();

للحصول على مثال لمشروع باستخدام Java ، راجع نموذج تصنيف صور Android .

أنواع البيانات المدعومة (في Java)

لاستخدام TensorFlow Lite ، يجب أن تكون أنواع البيانات لموترات الإدخال والإخراج أحد الأنواع الأولية التالية:

  • float
  • int
  • long
  • byte

أنواع String مدعومة أيضًا ، لكن يتم ترميزها بشكل مختلف عن الأنواع الأولية. على وجه الخصوص ، يحدد شكل سلسلة Tensor عدد وترتيب السلاسل في Tensor ، حيث يكون كل عنصر بحد ذاته سلسلة متغيرة الطول. بهذا المعنى ، لا يمكن حساب حجم (بايت) Tensor من الشكل والنوع فقط ، وبالتالي لا يمكن توفير ByteBuffer كوسيطة ByteBuffer واحدة مسطحة.

إذا أنواع البيانات الأخرى، بما في ذلك أنواع محاصر مثل Integer و Float ، وتستخدم، وهي IllegalArgumentException سيتم طرح.

المدخلات

يجب أن يكون كل إدخال عبارة عن مصفوفة أو مصفوفة متعددة الأبعاد من الأنواع الأولية المدعومة ، أو ByteBuffer خام ByteBuffer المناسب. إذا كان الإدخال عبارة عن صفيف أو مصفوفة متعددة الأبعاد ، فسيتم تغيير حجم موتر الإدخال المرتبط ضمنيًا إلى أبعاد الصفيف في وقت الاستدلال. إذا كان الإدخال ByteBuffer ، يجب على المتصل أولاً تغيير حجم موتر الإدخال المرتبط يدويًا (عبر Interpreter.resizeInput() ) قبل تشغيل الاستدلال.

عند استخدام ByteBuffer ، ويفضل استخدام مخازن بايت مباشرة، وهذا يسمح لل Interpreter لتجنب النسخ غير الضرورية. إذا كان ByteBuffer عبارة عن مخزن مؤقت للبايت المباشر ، فيجب أن يكون ترتيب ByteOrder.nativeOrder() . بعد استخدامه لاستدلال النموذج ، يجب أن يظل بدون تغيير حتى ينتهي استنتاج النموذج.

النواتج

يجب أن يكون كل ناتج مصفوفة أو مصفوفة متعددة الأبعاد من الأنواع الأولية المدعومة ، أو ByteBuffer بالحجم المناسب. لاحظ أن بعض الطرز تحتوي على مخرجات ديناميكية ، حيث يمكن أن يختلف شكل موتر الإخراج اعتمادًا على المدخلات. لا توجد طريقة مباشرة للتعامل مع هذا الأمر باستخدام واجهة برمجة تطبيقات استدلال جافا الحالية ، ولكن الإضافات المخططة ستجعل ذلك ممكنًا.

قم بتحميل وتشغيل نموذج في Swift

النظام الأساسي: iOS

يتوفر Swift API في TensorFlowLiteSwift Pod من Cocoapods.

أولاً ، تحتاج إلى استيراد وحدة 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...
}

قم بتحميل وتشغيل نموذج في Objective-C

النظام الأساسي: iOS

يتوفر Objective-C API في TensorFlowLiteObjC Pod من Cocoapods.

أولاً ، تحتاج إلى استيراد وحدة 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:&amp;error];
if (error != nil) { /* Error handling... */ }

استخدام C API في كود Objective-C

لا تدعم واجهة برمجة تطبيقات Objective-C حاليًا المفوضين. من أجل استخدام المندوبين برمز Objective-C ، تحتاج إلى الاتصال مباشرةً بواجهة برمجة تطبيقات C الأساسية.

#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 ++

المنصات: Android و iOS و Linux

في C ++ ، يتم تخزين النموذج في فئة FlatBufferModel . إنها تغلف نموذج TensorFlow Lite ويمكنك بنائه بطريقتين مختلفتين ، اعتمادًا على مكان تخزين النموذج:

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

الآن بعد أن أصبح لديك النموذج ككائن FlatBufferModel ، يمكنك تنفيذه باستخدام Interpreter FlatBufferModel . يمكن استخدام FlatBufferModel واحد في وقت واحد بواسطة أكثر من Interpreter .

يتم عرض الأجزاء المهمة من Interpreter API في مقتطف الشفرة أدناه. وتجدر الإشارة إلى أن:

  • يتم تمثيل الموترات بأعداد صحيحة لتجنب مقارنات السلاسل (وأي تبعية ثابتة على مكتبات السلاسل).
  • يجب عدم الوصول إلى المترجم من سلاسل الرسائل المتزامنة.
  • يجب تشغيل تخصيص الذاكرة لموترات الإدخال والإخراج عن طريق استدعاء AllocateTensors() مباشرة بعد تغيير حجم الموترات.

يبدو أبسط استخدام لـ TensorFlow Lite مع C ++ كما يلي:

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

لمزيد من أمثلة التعليمات البرمجية ، راجع minimal.cc و label_image.cc .

قم بتحميل وتشغيل نموذج في بايثون

النظام الأساسي: Linux

يتم توفير واجهة برمجة تطبيقات Python لتشغيل الاستدلال في الوحدة النمطية tf.lite . من خلاله ، ستحتاج في الغالب فقط إلى tf.lite.Interpreter لتحميل نموذج وتشغيل استنتاج.

يوضح المثال التالي كيفية استخدام مترجم Python لتحميل ملف .tflite وتشغيل الاستدلال ببيانات الإدخال العشوائية:

يوصى بهذا المثال إذا كنت تقوم بالتحويل من SavedModel باستخدام SignatureDef محدد. متاح بدءًا من 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'])

مثال آخر إذا لم يكن لدى النموذج تعريفات SignatureDefs.

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)

كبديل لتحميل النموذج كملف .tflite تحويله .tflite ، يمكنك دمج التعليمات البرمجية الخاصة بك مع TensorFlow Lite Converter Python API ( tf.lite.TFLiteConverter ) ، مما يسمح لك بتحويل نموذج TensorFlow الخاص بك إلى تنسيق TensorFlow Lite ثم تشغيل الاستدلال:

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

لمزيد من نموذج كود Python ، راجع label_image.py .

نصيحة: قم بتشغيل help(tf.lite.Interpreter) في محطة Python للحصول على وثائق مفصلة حول المترجم.

العمليات المدعومة

يدعم TensorFlow Lite مجموعة فرعية من عمليات TensorFlow مع بعض القيود. للحصول على قائمة كاملة بالعمليات والقيود ، راجع صفحة TF Lite Ops .