Android पर ML किट के अनुमान के लिए TensorFlow Lite मॉडल का उपयोग करें

आप TensorFlow Lite मॉडल के साथ ऑन-डिवाइस अनुमान लगाने के लिए ML किट का उपयोग कर सकते हैं।

इस एपीआई के लिए एंड्रॉइड एसडीके लेवल 16 (जेली बीन) या नए की आवश्यकता है।

शुरू करने से पहले

  1. यदि आपने पहले से नहीं किया है, तो अपने एंड्रॉइड प्रोजेक्ट में फायरबेस जोड़ें
  2. अपने मॉड्यूल (ऐप-स्तर) ग्रैडल फ़ाइल (आमतौर पर app/build.gradle ) में एमएल किट एंड्रॉइड लाइब्रेरीज़ के लिए निर्भरताएं जोड़ें:
    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 ऑप्टिमाइज़िंग कन्वर्टर

अपने मॉडल को होस्ट या बंडल करें

इससे पहले कि आप अपने ऐप में अनुमान के लिए TensorFlow Lite मॉडल का उपयोग कर सकें, आपको मॉडल को ML किट के लिए उपलब्ध कराना होगा। एमएल किट फायरबेस का उपयोग करके दूरस्थ रूप से होस्ट किए गए टेन्सरफ्लो लाइट मॉडल का उपयोग कर सकता है, जो ऐप बाइनरी के साथ बंडल किया गया है, या दोनों।

फायरबेस पर एक मॉडल होस्ट करके, आप एक नया ऐप संस्करण जारी किए बिना मॉडल को अपडेट कर सकते हैं, और आप उपयोगकर्ताओं के विभिन्न समूहों को गतिशील रूप से विभिन्न मॉडल पेश करने के लिए रिमोट कॉन्फिग और ए/बी परीक्षण का उपयोग कर सकते हैं।

यदि आप मॉडल को केवल फायरबेस के साथ होस्ट करके प्रदान करना चुनते हैं, और इसे अपने ऐप के साथ बंडल नहीं करते हैं, तो आप अपने ऐप के प्रारंभिक डाउनलोड आकार को कम कर सकते हैं। हालाँकि, ध्यान रखें कि यदि मॉडल आपके ऐप के साथ बंडल नहीं किया गया है, तो मॉडल से संबंधित कोई भी कार्यक्षमता तब तक उपलब्ध नहीं होगी जब तक आपका ऐप पहली बार मॉडल डाउनलोड नहीं करता।

अपने मॉडल को अपने ऐप के साथ बंडल करके, आप यह सुनिश्चित कर सकते हैं कि आपके ऐप की एमएल सुविधाएं तब भी काम करती हैं जब फायरबेस-होस्टेड मॉडल उपलब्ध नहीं है।

फायरबेस पर मॉडल होस्ट करें

अपने TensorFlow Lite मॉडल को Firebase पर होस्ट करने के लिए:

  1. फायरबेस कंसोल के एमएल किट अनुभाग में, कस्टम टैब पर क्लिक करें।
  2. कस्टम मॉडल जोड़ें (या कोई अन्य मॉडल जोड़ें ) पर क्लिक करें।
  3. एक नाम निर्दिष्ट करें जिसका उपयोग आपके फायरबेस प्रोजेक्ट में आपके मॉडल की पहचान करने के लिए किया जाएगा, फिर TensorFlow Lite मॉडल फ़ाइल अपलोड करें (आमतौर पर .tflite या .lite में समाप्त होती है)।
  4. अपने ऐप के मेनिफ़ेस्ट में घोषित करें कि इंटरनेट अनुमति आवश्यक है:
    <uses-permission android:name="android.permission.INTERNET" />
    

अपने फायरबेस प्रोजेक्ट में एक कस्टम मॉडल जोड़ने के बाद, आप अपने निर्दिष्ट नाम का उपयोग करके अपने ऐप्स में मॉडल का संदर्भ दे सकते हैं। किसी भी समय, आप एक नया TensorFlow Lite मॉडल अपलोड कर सकते हैं, और आपका ऐप नया मॉडल डाउनलोड करेगा और ऐप के दोबारा पुनरारंभ होने पर इसका उपयोग करना शुरू कर देगा। आप अपने ऐप के लिए मॉडल को अपडेट करने का प्रयास करने के लिए आवश्यक डिवाइस शर्तों को परिभाषित कर सकते हैं (नीचे देखें)।

एक ऐप के साथ मॉडलों को बंडल करें

अपने TensorFlow Lite मॉडल को अपने ऐप के साथ बंडल करने के लिए, मॉडल फ़ाइल (आमतौर पर .tflite या .lite में समाप्त होती है) को अपने ऐप के assets/ फ़ोल्डर में कॉपी करें। (आपको पहले app/ फ़ोल्डर पर राइट-क्लिक करके, फिर न्यू > फ़ोल्डर > एसेट फ़ोल्डर पर क्लिक करके फ़ोल्डर बनाना पड़ सकता है।)

