Apple प्लैटफ़ॉर्म पर पसंद के मुताबिक TensorFlow Lite मॉडल का इस्तेमाल करना

अगर आपका ऐप्लिकेशन, कस्टम TensorFlow Lite मॉडल का इस्तेमाल करता है, तो अपने मॉडल को डिप्लॉय करने के लिए Firebase ML का इस्तेमाल किया जा सकता है. Firebase की मदद से मॉडल डिप्लॉय करके, अपने ऐप्लिकेशन के शुरुआती डाउनलोड साइज़ को कम किया जा सकता है. साथ ही, ऐप्लिकेशन का नया वर्शन रिलीज़ किए बिना, ऐप्लिकेशन के एमएल मॉडल को अपडेट किया जा सकता है. इसके अलावा, Remote Config और A/B Testing की मदद से, उपयोगकर्ताओं के अलग-अलग ग्रुप को डाइनैमिक तौर पर अलग-अलग मॉडल दिखाए जा सकते हैं.

ज़रूरी शर्तें

  • MLModelDownloader लाइब्रेरी सिर्फ़ Swift के लिए उपलब्ध है.
  • TensorFlow Lite, iOS 9 और इसके बाद के वर्शन का इस्तेमाल करने वाले डिवाइसों पर ही काम करता है.

TensorFlow Lite मॉडल

TensorFlow Lite मॉडल, एमएल मॉडल होते हैं. इन्हें मोबाइल डिवाइसों पर चलाने के लिए ऑप्टिमाइज़ किया जाता है. TensorFlow Lite मॉडल पाने के लिए:

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

Firebase के साथ TensorFlowLite का इस्तेमाल करने के लिए, आपको CocoaPods का इस्तेमाल करना होगा. ऐसा इसलिए, क्योंकि फ़िलहाल TensorFlowLite, Swift Package Manager के साथ इंस्टॉल करने की सुविधा नहीं देता है. MLModelDownloader को इंस्टॉल करने के निर्देश पाने के लिए, CocoaPods को इंस्टॉल करने से जुड़ी गाइड देखें.

इन्हें इंस्टॉल करने के बाद, इनका इस्तेमाल करने के लिए Firebase और TensorFlowLite को इंपोर्ट करें.

Swift

import FirebaseMLModelDownloader
import TensorFlowLite

1. मॉडल डिप्लॉय करना

अपने कस्टम TensorFlow मॉडल को डिप्लॉय करने के लिए, Firebase कंसोल या Firebase Admin Python और Node.js SDK टूल का इस्तेमाल करें. कस्टम मॉडल डिप्लॉय और मैनेज करना लेख पढ़ें.

अपने Firebase प्रोजेक्ट में कस्टम मॉडल जोड़ने के बाद, अपने ऐप्लिकेशन में मॉडल को रेफ़रंस किया जा सकता है. इसके लिए, आपको वही नाम इस्तेमाल करना होगा जो आपने मॉडल को दिया था. किसी भी समय, नया TensorFlow Lite मॉडल डिप्लॉय किया जा सकता है. साथ ही, getModel() को कॉल करके, उपयोगकर्ताओं के डिवाइसों पर नया मॉडल डाउनलोड किया जा सकता है. इसके बारे में यहां बताया गया है.

2. मॉडल को डिवाइस पर डाउनलोड करें और TensorFlow Lite इंटरप्रेटर को शुरू करें

अपने ऐप्लिकेशन में TensorFlow Lite मॉडल का इस्तेमाल करने के लिए, पहले Firebase ML SDK टूल का इस्तेमाल करके, डिवाइस पर मॉडल का नया वर्शन डाउनलोड करें.

मॉडल डाउनलोड करने की प्रोसेस शुरू करने के लिए, मॉडल डाउनलोडर के getModel() तरीके को कॉल करें. इसमें, मॉडल को अपलोड करते समय दिया गया नाम, यह जानकारी कि आपको हमेशा नया मॉडल डाउनलोड करना है या नहीं, और वे शर्तें बताएं जिनके तहत आपको डाउनलोड करने की अनुमति देनी है.

डाउनलोड करने के तीन तरीके उपलब्ध हैं:

डाउनलोड का टाइप ब्यौरा
localModel डिवाइस से लोकल मॉडल पाएं. अगर कोई लोकल मॉडल उपलब्ध नहीं है, तो यह latestModel की तरह काम करता है. अगर आपको मॉडल के अपडेट की जांच नहीं करनी है, तो डाउनलोड के इस टाइप का इस्तेमाल करें. उदाहरण के लिए, मान लें कि आपको मॉडल के नाम पाने के लिए Remote Config का इस्तेमाल करना है. साथ ही, आपको हमेशा नए नामों से मॉडल अपलोड करने हैं (सुझाया गया).
localModelUpdateInBackground डिवाइस से लोकल मॉडल पाएं और बैकग्राउंड में मॉडल को अपडेट करना शुरू करें. अगर कोई लोकल मॉडल उपलब्ध नहीं है, तो यह latestModel की तरह काम करता है.
latestModel नया मॉडल पाएं. अगर लोकल मॉडल सबसे नया वर्शन है, तो लोकल मॉडल दिखाता है. अगर ऐसा नहीं है, तो नया मॉडल डाउनलोड करें. जब तक नया वर्शन डाउनलोड नहीं किया जाता, तब तक यह सुविधा काम नहीं करेगी. हालांकि, ऐसा करने का सुझाव नहीं दिया जाता. इस बिहेवियर का इस्तेमाल सिर्फ़ उन मामलों में करें जहां आपको साफ़ तौर पर नए वर्शन की ज़रूरत हो.

