Android এ একটি কাস্টম TensorFlow Lite মডেল ব্যবহার করুন

যদি আপনার অ্যাপ কাস্টম TensorFlow Lite মডেল ব্যবহার করে, তাহলে আপনি আপনার মডেলগুলি স্থাপন করতে Firebase ML ব্যবহার করতে পারেন। Firebase এর সাথে মডেল স্থাপন করে, আপনি আপনার অ্যাপের প্রাথমিক ডাউনলোডের আকার কমাতে পারেন এবং আপনার অ্যাপের নতুন সংস্করণ প্রকাশ না করেই আপনার অ্যাপের ML মডেল আপডেট করতে পারেন। এবং, রিমোট কনফিগারেশন এবং A/B টেস্টিং এর সাথে, আপনি গতিশীলভাবে বিভিন্ন মডেল ব্যবহারকারীদের বিভিন্ন সেটে পরিবেশন করতে পারেন।

টেনসরফ্লো লাইট মডেল

TensorFlow Lite মডেল হল ML মডেল যা মোবাইল ডিভাইসে চালানোর জন্য অপ্টিমাইজ করা হয়। একটি টেনসরফ্লো লাইট মডেল পেতে:

তুমি শুরু করার আগে

  1. যদি আপনি ইতিমধ্যেই না করে থাকেন তাহলে আপনার Android প্রকল্পে Firebase যোগ করুন
  2. আপনার মডিউলে (অ্যাপ-লেভেল) গ্রেডল ফাইল (সাধারণত <project>/<app-module>/build.gradle.kts বা <project>/<app-module>/build.gradle ), Firebase ML-এর জন্য নির্ভরতা যোগ করুন অ্যান্ড্রয়েডের জন্য মডেল ডাউনলোডার লাইব্রেরি। আমরা লাইব্রেরি সংস্করণ নিয়ন্ত্রণ করতে Firebase Android BoM ব্যবহার করার পরামর্শ দিই।

    এছাড়াও, Firebase ML মডেল ডাউনলোডার সেট আপ করার অংশ হিসাবে, আপনাকে আপনার অ্যাপে TensorFlow Lite SDK যোগ করতে হবে।

    dependencies {
        // Import the BoM for the Firebase platform
        implementation(platform("com.google.firebase:firebase-bom:32.8.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 লাইব্রেরির সামঞ্জস্যপূর্ণ সংস্করণ ব্যবহার করবে।

    (বিকল্প) BoM ব্যবহার না করে Firebase লাইব্রেরি নির্ভরতা যোগ করুন

    আপনি যদি Firebase BoM ব্যবহার না করা বেছে নেন, তাহলে আপনাকে অবশ্যই প্রতিটি 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:24.2.3")
    // Also add the dependency for the TensorFlow Lite library and specify its version implementation("org.tensorflow:tensorflow-lite:2.3.0")
    }
    একটি কোটলিন-নির্দিষ্ট লাইব্রেরি মডিউল খুঁজছেন? অক্টোবর 2023 থেকে শুরু হচ্ছে (Firebase BoM 32.5.0) , Kotlin এবং Java ডেভেলপাররা প্রধান লাইব্রেরি মডিউলের উপর নির্ভর করতে পারে (বিস্তারিত জানতে, এই উদ্যোগ সম্পর্কে প্রায়শই জিজ্ঞাসিত প্রশ্ন দেখুন)।
  3. আপনার অ্যাপের ম্যানিফেস্টে ঘোষণা করুন যে ইন্টারনেটের অনুমতি প্রয়োজন:
    <uses-permission android:name="android.permission.INTERNET" />

1. আপনার মডেল স্থাপন করুন

Firebase কনসোল বা Firebase অ্যাডমিন পাইথন এবং Node.js SDK ব্যবহার করে আপনার কাস্টম TensorFlow মডেলগুলি স্থাপন করুন৷ কাস্টম মডেল স্থাপন এবং পরিচালনা দেখুন।

আপনি আপনার ফায়ারবেস প্রোজেক্টে একটি কাস্টম মডেল যোগ করার পরে, আপনি আপনার নির্দিষ্ট করা নাম ব্যবহার করে আপনার অ্যাপে মডেলটি উল্লেখ করতে পারেন। যে কোনো সময়ে, আপনি একটি নতুন TensorFlow Lite মডেল স্থাপন করতে পারেন এবং getModel() কল করে ব্যবহারকারীদের ডিভাইসে নতুন মডেল ডাউনলোড করতে পারেন (নীচে দেখুন)।

2. ডিভাইসে মডেলটি ডাউনলোড করুন এবং একটি TensorFlow Lite ইন্টারপ্রেটার শুরু করুন৷

আপনার অ্যাপে আপনার TensorFlow Lite মডেল ব্যবহার করতে, ডিভাইসে মডেলটির সর্বশেষ সংস্করণ ডাউনলোড করতে প্রথমে Firebase ML SDK ব্যবহার করুন। তারপরে, মডেলের সাথে একটি TensorFlow Lite ইন্টারপ্রেটার ইনস্ট্যান্টিয়েট করুন।

মডেল ডাউনলোড শুরু করতে, মডেল ডাউনলোডারের getModel() পদ্ধতিতে কল করুন, আপনি মডেলটি আপলোড করার সময় আপনি যে নামটি নির্ধারণ করেছেন তা উল্লেখ করে, আপনি সর্বদা সর্বশেষ মডেলটি ডাউনলোড করতে চান কিনা এবং যে শর্তে আপনি ডাউনলোড করার অনুমতি দিতে চান তা উল্লেখ করে৷

আপনি তিনটি ডাউনলোড আচরণ থেকে চয়ন করতে পারেন:

ডাউনলোড টাইপ বর্ণনা
LOCAL_MODEL ডিভাইস থেকে স্থানীয় মডেল পান. কোনো স্থানীয় মডেল উপলব্ধ না থাকলে, এটি LATEST_MODEL এর মতো আচরণ করে। আপনি মডেল আপডেটের জন্য চেক করতে আগ্রহী না হলে এই ডাউনলোড টাইপ ব্যবহার করুন. উদাহরণস্বরূপ, আপনি মডেলের নামগুলি পুনরুদ্ধার করতে রিমোট কনফিগ ব্যবহার করছেন এবং আপনি সর্বদা নতুন নামে মডেলগুলি আপলোড করছেন (প্রস্তাবিত)।
LOCAL_MODEL_UPDATE_IN_BACKGROUND ডিভাইস থেকে স্থানীয় মডেল পান এবং পটভূমিতে মডেল আপডেট করা শুরু করুন৷ কোনো স্থানীয় মডেল উপলব্ধ না থাকলে, এটি LATEST_MODEL এর মতো আচরণ করে।
সর্বশেষ মডেল সর্বশেষ মডেল পান. স্থানীয় মডেল সর্বশেষ সংস্করণ হলে, স্থানীয় মডেল প্রদান করে। অন্যথায়, সর্বশেষ মডেল ডাউনলোড করুন. সর্বশেষ সংস্করণ ডাউনলোড না হওয়া পর্যন্ত এই আচরণটি অবরুদ্ধ হবে (প্রস্তাবিত নয়)। এই আচরণটি শুধুমাত্র সেই ক্ষেত্রে ব্যবহার করুন যেখানে আপনার স্পষ্টভাবে সর্বশেষ সংস্করণের প্রয়োজন৷

আপনার মডেল-সম্পর্কিত কার্যকারিতা অক্ষম করা উচিত-উদাহরণস্বরূপ, আপনার UI-এর অংশ ধূসর-আউট বা লুকান-যতক্ষণ না আপনি নিশ্চিত করছেন যে মডেলটি ডাউনলোড হয়েছে।

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 ইন্টারপ্রেটার ব্যবহার করতে পারেন। উদাহরণ স্বরূপ:

পাইথন

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] ফ্লোটিং-পয়েন্ট মানগুলির একটি ইনপুট আকৃতি সহ একটি চিত্র শ্রেণিবিন্যাসের মডেল থাকে তবে আপনি নিম্নলিখিত উদাহরণে দেখানো হিসাবে একটি Bitmap অবজেক্ট থেকে একটি ইনপুট ByteBuffer তৈরি করতে পারেন:

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 বরাদ্দ করুন এবং টেনসরফ্লো লাইট ইন্টারপ্রেটারের 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?
}

