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

আপনি টেনসরফ্লো লাইট মডেলের সাহায্যে ডিভাইসে অনুমান করতে ML কিট ব্যবহার করতে পারেন।

এই API-এর জন্য Android SDK লেভেল ১৬ (Jelly Bean) বা তার পরবর্তী সংস্করণ প্রয়োজন।

শুরু করার আগে

  1. যদি আপনি ইতিমধ্যেই না করে থাকেন, তাহলে আপনার অ্যান্ড্রয়েড প্রজেক্টে Firebase যোগ করুন
  2. আপনার মডিউল (অ্যাপ-লেভেল) গ্র্যাডল ফাইলে (সাধারণত app/build.gradle ) ML কিট অ্যান্ড্রয়েড লাইব্রেরির জন্য নির্ভরতা যোগ করুন:
    apply plugin: 'com.android.application'
    apply plugin: 'com.google.gms.google-services'
    
    dependencies {
      // ...
    
      implementation 'com.google.firebase:firebase-ml-model-interpreter:22.0.3'
    }
  3. আপনি যে TensorFlow মডেলটি ব্যবহার করতে চান তা TensorFlow Lite ফর্ম্যাটে রূপান্তর করুন। TOCO দেখুন: TensorFlow Lite Optimizing Converter

আপনার মডেল হোস্ট করুন অথবা বান্ডিল করুন

আপনার অ্যাপে অনুমানের জন্য TensorFlow Lite মডেল ব্যবহার করার আগে, আপনাকে অবশ্যই ML Kit-এর জন্য মডেলটি উপলব্ধ করতে হবে। ML Kit Firebase ব্যবহার করে দূরবর্তীভাবে হোস্ট করা TensorFlow Lite মডেলগুলি ব্যবহার করতে পারে, অ্যাপ বাইনারি বা উভয়ের সাথেই সংযুক্ত।

Firebase-এ একটি মডেল হোস্ট করার মাধ্যমে, আপনি নতুন অ্যাপ সংস্করণ প্রকাশ না করেই মডেলটি আপডেট করতে পারেন এবং আপনি Remote Config এবং A/B Testing ব্যবহার করে বিভিন্ন ব্যবহারকারীদের বিভিন্ন মডেল গতিশীলভাবে পরিবেশন করতে পারেন।

যদি আপনি শুধুমাত্র Firebase-এর সাথে হোস্ট করে মডেলটি সরবরাহ করতে চান, এবং আপনার অ্যাপের সাথে এটি বান্ডেল না করেন, তাহলে আপনি আপনার অ্যাপের প্রাথমিক ডাউনলোডের আকার কমাতে পারেন। তবে মনে রাখবেন, যদি মডেলটি আপনার অ্যাপের সাথে বান্ডেল না করা হয়, তাহলে আপনার অ্যাপটি প্রথমবার মডেলটি ডাউনলোড না করা পর্যন্ত মডেল-সম্পর্কিত কোনও কার্যকারিতা উপলব্ধ থাকবে না।

আপনার মডেলটিকে আপনার অ্যাপের সাথে বান্ডেল করে, আপনি নিশ্চিত করতে পারেন যে Firebase-হোস্টেড মডেলটি উপলব্ধ না থাকলেও আপনার অ্যাপের ML বৈশিষ্ট্যগুলি এখনও কাজ করছে।

Firebase-এ হোস্ট মডেলগুলি

Firebase-এ আপনার TensorFlow Lite মডেল হোস্ট করতে:

  1. Firebase কনসোলের ML Kit বিভাগে, কাস্টম ট্যাবে ক্লিক করুন।
  2. কাস্টম মডেল যোগ করুন (অথবা অন্য মডেল যোগ করুন ) ক্লিক করুন।
  3. আপনার Firebase প্রকল্পে আপনার মডেল সনাক্ত করতে ব্যবহৃত একটি নাম উল্লেখ করুন, তারপর TensorFlow Lite মডেল ফাইলটি আপলোড করুন (সাধারণত .tflite বা .lite দিয়ে শেষ হয়)।
  4. আপনার অ্যাপের ম্যানিফেস্টে, ঘোষণা করুন যে ইন্টারনেট অনুমতি প্রয়োজন:
    <uses-permission android:name="android.permission.INTERNET" />

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