फिर, यह सुनिश्चित करने के लिए कि ऐप बनाते समय ग्रैडल मॉडलों को संपीड़ित नहीं करता है, अपने ऐप की build.gradle फ़ाइल में निम्नलिखित जोड़ें:

android {

    // ...

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

मॉडल फ़ाइल को ऐप पैकेज में शामिल किया जाएगा और कच्ची संपत्ति के रूप में एमएल किट के लिए उपलब्ध होगा।

मॉडल लोड करें

अपने ऐप में अपने TensorFlow Lite मॉडल का उपयोग करने के लिए, पहले ML किट को उन स्थानों से कॉन्फ़िगर करें जहां आपका मॉडल उपलब्ध है: दूरस्थ रूप से फायरबेस का उपयोग करके, स्थानीय स्टोरेज में, या दोनों में। यदि आप स्थानीय और दूरस्थ दोनों मॉडल निर्दिष्ट करते हैं, तो यदि दूरस्थ मॉडल उपलब्ध है तो आप इसका उपयोग कर सकते हैं, और यदि दूरस्थ मॉडल उपलब्ध नहीं है तो स्थानीय रूप से संग्रहीत मॉडल पर वापस आ सकते हैं।

फ़ायरबेस-होस्टेड मॉडल कॉन्फ़िगर करें

यदि आपने अपने मॉडल को फायरबेस के साथ होस्ट किया है, तो एक FirebaseCustomRemoteModel ऑब्जेक्ट बनाएं, जिसमें मॉडल अपलोड करते समय आपने जो नाम निर्दिष्ट किया था उसे निर्दिष्ट करें:

Java

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

Kotlin+KTX

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

फिर, उन शर्तों को निर्दिष्ट करते हुए मॉडल डाउनलोड कार्य शुरू करें जिनके तहत आप डाउनलोड करने की अनुमति देना चाहते हैं। यदि मॉडल डिवाइस पर नहीं है, या यदि मॉडल का एक नया संस्करण उपलब्ध है, तो कार्य फायरबेस से मॉडल को एसिंक्रोनस रूप से डाउनलोड करेगा:

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

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

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

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

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

यदि आपके पास केवल दूरस्थ रूप से होस्ट किया गया मॉडल है, तो आपको मॉडल-संबंधित कार्यक्षमता को अक्षम करना चाहिए - उदाहरण के लिए, अपने यूआई के हिस्से को ग्रे-आउट या छुपाएं - जब तक कि आप पुष्टि न करें कि मॉडल डाउनलोड हो गया है। आप श्रोता को मॉडल प्रबंधक की 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+KTX

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 मान होते हैं। आपको अपने मॉडल द्वारा उपयोग की जाने वाली सरणियों की संख्या और आयाम ("आकार") के साथ एमएल किट को कॉन्फ़िगर करना होगा।

यदि आप अपने मॉडल के इनपुट और आउटपुट के आकार और डेटा प्रकार को नहीं जानते हैं, तो आप अपने मॉडल का निरीक्षण करने के लिए 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 ऑब्जेक्ट बनाकर अपने ऐप के मॉडल दुभाषिया को कॉन्फ़िगर कर सकते हैं।

उदाहरण के लिए, एक फ़्लोटिंग-पॉइंट छवि वर्गीकरण मॉडल इनपुट के रूप में float मानों की एक N x224x224x3 सरणी ले सकता है, जो 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+KTX

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

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

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

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

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

परिशिष्ट: मॉडल सुरक्षा

भले ही आप अपने TensorFlow Lite मॉडल को ML किट के लिए कैसे उपलब्ध कराते हैं, ML किट उन्हें स्थानीय भंडारण में मानक क्रमबद्ध प्रोटोबफ़ प्रारूप में संग्रहीत करता है।

सैद्धांतिक रूप से, इसका मतलब यह है कि कोई भी आपके मॉडल की नकल कर सकता है। हालाँकि, व्यवहार में, अधिकांश मॉडल इतने एप्लिकेशन-विशिष्ट होते हैं और अनुकूलन द्वारा अस्पष्ट होते हैं कि जोखिम आपके कोड को अलग करने और पुन: उपयोग करने वाले प्रतिस्पर्धियों के जोखिम के समान होता है। फिर भी, अपने ऐप में कस्टम मॉडल का उपयोग करने से पहले आपको इस जोखिम के बारे में पता होना चाहिए।

एंड्रॉइड एपीआई स्तर 21 (लॉलीपॉप) और नए पर, मॉडल को एक निर्देशिका में डाउनलोड किया जाता है जिसे स्वचालित बैकअप से बाहर रखा गया है।

एंड्रॉइड एपीआई स्तर 20 और पुराने पर, मॉडल को ऐप-प्राइवेट इंटरनल स्टोरेज में com.google.firebase.ml.custom.models नामक निर्देशिका में डाउनलोड किया जाता है। यदि आपने BackupAgent का उपयोग करके फ़ाइल बैकअप सक्षम किया है, तो आप इस निर्देशिका को बाहर करना चुन सकते हैं।