TensorFlow Lite सहायता लाइब्रेरी की मदद से, इनपुट और आउटपुट डेटा प्रोसेस करें

मोबाइल ऐप्लिकेशन डेवलपर आम तौर पर बिटमैप या पूर्णांक जैसे टाइप किए गए ऑब्जेक्ट के साथ इंटरैक्ट करते हैं. हालांकि, डिवाइस पर मशीन लर्निंग मॉडल पर काम करने वाला TensorFlow Lite अनुवादक एपीआई, ByteBuffer के रूप में टेन्सर का इस्तेमाल करता है. इस डेटा को डीबग और हेर-फेर करना मुश्किल हो सकता है. TensorFlow Lite Android की सहायता लाइब्रेरी को TensorFlow Lite मॉडल के इनपुट और आउटपुट को प्रोसेस करने में मदद करने के लिए डिज़ाइन किया गया है और TensorFlow Lite अनुवादक को इस्तेमाल में आसान बनाया गया है.

शुरू करें

Gradle डिपेंडेंसी और अन्य सेटिंग इंपोर्ट करना

.tflite मॉडल फ़ाइल को Android मॉड्यूल की एसेट डायरेक्ट्री में कॉपी करें जहां मॉडल चलाया जाएगा. यह बताएं कि फ़ाइल कंप्रेस न की जाए. साथ ही, मॉड्यूल की build.gradle फ़ाइल में TensorFlow Lite लाइब्रेरी जोड़ें:

android {
    // Other settings

    // Specify tflite file should not be compressed for the app apk
    aaptOptions {
        noCompress "tflite"
    }

}

dependencies {
    // Other dependencies

    // Import tflite dependencies
    implementation 'org.tensorflow:tensorflow-lite:0.0.0-nightly-SNAPSHOT'
    // The GPU delegate library is optional. Depend on it as needed.
    implementation 'org.tensorflow:tensorflow-lite-gpu:0.0.0-nightly-SNAPSHOT'
    implementation 'org.tensorflow:tensorflow-lite-support:0.0.0-nightly-SNAPSHOT'
}

सपोर्ट लाइब्रेरी के अलग-अलग वर्शन के लिए, MavenCentral पर होस्ट की गई TensorFlow Lite की सहायता लाइब्रेरी एक्सप्लोर करें.

बुनियादी इमेज में बदलाव और कन्वर्ज़न

TensorFlow Lite की सहायता लाइब्रेरी में, इमेज में बदलाव करने के बुनियादी तरीकों का एक सुइट मौजूद है. जैसे, क्रॉप करना और साइज़ बदलना. इसका इस्तेमाल करने के लिए, ImagePreprocessor बनाएं और ज़रूरी कार्रवाइयां जोड़ें. इमेज को TensorFlow Lite अनुवादक के ज़रिए ज़रूरी टेन्सर फ़ॉर्मैट में बदलने के लिए, इनपुट के तौर पर इस्तेमाल करने के लिए TensorImage बनाएं:

import org.tensorflow.lite.DataType;
import org.tensorflow.lite.support.image.ImageProcessor;
import org.tensorflow.lite.support.image.TensorImage;
import org.tensorflow.lite.support.image.ops.ResizeOp;

// Initialization code
// Create an ImageProcessor with all ops required. For more ops, please
// refer to the ImageProcessor Architecture section in this README.
ImageProcessor imageProcessor =
    new ImageProcessor.Builder()
        .add(new ResizeOp(224, 224, ResizeOp.ResizeMethod.BILINEAR))
        .build();

// Create a TensorImage object. This creates the tensor of the corresponding
// tensor type (uint8 in this case) that the TensorFlow Lite interpreter needs.
TensorImage tensorImage = new TensorImage(DataType.UINT8);

// Analysis code for every frame
// Preprocess the image
tensorImage.load(bitmap);
tensorImage = imageProcessor.process(tensorImage);

टेन्सर के DataType को मेटाडेटा की जानकारी इकट्ठा करने वाली लाइब्रेरी के साथ-साथ, मॉडल की अन्य जानकारी की मदद से भी पढ़ा जा सकता है.

ऑडियो का बेसिक डेटा प्रोसेसिंग

TensorFlow Lite की सहायता लाइब्रेरी, TensorAudio क्लास के बारे में भी बताती है. इसमें ऑडियो डेटा प्रोसेस करने के कुछ बुनियादी तरीके शामिल होते हैं. इसे ज़्यादातर AudioRecord के साथ इस्तेमाल किया जाता है और रिंग बफ़र में ऑडियो सैंपल कैप्चर करता है.