একটি অ্যাপের সাহায্যে মডেলগুলিকে বান্ডিল করুন

আপনার অ্যাপের সাথে আপনার TensorFlow Lite মডেলটি বান্ডেল করতে, মডেল ফাইলটি (সাধারণত .tflite বা .lite দিয়ে শেষ হয়) আপনার অ্যাপের assets/ ফোল্ডারে কপি করুন। (আপনাকে প্রথমে app/ ফোল্ডারে ডান ক্লিক করে, তারপর New > Folder > Assets Folder এ ক্লিক করে ফোল্ডারটি তৈরি করতে হতে পারে।)

তারপর, আপনার অ্যাপের build.gradle ফাইলে নিম্নলিখিতটি যোগ করুন যাতে নিশ্চিত করা যায় যে Gradle অ্যাপ তৈরি করার সময় মডেলগুলিকে সংকুচিত করে না:

android {

    // ...

    aaptOptions {
        noCompress "tflite"  // Your model's file extension: "tflite", "lite", etc.
    }
}

মডেল ফাইলটি অ্যাপ প্যাকেজে অন্তর্ভুক্ত করা হবে এবং একটি কাঁচা সম্পদ হিসেবে ML Kit-এর কাছে উপলব্ধ হবে।

মডেলটি লোড করুন

আপনার অ্যাপে আপনার TensorFlow Lite মডেল ব্যবহার করতে, প্রথমে আপনার মডেলটি কোথায় উপলব্ধ তা দিয়ে ML Kit কনফিগার করুন: দূরবর্তীভাবে Firebase ব্যবহার করে, স্থানীয় স্টোরেজে, অথবা উভয়ই। যদি আপনি স্থানীয় এবং দূরবর্তী মডেল উভয়ই নির্দিষ্ট করেন, তাহলে যদি উপলব্ধ থাকে তবে আপনি দূরবর্তী মডেলটি ব্যবহার করতে পারেন এবং যদি দূরবর্তী মডেলটি উপলব্ধ না হয় তবে স্থানীয়ভাবে সংরক্ষিত মডেলটিতে ফিরে যেতে পারেন।

একটি Firebase-হোস্টেড মডেল কনফিগার করুন

যদি আপনি আপনার মডেলটি Firebase দিয়ে হোস্ট করে থাকেন, তাহলে একটি FirebaseCustomRemoteModel অবজেক্ট তৈরি করুন, যেখানে আপনি মডেলটি আপলোড করার সময় যে নামটি দিয়েছিলেন তা উল্লেখ করুন:

Java

FirebaseCustomRemoteModel remoteModel =
        new FirebaseCustomRemoteModel.Builder("your_model").build();

Kotlin

val remoteModel = FirebaseCustomRemoteModel.Builder("your_model").build()

তারপর, মডেল ডাউনলোড টাস্ক শুরু করুন, আপনি কোন শর্তাবলীর অধীনে ডাউনলোডের অনুমতি দিতে চান তা উল্লেখ করুন। যদি মডেলটি ডিভাইসে না থাকে, অথবা মডেলের একটি নতুন সংস্করণ উপলব্ধ থাকে, তাহলে টাস্কটি Firebase থেকে অ্যাসিঙ্ক্রোনাসভাবে মডেলটি ডাউনলোড করবে:

Java

FirebaseModelDownloadConditions conditions = new FirebaseModelDownloadConditions.Builder()
        .requireWifi()
        .build();
FirebaseModelManager.getInstance().download(remoteModel, conditions)
        .addOnCompleteListener(new OnCompleteListener<Void>() {
            @Override
            public void onComplete(@NonNull Task<Void> task) {
                // Success.
            }
        });

Kotlin

val conditions = FirebaseModelDownloadConditions.Builder()
    .requireWifi()
    .build()
FirebaseModelManager.getInstance().download(remoteModel, conditions)
    .addOnCompleteListener {
        // Success.
    }

অনেক অ্যাপ তাদের ইনিশিয়ালাইজেশন কোডে ডাউনলোডের কাজ শুরু করে, কিন্তু মডেলটি ব্যবহার করার আগে আপনি যেকোনো সময় তা করতে পারেন।

একটি স্থানীয় মডেল কনফিগার করুন

