از یک مدل سفارشی TensorFlow Lite در اندروید استفاده کنید

If your app uses custom TensorFlow Lite models, you can use Firebase ML to deploy your models. با استقرار مدل‌ها با Firebase، می‌توانید حجم دانلود اولیه برنامه خود را کاهش دهید و مدل‌های ML برنامه خود را بدون انتشار نسخه جدیدی از برنامه خود به‌روزرسانی کنید. And, with Remote Config and A/B Testing , you can dynamically serve different models to different sets of users.

مدل های TensorFlow Lite

TensorFlow Lite models are ML models that are optimized to run on mobile devices. برای دریافت یک مدل TensorFlow Lite:

قبل از شروع

  1. اگر قبلاً این کار را نکرده‌اید، Firebase را به پروژه Android خود اضافه کنید .
  2. در فایل Gradle ماژول (سطح برنامه) خود (معمولا <project>/<app-module>/build.gradle.kts یا <project>/<app-module>/build.gradle )، وابستگی را برای کتابخانه دانلود کننده مدل Firebase ML برای Android اضافه کنید. توصیه می‌کنیم از Firebase Android BoM برای کنترل نسخه‌سازی کتابخانه استفاده کنید.

    Also, as part of setting up Firebase ML model downloader, you need to add the TensorFlow Lite SDK to your app.

    dependencies {
        // Import the BoM for the Firebase platform
        implementation(platform("com.google.firebase:firebase-bom:34.3.0"))
    
        // 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")
    }

    با استفاده از Firebase Android BoM ، برنامه شما همیشه از نسخه‌های سازگار کتابخانه‌های Firebase Android استفاده می‌کند.

    (جایگزین) وابستگی های کتابخانه Firebase را بدون استفاده از BoM اضافه کنید

    اگر تصمیم گرفتید از Firebase BoM استفاده نکنید، باید هر نسخه کتابخانه 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:26.0.1")
    // Also add the dependency for the TensorFlow Lite library and specify its version implementation("org.tensorflow:tensorflow-lite:2.3.0")
    }
  3. In your app's manifest, declare that INTERNET permission is required:
    <uses-permission android:name="android.permission.INTERNET" />

1. مدل خود را مستقر کنید

Deploy your custom TensorFlow models using either the Firebase console or the Firebase Admin Python and Node.js SDKs. به استقرار و مدیریت مدل‌های سفارشی مراجعه کنید.

پس از اینکه یک مدل سفارشی را به پروژه Firebase خود اضافه کردید، می‌توانید با استفاده از نامی که مشخص کرده‌اید به مدل در برنامه‌های خود ارجاع دهید. At any time, you can deploy a new TensorFlow Lite model and download the new model onto users' devices by calling getModel() (see below).

2. مدل را در دستگاه دانلود کنید و یک مفسر TensorFlow Lite را مقداردهی اولیه کنید

برای استفاده از مدل TensorFlow Lite در برنامه خود، ابتدا از Firebase ML SDK برای دانلود آخرین نسخه مدل در دستگاه استفاده کنید. Then, instantiate a TensorFlow Lite interpreter with the model.

برای شروع دانلود مدل، متد getModel() دانلود کننده مدل را فراخوانی کنید، نامی را که به مدل اختصاص داده اید هنگام آپلود کردن، مشخص کنید که آیا می خواهید همیشه آخرین مدل را دانلود کنید، و شرایطی که می خواهید اجازه دانلود را بدهید.

شما می توانید از بین سه رفتار دانلود انتخاب کنید:

نوع دانلود توضیحات
LOCAL_MODEL مدل محلی را از دستگاه دریافت کنید. If there is no local model available, this behaves like LATEST_MODEL . Use this download type if you are not interested in checking for model updates. برای مثال، شما از Remote Config برای بازیابی نام مدل ها استفاده می کنید و همیشه مدل ها را با نام های جدید آپلود می کنید (توصیه می شود).
LOCAL_MODEL_UPDATE_IN_BACKGROUND مدل محلی را از دستگاه دریافت کنید و به روز رسانی مدل را در پس زمینه شروع کنید. If there is no local model available, this behaves like LATEST_MODEL .
LATEST_MODEL آخرین مدل را دریافت کنید. اگر مدل محلی آخرین نسخه باشد، مدل محلی را برمی گرداند. در غیر این صورت آخرین مدل را دانلود کنید. این رفتار تا زمانی که آخرین نسخه دانلود نشود مسدود می شود (توصیه نمی شود). Use this behavior only in cases where you explicitly need the latest version.

باید عملکردهای مربوط به مدل را غیرفعال کنید - برای مثال، خاکستری کردن یا پنهان کردن بخشی از رابط کاربری خود - تا زمانی که تأیید کنید مدل دانلود شده است.

Kotlin

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. استنتاج بر روی داده های ورودی انجام دهید

اشکال ورودی و خروجی مدل خود را دریافت کنید

The TensorFlow Lite model interpreter takes as input and produces as output one or more multidimensional arrays. این آرایه ها حاوی مقادیر byte ، int ، long یا float هستند. قبل از اینکه بتوانید داده ها را به یک مدل منتقل کنید یا از نتیجه آن استفاده کنید، باید تعداد و ابعاد ("شکل") آرایه هایی که مدل شما استفاده می کند را بدانید.

اگر مدل را خودتان ساخته‌اید، یا اگر فرمت ورودی و خروجی مدل مستند است، ممکن است قبلاً این اطلاعات را داشته باشید. اگر شکل و نوع داده ورودی و خروجی مدل خود را نمی دانید، می توانید از مفسر TensorFlow Lite برای بررسی مدل خود استفاده کنید. به عنوان مثال:

پایتون

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

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 به اندازه کافی بزرگ اختصاص دهید تا خروجی مدل را در خود داشته باشد و بافر ورودی و بافر خروجی را به متد run() مترجم TensorFlow Lite منتقل کنید. به عنوان مثال، برای شکل خروجی [1 1000] مقادیر ممیز شناور:

Kotlin

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

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 ML قرار می‌دهید، Firebase ML آنها را در قالب استاندارد پروتوباف سریالی در حافظه محلی ذخیره می‌کند.

در تئوری، این بدان معنی است که هر کسی می تواند مدل شما را کپی کند. با این حال، در عمل، بیشتر مدل‌ها به قدری برنامه‌های کاربردی خاص هستند و به‌وسیله بهینه‌سازی‌ها مبهم هستند که خطر آن مشابه خطر جداسازی و استفاده مجدد کد شما توسط رقبا است. Nevertheless, you should be aware of this risk before you use a custom model in your app.

در Android API سطح 21 (Lollipop) و جدیدتر، مدل در فهرستی دانلود می‌شود که از پشتیبان‌گیری خودکار حذف شده است.

در Android API سطح 20 و بالاتر، مدل در فهرستی به نام com.google.firebase.ml.custom.models در حافظه داخلی برنامه-خصوصی دانلود می شود. اگر پشتیبان‌گیری از فایل را با استفاده از BackupAgent فعال کرده‌اید، می‌توانید این فهرست را حذف کنید.