आपको मॉडल से जुड़ी सुविधा बंद कर देनी चाहिए. उदाहरण के लिए, जब तक मॉडल डाउनलोड होने की पुष्टि नहीं हो जाती, तब तक अपने यूज़र इंटरफ़ेस (यूआई) के कुछ हिस्से को धूसर कर दें या छिपा दें.

Swift

let conditions = ModelDownloadConditions(allowsCellularAccess: false)
ModelDownloader.modelDownloader()
    .getModel(name: "your_model",
              downloadType: .localModelUpdateInBackground,
              conditions: conditions) { result in
        switch (result) {
        case .success(let customModel):
            do {
                // 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.
                let interpreter = try Interpreter(modelPath: customModel.path)
            } catch {
                // Error. Bad model file?
            }
        case .failure(let error):
            // Download was unsuccessful. Don't enable ML features.
            print(error)
        }
}

कई ऐप्लिकेशन, डाउनलोड करने का टास्क अपने इनिशियलाइज़ेशन कोड में शुरू करते हैं. हालांकि, मॉडल का इस्तेमाल करने से पहले, इसे किसी भी समय शुरू किया जा सकता है.

3. इनपुट डेटा पर अनुमान लगाना

अपने मॉडल के इनपुट और आउटपुट शेप पाना

TensorFlow Lite मॉडल इंटरप्रेटर, इनपुट के तौर पर एक या उससे ज़्यादा मल्टीडाइमेंशनल ऐरे लेता है और आउटपुट के तौर पर भी एक या उससे ज़्यादा मल्टीडाइमेंशनल ऐरे जनरेट करता है. इन कलेक्शन में byte, int, long या float वैल्यू होती हैं. किसी मॉडल को डेटा पास करने या उसके नतीजे का इस्तेमाल करने से पहले, आपको यह पता होना चाहिए कि आपका मॉडल कितनी और किस डाइमेंशन ("शेप") की ऐरे का इस्तेमाल करता है.

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

Python

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] फ़्लोटिंग-पॉइंट वैल्यू हैं, तो आपको इमेज के रंग की वैल्यू को फ़्लोटिंग-पॉइंट रेंज में स्केल करना पड़ सकता है. जैसा कि इस उदाहरण में दिखाया गया है:

Swift

let image: CGImage = // Your input image
guard let context = CGContext(
  data: nil,
  width: image.width, height: image.height,
  bitsPerComponent: 8, bytesPerRow: image.width * 4,
  space: CGColorSpaceCreateDeviceRGB(),
  bitmapInfo: CGImageAlphaInfo.noneSkipFirst.rawValue
) else {
  return false
}

context.draw(image, in: CGRect(x: 0, y: 0, width: image.width, height: image.height))
guard let imageData = context.data else { return false }

var inputData = Data()
for row in 0 ..&lt; 224 {
  for col in 0 ..&lt; 224 {
    let offset = 4 * (row * context.width + col)
    // (Ignore offset 0, the unused alpha channel)
    let red = imageData.load(fromByteOffset: offset+1, as: UInt8.self)
    let green = imageData.load(fromByteOffset: offset+2, as: UInt8.self)
    let blue = imageData.load(fromByteOffset: offset+3, as: UInt8.self)

    // Normalize channel values to [0.0, 1.0]. This requirement varies
    // by model. For example, some models might require values to be
    // normalized to the range [-1.0, 1.0] instead, and others might
    // require fixed-point values or the original bytes.
    var normalizedRed = Float32(red) / 255.0
    var normalizedGreen = Float32(green) / 255.0
    var normalizedBlue = Float32(blue) / 255.0

    // Append normalized values to Data object in RGB order.
    let elementSize = MemoryLayout.size(ofValue: normalizedRed)
    var bytes = [UInt8](repeating: 0, count: elementSize)
    memcpy(&amp;bytes, &amp;normalizedRed, elementSize)
    inputData.append(&amp;bytes, count: elementSize)
    memcpy(&amp;bytes, &amp;normalizedGreen, elementSize)
    inputData.append(&amp;bytes, count: elementSize)
    memcpy(&ammp;bytes, &amp;normalizedBlue, elementSize)
    inputData.append(&amp;bytes, count: elementSize)
  }
}

इसके बाद, अपने इनपुट NSData को इंटरप्रेटर में कॉपी करें और इसे चलाएं:

Swift

try interpreter.allocateTensors()
try interpreter.copy(inputData, toInputAt: 0)
try interpreter.invoke()

इंटरप्रेटर के output(at:) तरीके को कॉल करके, मॉडल का आउटपुट पाया जा सकता है. आउटपुट का इस्तेमाल कैसे किया जाए, यह इस्तेमाल किए जा रहे मॉडल पर निर्भर करता है.

उदाहरण के लिए, अगर आपको क्लासिफ़िकेशन करना है, तो अगले चरण के तौर पर, आपको नतीजे के इंडेक्स को उन लेबल पर मैप करना होगा जो उन्हें दिखाते हैं:

Swift

let output = try interpreter.output(at: 0)
let probabilities =
        UnsafeMutableBufferPointer<Float32>.allocate(capacity: 1000)
output.data.copyBytes(to: probabilities)

guard let labelPath = Bundle.main.path(forResource: "retrained_labels", ofType: "txt") else { return }
let fileContents = try? String(contentsOfFile: labelPath)
guard let labels = fileContents?.components(separatedBy: "\n") else { return }

for i in labels.indices {
    print("\(labels[i]): \(probabilities[i])")
}

अपेंडिक्स: मॉडल की सुरक्षा

आपने अपने TensorFlow Lite मॉडल को Firebase ML के लिए उपलब्ध कराने का तरीका चाहे जो भी चुना हो, Firebase ML उन्हें लोकल स्टोरेज में स्टैंडर्ड सीरियलाइज़ किए गए प्रोटोबफ़ फ़ॉर्मैट में सेव करता है.

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