import android.media.AudioRecord;
import org.tensorflow.lite.support.audio.TensorAudio;

// Create an `AudioRecord` instance.
AudioRecord record = AudioRecord(...)

// Create a `TensorAudio` object from Android AudioFormat.
TensorAudio tensorAudio = new TensorAudio(record.getFormat(), size)

// Load all audio samples available in the AudioRecord without blocking.
tensorAudio.load(record)

// Get the `TensorBuffer` for inference.
TensorBuffer buffer = tensorAudio.getTensorBuffer()

आउटपुट ऑब्जेक्ट बनाएं और मॉडल को चलाएं

मॉडल को चलाने से पहले, हमें कंटेनर ऑब्जेक्ट बनाना होगा, जो नतीजे को स्टोर करेंगे:

import org.tensorflow.lite.DataType;
import org.tensorflow.lite.support.tensorbuffer.TensorBuffer;

// Create a container for the result and specify that this is a quantized model.
// Hence, the 'DataType' is defined as UINT8 (8-bit unsigned integer)
TensorBuffer probabilityBuffer =
    TensorBuffer.createFixedSize(new int[]{1, 1001}, DataType.UINT8);

मॉडल लोड हो रहा है और अनुमान चल रहा है:

import java.nio.MappedByteBuffer;
import org.tensorflow.lite.InterpreterFactory;
import org.tensorflow.lite.InterpreterApi;

// Initialise the model
try{
    MappedByteBuffer tfliteModel
        = FileUtil.loadMappedFile(activity,
            "mobilenet_v1_1.0_224_quant.tflite");
    InterpreterApi tflite = new InterpreterFactory().create(
        tfliteModel, new InterpreterApi.Options());
} catch (IOException e){
    Log.e("tfliteSupport", "Error reading model", e);
}

// Running inference
if(null != tflite) {
    tflite.run(tImage.getBuffer(), probabilityBuffer.getBuffer());
}

नतीजा ऐक्सेस करना

डेवलपर, आउटपुट को सीधे probabilityBuffer.getFloatArray() के ज़रिए ऐक्सेस कर सकते हैं. अगर मॉडल, कैलकुलेटेड आउटपुट जनरेट करता है, तो नतीजे को बदलना न भूलें. MobileNet के क्वांटाइज़्ड मॉडल के लिए, डेवलपर को हर आउटपुट वैल्यू को 255 से भाग देना होगा, ताकि हर कैटगरी के लिए 0 (सबसे कम संभावना) से 1 (सबसे कम संभावना) तक की संभावना मिल सके.

ज़रूरी नहीं: नतीजों को लेबल के हिसाब से मैप करना

डेवलपर वैकल्पिक तौर पर नतीजों को लेबल के साथ मैप कर सकते हैं. सबसे पहले, लेबल की टेक्स्ट फ़ाइल को मॉड्यूल की एसेट डायरेक्ट्री में कॉपी करें. इसके बाद, इस कोड का इस्तेमाल करके लेबल फ़ाइल लोड करें:

import org.tensorflow.lite.support.common.FileUtil;

final String ASSOCIATED_AXIS_LABELS = "labels.txt";
List<String> associatedAxisLabels = null;

try {
    associatedAxisLabels = FileUtil.loadLabels(this, ASSOCIATED_AXIS_LABELS);
} catch (IOException e) {
    Log.e("tfliteSupport", "Error reading label file", e);
}

यह स्निपेट बताता है कि प्रॉबबिलिटी को कैटगरी लेबल से कैसे जोड़ा जाए:

import java.util.Map;
import org.tensorflow.lite.support.common.TensorProcessor;
import org.tensorflow.lite.support.common.ops.NormalizeOp;
import org.tensorflow.lite.support.label.TensorLabel;

// Post-processor which dequantize the result
TensorProcessor probabilityProcessor =
    new TensorProcessor.Builder().add(new NormalizeOp(0, 255)).build();

if (null != associatedAxisLabels) {
    // Map of labels and their corresponding probability
    TensorLabel labels = new TensorLabel(associatedAxisLabels,
        probabilityProcessor.process(probabilityBuffer));

    // Create a map to access the result based on label
    Map<String, Float> floatMap = labels.getMapWithFloatValue();
}

इस्तेमाल के उदाहरण का मौजूदा कवरेज