পরিশিষ্ট: মডেল নিরাপত্তা

আপনি কীভাবে আপনার টেনসরফ্লো লাইট মডেলগুলিকে Firebase ML-এ উপলব্ধ করেন না কেন, Firebase ML স্থানীয় স্টোরেজে স্ট্যান্ডার্ড সিরিয়ালাইজড প্রোটোবাফ ফর্ম্যাটে সঞ্চয় করে৷

তত্ত্বগতভাবে, এর মানে হল যে কেউ আপনার মডেল অনুলিপি করতে পারে। যাইহোক, বাস্তবে, বেশিরভাগ মডেলগুলি এতটাই অ্যাপ্লিকেশন-নির্দিষ্ট এবং অপ্টিমাইজেশান দ্বারা অস্পষ্ট যে ঝুঁকি প্রতিযোগীদের বিচ্ছিন্ন করা এবং আপনার কোড পুনরায় ব্যবহার করার মতোই। তবুও, আপনার অ্যাপে একটি কাস্টম মডেল ব্যবহার করার আগে আপনার এই ঝুঁকি সম্পর্কে সচেতন হওয়া উচিত।

অ্যান্ড্রয়েড এপিআই লেভেল 21 (ললিপপ) এবং নতুনটিতে, মডেলটি একটি ডিরেক্টরিতে ডাউনলোড করা হয় যা স্বয়ংক্রিয় ব্যাকআপ থেকে বাদ দেওয়া হয়।

অ্যান্ড্রয়েড এপিআই লেভেল 20 এবং তার বেশি বয়সে, মডেলটিকে অ্যাপ-প্রাইভেট ইন্টারনাল স্টোরেজে com.google.firebase.ml.custom.models নামে একটি ডিরেক্টরিতে ডাউনলোড করা হয়। আপনি যদি BackupAgent ব্যবহার করে ফাইল ব্যাকআপ সক্ষম করেন, তাহলে আপনি এই ডিরেক্টরিটি বাদ দিতে বেছে নিতে পারেন।