যদি আপনি আপনার অ্যাপের সাথে মডেলটি বান্ডেল করে থাকেন, তাহলে TensorFlow Lite মডেলের ফাইলের নাম উল্লেখ করে একটি FirebaseCustomLocalModel অবজেক্ট তৈরি করুন:

Java

FirebaseCustomLocalModel localModel = new FirebaseCustomLocalModel.Builder()
        .setAssetFilePath("your_model.tflite")
        .build();

Kotlin

val localModel = FirebaseCustomLocalModel.Builder()
    .setAssetFilePath("your_model.tflite")
    .build()

আপনার মডেল থেকে একজন দোভাষী তৈরি করুন

আপনার মডেল সোর্সগুলি কনফিগার করার পরে, তাদের যেকোনো একটি থেকে একটি FirebaseModelInterpreter অবজেক্ট তৈরি করুন।

যদি আপনার কেবল স্থানীয়ভাবে বান্ডিল করা মডেল থাকে, তাহলে আপনার FirebaseCustomLocalModel অবজেক্ট থেকে একটি ইন্টারপ্রেটার তৈরি করুন:

Java

FirebaseModelInterpreter interpreter;
try {
    FirebaseModelInterpreterOptions options =
            new FirebaseModelInterpreterOptions.Builder(localModel).build();
    interpreter = FirebaseModelInterpreter.getInstance(options);
} catch (FirebaseMLException e) {
    // ...
}

Kotlin

val options = FirebaseModelInterpreterOptions.Builder(localModel).build()
val interpreter = FirebaseModelInterpreter.getInstance(options)

যদি আপনার একটি রিমোটলি-হোস্টেড মডেল থাকে, তাহলে এটি চালানোর আগে আপনাকে এটি ডাউনলোড করা হয়েছে কিনা তা পরীক্ষা করতে হবে। আপনি মডেল ম্যানেজারের isModelDownloaded() পদ্ধতি ব্যবহার করে মডেল ডাউনলোড টাস্কের অবস্থা পরীক্ষা করতে পারেন।

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

Java

FirebaseModelManager.getInstance().isModelDownloaded(remoteModel)
        .addOnSuccessListener(new OnSuccessListener<Boolean>() {
            @Override
            public void onSuccess(Boolean isDownloaded) {
                FirebaseModelInterpreterOptions options;
                if (isDownloaded) {
                    options = new FirebaseModelInterpreterOptions.Builder(remoteModel).build();
                } else {
                    options = new FirebaseModelInterpreterOptions.Builder(localModel).build();
                }
                FirebaseModelInterpreter interpreter = FirebaseModelInterpreter.getInstance(options);
                // ...
            }
        });

Kotlin

FirebaseModelManager.getInstance().isModelDownloaded(remoteModel)
    .addOnSuccessListener { isDownloaded -> 
    val options =
        if (isDownloaded) {
            FirebaseModelInterpreterOptions.Builder(remoteModel).build()
        } else {
            FirebaseModelInterpreterOptions.Builder(localModel).build()
        }
    val interpreter = FirebaseModelInterpreter.getInstance(options)
}

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

Java

FirebaseModelManager.getInstance().download(remoteModel, conditions)
        .addOnSuccessListener(new OnSuccessListener<Void>() {
            @Override
            public void onSuccess(Void v) {
              // Download complete. Depending on your app, you could enable
              // the ML feature, or switch from the local model to the remote
              // model, etc.
            }
        });

Kotlin

FirebaseModelManager.getInstance().download(remoteModel, conditions)
    .addOnCompleteListener {
        // Download complete. Depending on your app, you could enable the ML
        // feature, or switch from the local model to the remote model, etc.
    }

মডেলের ইনপুট এবং আউটপুট নির্দিষ্ট করুন।

এরপর, মডেল ইন্টারপ্রেটারের ইনপুট এবং আউটপুট ফর্ম্যাট কনফিগার করুন।

একটি TensorFlow Lite মডেল ইনপুট হিসেবে গ্রহণ করে এবং আউটপুট হিসেবে এক বা একাধিক বহুমাত্রিক অ্যারে তৈরি করে। এই অ্যারেগুলিতে byte , int , long , অথবা float মান থাকে। আপনার মডেল যে অ্যারে ব্যবহার করে তার সংখ্যা এবং মাত্রা ("আকৃতি") দিয়ে আপনাকে ML Kit কনফিগার করতে হবে।

