استخدام نموذج TensorFlow Lite المخصّص على Android

إذا كان تطبيقك يستخدم تنسيقًا مخصّصًا TensorFlow Lite، يمكنك استخدام تعلُّم الآلة في Firebase لنشر نماذجك. من ونشر نماذج باستخدام Firebase، يمكنك تقليل حجم التنزيل الأولي تطبيقك وتحديث نماذج تعلُّم الآلة في تطبيقك بدون طرح إصدار جديد من تطبيقك. وباستخدام "الإعداد عن بُعد" و"اختبار A/B"، يمكنك إجراء ما يلي بشكل ديناميكي نماذج مختلفة لمجموعات مختلفة من المستخدمين.

طُرز TensorFlow Lite

نماذج TensorFlow Lite هي نماذج تعلُّم الآلة التي تم تحسينها لتعمل على الأجهزة الجوّالة. الأجهزة. للحصول على نموذج TensorFlow Lite، اتّبِع الخطوات التالية:

قبل البدء

  1. إذا لم تكن قد فعلت ذلك بالفعل، إضافة Firebase إلى مشروع Android
  2. في ملف Gradle للوحدة (على مستوى التطبيق) (عادةً <project>/<app-module>/build.gradle.kts أو <project>/<app-module>/build.gradle)، إضافة الاعتمادية لمكتبة أدوات تنزيل نماذج تعلُّم الآلة في Firebase لنظام التشغيل Android. ننصح باستخدام قائمة مواد العرض لنظام Android في Firebase للتحكم في إصدارات المكتبة.

    وكجزء من عملية إعداد أداة تنزيل نموذج تعلُّم الآلة من Firebase، عليك إضافة حزمة تطوير البرامج (SDK) من TensorFlow Lite إلى تطبيقك.

    dependencies {
        // Import the BoM for the Firebase platform
        implementation(platform("com.google.firebase:firebase-bom:33.1.2"))
    
        // Add the dependency for the Firebase ML model downloader library
        // When using the BoM, you don't specify versions in Firebase library dependencies
        implementation("com.google.firebase:firebase-ml-modeldownloader")
    // Also add the dependency for the TensorFlow Lite library and specify its version implementation("org.tensorflow:tensorflow-lite:2.3.0")
    }

    باستخدام قائمة قائمتها التشغيلية (Android BoM) من Firebase سيستخدم تطبيقك دائمًا إصدارات متوافقة من مكتبات Android في Firebase.

    (بديل) إضافة تبعيات مكتبة Firebase بدون استخدام BoM

    إذا اخترت عدم استخدام قائمة عناصر Firebase، يجب تحديد كل إصدار من إصدارات مكتبة Firebase. في سطر التبعية.

    يُرجى ملاحظة أنّه إذا كنت تستخدم مكتبات Firebase متعددة في تطبيقك، سنعتمد بشدة التوصية باستخدام BoM لإدارة نسخ المكتبة، مما يضمن نشر جميع النسخ متوافقة مع الأجهزة الجوّالة

    dependencies {
        // Add the dependency for the Firebase ML model downloader library
        // When NOT using the BoM, you must specify versions in Firebase library dependencies
        implementation("com.google.firebase:firebase-ml-modeldownloader:25.0.0")
    // Also add the dependency for the TensorFlow Lite library and specify its version implementation("org.tensorflow:tensorflow-lite:2.3.0")
    }
    هل تبحث عن وحدة مكتبة خاصة بلغة Kotlin؟ ستبدأ بعد تشرين الأول (أكتوبر) 2023 (الإصدار 32.5.0 من Firebase BoM)، بإمكان مطوّري برامج Kotlin وJava تعتمد على وحدة المكتبة الرئيسية (لمزيد من التفاصيل، راجع الأسئلة الشائعة حول هذه المبادرة).
  3. في بيان تطبيقك، عليك الإشارة إلى أنّه يجب الحصول على إذن INTERNET:
    <uses-permission android:name="android.permission.INTERNET" />

1- نشر النموذج

انشر نماذج TensorFlow المخصّصة باستخدام وحدة تحكُّم Firebase أو حزم تطوير البرامج (SDK) الخاصة بمشرفي Firebase وهما Python وNode.js. عرض نشر النماذج المخصَّصة وإدارتها

بعد إضافة نموذج مخصّص إلى مشروعك على Firebase، يمكنك الرجوع إلى النموذج في تطبيقاتك باستخدام الاسم الذي حددته. يمكنك في أي وقت نشر نموذج TensorFlow Lite الجديد وتنزيل النموذج الجديد على الأجهزة بواسطة الاتصال بـ getModel() (انظر أدناه).

2- تنزيل النموذج على الجهاز وإعداد أداة الترجمة الفورية من TensorFlow Lite

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

لبدء تنزيل النموذج، يمكنك استدعاء طريقة getModel() لأداة تنزيل النموذج، تحديد الاسم الذي عينته للنموذج عند تحميله، سواء ترغب دائمًا في تنزيل أحدث طراز، والحالات التي بموجبها يريدون السماح بالتنزيل.