TensorFlow Lite की सहायता लाइब्रेरी के मौजूदा वर्शन में ये चीज़ें शामिल हैं:

  • सामान्य डेटा टाइप (फ़्लोट, uint8, इमेज, ऑडियो, और इन ऑब्जेक्ट का अरे) को tflite मॉडल के इनपुट और आउटपुट के तौर पर इस्तेमाल करें.
  • इमेज से जुड़ी बुनियादी कार्रवाइयां (इमेज काटें, उसका साइज़ बदलना, और उसे घुमाना).
  • नॉर्मलाइज़ेशन और क्वांटाइज़ेशन
  • फ़ाइल का इस्तेमाल

आने वाले वर्शन में, टेक्स्ट से जुड़े ऐप्लिकेशन बेहतर तरीके से काम करेंगे.

ImageProcessor आर्किटेक्चर

ImageProcessor के डिज़ाइन की मदद से, इमेज में बदलाव करने की कार्रवाइयों को आसानी से समझा जा सकता है. साथ ही, बिल्ड प्रोसेस के दौरान उन्हें ऑप्टिमाइज़ किया जा सकता है. फ़िलहाल, ImageProcessor, प्री-प्रोसेसिंग के तीन बेसिक ऑपरेशंस के साथ काम करता है. इनके बारे में, नीचे दिए गए कोड स्निपेट की तीन टिप्पणियों में बताया गया है:

import org.tensorflow.lite.support.common.ops.NormalizeOp;
import org.tensorflow.lite.support.common.ops.QuantizeOp;
import org.tensorflow.lite.support.image.ops.ResizeOp;
import org.tensorflow.lite.support.image.ops.ResizeWithCropOrPadOp;
import org.tensorflow.lite.support.image.ops.Rot90Op;

int width = bitmap.getWidth();
int height = bitmap.getHeight();

int size = height > width ? width : height;

ImageProcessor imageProcessor =
    new ImageProcessor.Builder()
        // Center crop the image to the largest square possible
        .add(new ResizeWithCropOrPadOp(size, size))
        // Resize using Bilinear or Nearest neighbour
        .add(new ResizeOp(224, 224, ResizeOp.ResizeMethod.BILINEAR));
        // Rotation counter-clockwise in 90 degree increments
        .add(new Rot90Op(rotateDegrees / 90))
        .add(new NormalizeOp(127.5, 127.5))
        .add(new QuantizeOp(128.0, 1/128.0))
        .build();

नॉर्मलाइज़ेशन और क्वांटाइज़ेशन के बारे में ज़्यादा जानकारी यहां देखें.

सहायता लाइब्रेरी का आखिरी लक्ष्य, सभी tf.image ट्रांसफ़ॉर्मेशन में मदद करना है. इसका मतलब है कि ट्रांसफ़ॉर्मेशन ऐक्शन, TensorFlow की तरह ही होगा और उसे लागू करने का काम, ऑपरेटिंग सिस्टम पर निर्भर नहीं करेगा.

डेवलपर, पसंद के मुताबिक प्रोसेसर भी बना सकते हैं. इन मामलों में, ट्रेनिंग प्रोसेस के मुताबिक होना ज़रूरी है. इसका मतलब है कि दोबारा बनाने की संभावना बढ़ाने के लिए, ट्रेनिंग और अनुमान, दोनों पर एक ही प्रीप्रोसेसिंग लागू होनी चाहिए.

क्वांटाइज़ेशन

TensorImage या TensorBuffer जैसे इनपुट या आउटपुट ऑब्जेक्ट शुरू करते समय, आपको उनके टाइप DataType.UINT8 या DataType.FLOAT32 के तौर पर तय करने होंगे.

TensorImage tensorImage = new TensorImage(DataType.UINT8);
TensorBuffer probabilityBuffer =
    TensorBuffer.createFixedSize(new int[]{1, 1001}, DataType.UINT8);

TensorProcessor का इस्तेमाल, इनपुट टेंसर को मापने या आउटपुट टेंसर को कम करने के लिए किया जा सकता है. उदाहरण के लिए, वॉल्यूम वाले आउटपुट TensorBuffer को प्रोसेस करते समय डेवलपर, DequantizeOp का इस्तेमाल करके, नतीजे को 0 और 1 के बीच के फ़्लोटिंग पॉइंट प्रॉबबिलिटी के तौर पर घटा सकता है:

import org.tensorflow.lite.support.common.TensorProcessor;

// Post-processor which dequantize the result
TensorProcessor probabilityProcessor =
    new TensorProcessor.Builder().add(new DequantizeOp(0, 1/255.0)).build();
TensorBuffer dequantizedBuffer = probabilityProcessor.process(probabilityBuffer);

टेंसर के क्वांटाइज़ेशन पैरामीटर को मेटाडेटा एक्सट्रैक्टर लाइब्रेरी से पढ़ा जा सकता है.