যদি আপনি আপনার মডেলের ইনপুট এবং আউটপুটের আকৃতি এবং ডেটা টাইপ না জানেন, তাহলে আপনি আপনার মডেলটি পরীক্ষা করার জন্য TensorFlow Lite Python ইন্টারপ্রেটার ব্যবহার করতে পারেন। উদাহরণস্বরূপ:

import tensorflow as tf

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

# Print input shape and type
print(interpreter.get_input_details()[0]['shape'])  # Example: [1 224 224 3]
print(interpreter.get_input_details()[0]['dtype'])  # Example: <class 'numpy.float32'>

# Print output shape and type
print(interpreter.get_output_details()[0]['shape'])  # Example: [1 1000]
print(interpreter.get_output_details()[0]['dtype'])  # Example: <class 'numpy.float32'>

আপনার মডেলের ইনপুট এবং আউটপুটের ফর্ম্যাট নির্ধারণ করার পরে, আপনি একটি FirebaseModelInputOutputOptions অবজেক্ট তৈরি করে আপনার অ্যাপের মডেল ইন্টারপ্রেটার কনফিগার করতে পারেন।

উদাহরণস্বরূপ, একটি ফ্লোটিং-পয়েন্ট ইমেজ ক্লাসিফিকেশন মডেল ইনপুট হিসেবে N x224x224x3 float ভ্যালুর একটি অ্যারে নিতে পারে, যা N 224x224 থ্রি-চ্যানেল (RGB) ইমেজের একটি ব্যাচকে প্রতিনিধিত্ব করে এবং আউটপুট হিসেবে 1000টি float ভ্যালুর একটি তালিকা তৈরি করে, প্রতিটি সম্ভাব্যতাকে প্রতিনিধিত্ব করে যে ছবিটি মডেলের ভবিষ্যদ্বাণী করা 1000টি ক্যাটাগরির একটির সদস্য।

এই ধরনের মডেলের জন্য, আপনাকে মডেল ইন্টারপ্রেটারের ইনপুট এবং আউটপুট নীচে দেখানো পদ্ধতিতে কনফিগার করতে হবে:

Java

FirebaseModelInputOutputOptions inputOutputOptions =
        new FirebaseModelInputOutputOptions.Builder()
                .setInputFormat(0, FirebaseModelDataType.FLOAT32, new int[]{1, 224, 224, 3})
                .setOutputFormat(0, FirebaseModelDataType.FLOAT32, new int[]{1, 5})
                .build();

Kotlin

val inputOutputOptions = FirebaseModelInputOutputOptions.Builder()
        .setInputFormat(0, FirebaseModelDataType.FLOAT32, intArrayOf(1, 224, 224, 3))
        .setOutputFormat(0, FirebaseModelDataType.FLOAT32, intArrayOf(1, 5))
        .build()

ইনপুট ডেটার উপর অনুমান সম্পাদন করুন

অবশেষে, মডেলটি ব্যবহার করে অনুমান সম্পাদন করতে, আপনার ইনপুট ডেটা নিন এবং আপনার মডেলের জন্য সঠিক আকৃতির একটি ইনপুট অ্যারে পেতে প্রয়োজনীয় ডেটাতে যেকোনো রূপান্তর সম্পাদন করুন।

উদাহরণস্বরূপ, যদি আপনার কাছে [1 224 224 3] ফ্লোটিং-পয়েন্ট মান সহ একটি চিত্র শ্রেণিবিন্যাস মডেল থাকে, তাহলে আপনি নিম্নলিখিত উদাহরণে দেখানো Bitmap অবজেক্ট থেকে একটি ইনপুট অ্যারে তৈরি করতে পারেন:

Java

Bitmap bitmap = getYourInputImage();
bitmap = Bitmap.createScaledBitmap(bitmap, 224, 224, true);

int batchNum = 0;
float[][][][] input = new float[1][224][224][3];
for (int x = 0; x < 224; x++) {
    for (int y = 0; y < 224; y++) {
        int pixel = bitmap.getPixel(x, y);
        // Normalize channel values to [-1.0, 1.0]. This requirement varies by
        // model. For example, some models might require values to be normalized
        // to the range [0.0, 1.0] instead.
        input[batchNum][x][y][0] = (Color.red(pixel) - 127) / 128.0f;
        input[batchNum][x][y][1] = (Color.green(pixel) - 127) / 128.0f;
        input[batchNum][x][y][2] = (Color.blue(pixel) - 127) / 128.0f;
    }
}