يمكنك الاختيار من بين ثلاثة سلوكيات للتنزيل:

نوع عملية التنزيل الوصف
النموذج المحلي الحصول على الطراز المحلي من الجهاز في حال عدم توفُّر نموذج محلي، سيتم يتصرف مثل LATEST_MODEL. استخدام هذه المسودة نوع التنزيل إذا لم تكن مهتمًا البحث عن تحديثات النموذج. على سبيل المثال: تستخدم "الإعداد عن بُعد" لاسترداد أسماء النماذج ودائمًا تحميل النماذج تحت أسماء جديدة (يُنصح بهذا الخيار)
LOCAL_MODEL_UPDATE_IN_BACKGROUND الحصول على الطراز المحلي من الجهاز تحديث النموذج في الخلفية. في حال عدم توفُّر نموذج محلي، سيتم يتصرف مثل LATEST_MODEL.
LATEST_MODEL احصل على أحدث طراز. إذا كان النموذج المحلي يعرض الإصدار المحلي model. أو يمكنك تنزيل أحدث إصدار model. سيتم حظر هذا السلوك حتى تنزيل أحدث إصدار (ليس (يوصى به). لا تستخدم هذا السلوك إلا في الحالات التي تحتاج فيها صراحة إلى أحدث .

ينبغي لك تعطيل الوظائف المتعلقة بالنموذج، على سبيل المثال، الوضع الرمادي أو إخفاء جزء من واجهة المستخدم — إلى أن تتأكد من تنزيل النموذج.

Kotlin+KTX

val conditions = CustomModelDownloadConditions.Builder()
        .requireWifi()  // Also possible: .requireCharging() and .requireDeviceIdle()
        .build()
FirebaseModelDownloader.getInstance()
        .getModel("your_model", DownloadType.LOCAL_MODEL_UPDATE_IN_BACKGROUND,
            conditions)
        .addOnSuccessListener { model: CustomModel? ->
            // Download complete. Depending on your app, you could enable the ML
            // feature, or switch from the local model to the remote model, etc.

            // The CustomModel object contains the local path of the model file,
            // which you can use to instantiate a TensorFlow Lite interpreter.
            val modelFile = model?.file
            if (modelFile != null) {
                interpreter = Interpreter(modelFile)
            }
        }

Java

CustomModelDownloadConditions conditions = new CustomModelDownloadConditions.Builder()
    .requireWifi()  // Also possible: .requireCharging() and .requireDeviceIdle()
    .build();
FirebaseModelDownloader.getInstance()
    .getModel("your_model", DownloadType.LOCAL_MODEL_UPDATE_IN_BACKGROUND, conditions)
    .addOnSuccessListener(new OnSuccessListener<CustomModel>() {
      @Override
      public void onSuccess(CustomModel model) {
        // Download complete. Depending on your app, you could enable the ML
        // feature, or switch from the local model to the remote model, etc.

        // The CustomModel object contains the local path of the model file,
        // which you can use to instantiate a TensorFlow Lite interpreter.
        File modelFile = model.getFile();
        if (modelFile != null) {
            interpreter = new Interpreter(modelFile);
        }
      }
    });

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

3- إجراء استنتاج على بيانات الإدخال

الحصول على أشكال المدخلات والمخرجات لنموذجك

يستخدم مترجم النموذج TensorFlow Lite كمدخل وينتج كمخرج. واحدة أو أكثر من الصفائف متعددة الأبعاد. تحتوي هذه الصفائف على byte أو int أو long أو float القيم. قبل أن تتمكن من تمرير البيانات إلى نموذج أو استخدام نتيجته، يجب أن تعرف عدد الصفائف التي يستخدمها نموذجك وأبعادها ("الشكل").

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

Python

import tensorflow as tf

interpreter = tf.lite.Interpreter(model_path="your_model.tflite")
interpreter.allocate_tensors()

# Print input shape and type
inputs = interpreter.get_input_details()
print('{} input(s):'.format(len(inputs)))
for i in range(0, len(inputs)):
    print('{} {}'.format(inputs[i]['shape'], inputs[i]['dtype']))

# Print output shape and type
outputs = interpreter.get_output_details()
print('\n{} output(s):'.format(len(outputs)))
for i in range(0, len(outputs)):
    print('{} {}'.format(outputs[i]['shape'], outputs[i]['dtype']))

مثال على الإخراج:

1 input(s):
[  1 224 224   3] <class 'numpy.float32'>

1 output(s):
[1 1000] <class 'numpy.float32'>

تشغيل ميزة "الترجمة الفورية"

بعد تحديد تنسيق مدخلات ومخرجات النموذج، احصل على إدخال البيانات وإجراء أي عمليات تحويل على البيانات اللازمة للحصول على مدخلاً للشكل المناسب لنموذجك.

فعلى سبيل المثال، إذا كان لديك نموذج تصنيف صور به شكل إدخال [1 224 224 3] قيمة النقطة العائمة، يمكنك إنشاء إدخال ByteBuffer من كائن Bitmap كما هو موضح في المثال التالي:

Kotlin+KTX

val bitmap = Bitmap.createScaledBitmap(yourInputImage, 224, 224, true)
val input = ByteBuffer.allocateDirect(224*224*3*4).order(ByteOrder.nativeOrder())
for (y in 0 until 224) {
    for (x in 0 until 224) {
        val px = bitmap.getPixel(x, y)

        // Get channel values from the pixel value.
        val r = Color.red(px)
        val g = Color.green(px)
        val b = Color.blue(px)

        // Normalize channel values to [-1.0, 1.0]. This requirement depends on the model.
        // For example, some models might require values to be normalized to the range
        // [0.0, 1.0] instead.
        val rf = (r - 127) / 255f
        val gf = (g - 127) / 255f
        val bf = (b - 127) / 255f

        input.putFloat(rf)
        input.putFloat(gf)
        input.putFloat(bf)
    }
}

Java

Bitmap bitmap = Bitmap.createScaledBitmap(yourInputImage, 224, 224, true);
ByteBuffer input = ByteBuffer.allocateDirect(224 * 224 * 3 * 4).order(ByteOrder.nativeOrder());
for (int y = 0; y < 224; y++) {
    for (int x = 0; x < 224; x++) {
        int px = bitmap.getPixel(x, y);

        // Get channel values from the pixel value.
        int r = Color.red(px);
        int g = Color.green(px);
        int b = Color.blue(px);

        // Normalize channel values to [-1.0, 1.0]. This requirement depends
        // on the model. For example, some models might require values to be
        // normalized to the range [0.0, 1.0] instead.
        float rf = (r - 127) / 255.0f;
        float gf = (g - 127) / 255.0f;
        float bf = (b - 127) / 255.0f;

        input.putFloat(rf);
        input.putFloat(gf);
        input.putFloat(bf);
    }
}

بعد ذلك، خصِّص ByteBuffer كبيرة بما يكفي لاحتواء ناتج النموذج تمرير المخزن المؤقت للإدخال والمخزن المؤقت للمخرجات إلى مترجم TensorFlow Lite طريقة run(). على سبيل المثال، لشكل إخراج [1 1000] نقطة عائمة القيم التالية:

Kotlin+KTX

val bufferSize = 1000 * java.lang.Float.SIZE / java.lang.Byte.SIZE
val modelOutput = ByteBuffer.allocateDirect(bufferSize).order(ByteOrder.nativeOrder())
interpreter?.run(input, modelOutput)

Java

int bufferSize = 1000 * java.lang.Float.SIZE / java.lang.Byte.SIZE;
ByteBuffer modelOutput = ByteBuffer.allocateDirect(bufferSize).order(ByteOrder.nativeOrder());
interpreter.run(input, modelOutput);

وتعتمد كيفية استخدامك للمخرجات على النموذج الذي تستخدمه.

على سبيل المثال، إذا كنت بصدد إجراء التصنيف، كخطوة تالية، يمكنك أن وتعيين فهارس النتيجة بالتسميات التي تمثلها:

Kotlin+KTX

modelOutput.rewind()
val probabilities = modelOutput.asFloatBuffer()
try {
    val reader = BufferedReader(
            InputStreamReader(assets.open("custom_labels.txt")))
    for (i in probabilities.capacity()) {
        val label: String = reader.readLine()
        val probability = probabilities.get(i)
        println("$label: $probability")
    }
} catch (e: IOException) {
    // File not found?
}

Java

modelOutput.rewind();
FloatBuffer probabilities = modelOutput.asFloatBuffer();
try {
    BufferedReader reader = new BufferedReader(
            new InputStreamReader(getAssets().open("custom_labels.txt")));
    for (int i = 0; i < probabilities.capacity(); i++) {
        String label = reader.readLine();
        float probability = probabilities.get(i);
        Log.i(TAG, String.format("%s: %1.4f", label, probability));
    }
} catch (IOException e) {
    // File not found?
}

الملحق: أمان النموذج

بغض النظر عن كيفية إتاحة طُرز TensorFlow Lite تخزنها تكنولوجيا تعلُّم الآلة في Firebase، بتنسيق أولي متسلسل قياسي في التخزين المحلي.

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

في المستوى 21 من واجهة برمجة تطبيقات Android (Lollipop) والإصدارات الأحدث، يتم تنزيل النموذج إلى الدليل استبعاده من ميزة الاحتفاظ بنسخة احتياطية تلقائيًا.

في المستوى 20 من واجهة برمجة تطبيقات Android والإصدارات الأقدم، يتم تنزيل النموذج إلى دليل. باسم com.google.firebase.ml.custom.models في خصوصية التطبيق وحدة التخزين الداخلية. في حال تفعيل الاحتفاظ بنسخة احتياطية من الملفات باستخدام BackupAgent، يمكنك اختيار استبعاد هذا الدليل.