Kotlin

val bitmap = Bitmap.createScaledBitmap(yourInputImage, 224, 224, true)

val batchNum = 0
val input = Array(1) { Array(224) { Array(224) { FloatArray(3) } } }
for (x in 0..223) {
    for (y in 0..223) {
        val pixel = bitmap.getPixel(x, y)
        // Normalize channel values to [-1.0, 1.0]. This requirement varies by
        // model. For example, some models might require values to be normalized
        // to the range [0.0, 1.0] instead.
        input[batchNum][x][y][0] = (Color.red(pixel) - 127) / 255.0f
        input[batchNum][x][y][1] = (Color.green(pixel) - 127) / 255.0f
        input[batchNum][x][y][2] = (Color.blue(pixel) - 127) / 255.0f
    }
}

তারপর, আপনার ইনপুট ডেটা দিয়ে একটি FirebaseModelInputs অবজেক্ট তৈরি করুন, এবং এটি এবং মডেলের ইনপুট এবং আউটপুট স্পেসিফিকেশন মডেল ইন্টারপ্রেটার এর run পদ্ধতিতে পাস করুন:

Java

FirebaseModelInputs inputs = new FirebaseModelInputs.Builder()
        .add(input)  // add() as many input arrays as your model requires
        .build();
firebaseInterpreter.run(inputs, inputOutputOptions)
        .addOnSuccessListener(
                new OnSuccessListener<FirebaseModelOutputs>() {
                    @Override
                    public void onSuccess(FirebaseModelOutputs result) {
                        // ...
                    }
                })
        .addOnFailureListener(
                new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception e) {
                        // Task failed with an exception
                        // ...
                    }
                });

Kotlin

val inputs = FirebaseModelInputs.Builder()
        .add(input) // add() as many input arrays as your model requires
        .build()
firebaseInterpreter.run(inputs, inputOutputOptions)
        .addOnSuccessListener { result ->
            // ...
        }
        .addOnFailureListener { e ->
            // Task failed with an exception
            // ...
        }

যদি কলটি সফল হয়, তাহলে আপনি সাকসেস লিসেনারের কাছে পাঠানো অবজেক্টের getOutput() মেথডটি কল করে আউটপুট পেতে পারেন। উদাহরণস্বরূপ:

Java

float[][] output = result.getOutput(0);
float[] probabilities = output[0];

Kotlin

val output = result.getOutput<Array<FloatArray>>(0)
val probabilities = output[0]

আপনি আউটপুট কীভাবে ব্যবহার করবেন তা নির্ভর করে আপনি যে মডেলটি ব্যবহার করছেন তার উপর।

উদাহরণস্বরূপ, যদি আপনি শ্রেণীবিভাগ সম্পাদন করেন, তাহলে পরবর্তী ধাপ হিসেবে, আপনি ফলাফলের সূচীগুলিকে তাদের প্রতিনিধিত্বকারী লেবেলগুলির সাথে ম্যাপ করতে পারেন:

Java

BufferedReader reader = new BufferedReader(
        new InputStreamReader(getAssets().open("retrained_labels.txt")));
for (int i = 0; i < probabilities.length; i++) {
    String label = reader.readLine();
    Log.i("MLKit", String.format("%s: %1.4f", label, probabilities[i]));
}

Kotlin

val reader = BufferedReader(
        InputStreamReader(assets.open("retrained_labels.txt")))
for (i in probabilities.indices) {
    val label = reader.readLine()
    Log.i("MLKit", String.format("%s: %1.4f", label, probabilities[i]))
}

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

আপনি আপনার টেনসরফ্লো লাইট মডেলগুলিকে ML Kit-এ যেভাবেই উপলব্ধ করুন না কেন, ML Kit স্থানীয় স্টোরেজে স্ট্যান্ডার্ড সিরিয়ালাইজড প্রোটোবাফ ফর্ম্যাটে সেগুলি সংরক্ষণ করে।

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

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

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