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

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

एमएल किट केवल iOS 9 और नए संस्करण चलाने वाले उपकरणों पर TensorFlow Lite मॉडल का उपयोग कर सकता है।

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

  1. यदि आपने पहले से ही अपने ऐप में फायरबेस नहीं जोड़ा है, तो आरंभ करने की मार्गदर्शिका में दिए गए चरणों का पालन करके ऐसा करें।
  2. अपने पॉडफाइल में एमएल किट लाइब्रेरी शामिल करें:
    pod 'Firebase/MLModelInterpreter', '6.25.0'
    
    अपने प्रोजेक्ट के पॉड इंस्टॉल या अपडेट करने के बाद, अपने Xcode प्रोजेक्ट को इसके .xcworkspace का उपयोग करके खोलना सुनिश्चित करें।
  3. अपने ऐप में, फ़ायरबेस आयात करें:

    तीव्र

    import Firebase

    उद्देश्य सी

    @import Firebase;
  4. जिस TensorFlow मॉडल का आप उपयोग करना चाहते हैं उसे TensorFlow Lite प्रारूप में बदलें। TOCO देखें: TensorFlow Lite ऑप्टिमाइज़िंग कन्वर्टर

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

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

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

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

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

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

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

  1. फायरबेस कंसोल के एमएल किट अनुभाग में, कस्टम टैब पर क्लिक करें।
  2. कस्टम मॉडल जोड़ें (या कोई अन्य मॉडल जोड़ें ) पर क्लिक करें।
  3. एक नाम निर्दिष्ट करें जिसका उपयोग आपके फायरबेस प्रोजेक्ट में आपके मॉडल की पहचान करने के लिए किया जाएगा, फिर TensorFlow Lite मॉडल फ़ाइल अपलोड करें (आमतौर पर .tflite या .lite में समाप्त होती है)।

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

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

अपने TensorFlow Lite मॉडल को अपने ऐप के साथ बंडल करने के लिए, मॉडल फ़ाइल (आमतौर पर .tflite या .lite में समाप्त होती है) को अपने Xcode प्रोजेक्ट में जोड़ें, ऐसा करते समय कॉपी बंडल संसाधनों का चयन करने का ध्यान रखें। मॉडल फ़ाइल ऐप बंडल में शामिल की जाएगी और एमएल किट के लिए उपलब्ध होगी।

मॉडल लोड करें

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

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

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

तीव्र

let remoteModel = CustomRemoteModel(
  name: "your_remote_model"  // The name you assigned in the Firebase console.
)

उद्देश्य सी

// Initialize using the name you assigned in the Firebase console.
FIRCustomRemoteModel *remoteModel =
    [[FIRCustomRemoteModel alloc] initWithName:@"your_remote_model"];

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

तीव्र

let downloadConditions = ModelDownloadConditions(
  allowsCellularAccess: true,
  allowsBackgroundDownloading: true
)

let downloadProgress = ModelManager.modelManager().download(
  remoteModel,
  conditions: downloadConditions
)

उद्देश्य सी

FIRModelDownloadConditions *downloadConditions =
    [[FIRModelDownloadConditions alloc] initWithAllowsCellularAccess:YES
                                         allowsBackgroundDownloading:YES];

NSProgress *downloadProgress =
    [[FIRModelManager modelManager] downloadRemoteModel:remoteModel
                                             conditions:downloadConditions];

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

एक स्थानीय मॉडल कॉन्फ़िगर करें

यदि आपने मॉडल को अपने ऐप के साथ बंडल किया है, तो TensorFlow Lite मॉडल का फ़ाइल नाम निर्दिष्ट करते हुए एक CustomLocalModel ऑब्जेक्ट बनाएं:

तीव्र

guard let modelPath = Bundle.main.path(
  forResource: "your_model",
  ofType: "tflite",
  inDirectory: "your_model_directory"
) else { /* Handle error. */ }
let localModel = CustomLocalModel(modelPath: modelPath)

उद्देश्य सी

NSString *modelPath = [NSBundle.mainBundle pathForResource:@"your_model"
                                                    ofType:@"tflite"
                                               inDirectory:@"your_model_directory"];
FIRCustomLocalModel *localModel =
    [[FIRCustomLocalModel alloc] initWithModelPath:modelPath];

अपने मॉडल से एक दुभाषिया बनाएं

अपने मॉडल स्रोतों को कॉन्फ़िगर करने के बाद, उनमें से एक से एक ModelInterpreter ऑब्जेक्ट बनाएं।

यदि आपके पास केवल स्थानीय रूप से बंडल किया गया मॉडल है, तो बस CustomLocalModel ऑब्जेक्ट को modelInterpreter(localModel:) पर पास करें:

तीव्र

let interpreter = ModelInterpreter.modelInterpreter(localModel: localModel)

उद्देश्य सी

FIRModelInterpreter *interpreter =
    [FIRModelInterpreter modelInterpreterForLocalModel:localModel];

यदि आपके पास दूरस्थ रूप से होस्ट किया गया मॉडल है, तो आपको इसे चलाने से पहले यह जांचना होगा कि इसे डाउनलोड किया गया है। आप मॉडल प्रबंधक की isModelDownloaded(remoteModel:) विधि का उपयोग करके मॉडल डाउनलोड कार्य की स्थिति की जांच कर सकते हैं।

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

तीव्र

var interpreter: ModelInterpreter
if ModelManager.modelManager().isModelDownloaded(remoteModel) {
  interpreter = ModelInterpreter.modelInterpreter(remoteModel: remoteModel)
} else {
  interpreter = ModelInterpreter.modelInterpreter(localModel: localModel)
}

उद्देश्य सी

FIRModelInterpreter *interpreter;
if ([[FIRModelManager modelManager] isModelDownloaded:remoteModel]) {
  interpreter = [FIRModelInterpreter modelInterpreterForRemoteModel:remoteModel];
} else {
  interpreter = [FIRModelInterpreter modelInterpreterForLocalModel:localModel];
}

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

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

तीव्र

NotificationCenter.default.addObserver(
    forName: .firebaseMLModelDownloadDidSucceed,
    object: nil,
    queue: nil
) { [weak self] notification in
    guard let strongSelf = self,
        let userInfo = notification.userInfo,
        let model = userInfo[ModelDownloadUserInfoKey.remoteModel.rawValue]
            as? RemoteModel,
        model.name == "your_remote_model"
        else { return }
    // The model was downloaded and is available on the device
}

NotificationCenter.default.addObserver(
    forName: .firebaseMLModelDownloadDidFail,
    object: nil,
    queue: nil
) { [weak self] notification in
    guard let strongSelf = self,
        let userInfo = notification.userInfo,
        let model = userInfo[ModelDownloadUserInfoKey.remoteModel.rawValue]
            as? RemoteModel
        else { return }
    let error = userInfo[ModelDownloadUserInfoKey.error.rawValue]
    // ...
}

उद्देश्य सी

__weak typeof(self) weakSelf = self;

[NSNotificationCenter.defaultCenter
    addObserverForName:FIRModelDownloadDidSucceedNotification
                object:nil
                 queue:nil
            usingBlock:^(NSNotification *_Nonnull note) {
              if (weakSelf == nil | note.userInfo == nil) {
                return;
              }
              __strong typeof(self) strongSelf = weakSelf;

              FIRRemoteModel *model = note.userInfo[FIRModelDownloadUserInfoKeyRemoteModel];
              if ([model.name isEqualToString:@"your_remote_model"]) {
                // The model was downloaded and is available on the device
              }
            }];

[NSNotificationCenter.defaultCenter
    addObserverForName:FIRModelDownloadDidFailNotification
                object:nil
                 queue:nil
            usingBlock:^(NSNotification *_Nonnull note) {
              if (weakSelf == nil | note.userInfo == nil) {
                return;
              }
              __strong typeof(self) strongSelf = weakSelf;

              NSError *error = note.userInfo[FIRModelDownloadUserInfoKeyError];
            }];

मॉडल का इनपुट और आउटपुट निर्दिष्ट करें

इसके बाद, मॉडल दुभाषिया के इनपुट और आउटपुट स्वरूपों को कॉन्फ़िगर करें।

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'>

अपने मॉडल के इनपुट और आउटपुट का प्रारूप निर्धारित करने के बाद, एक ModelInputOutputOptions ऑब्जेक्ट बनाकर अपने ऐप के मॉडल दुभाषिया को कॉन्फ़िगर करें।

उदाहरण के लिए, एक फ़्लोटिंग-पॉइंट छवि वर्गीकरण मॉडल इनपुट के रूप में Float मानों की एक N x224x224x3 सरणी ले सकता है, जो N 224x224 तीन-चैनल (RGB) छवियों के एक बैच का प्रतिनिधित्व करता है, और आउटपुट के रूप में 1000 Float मानों की एक सूची तैयार कर सकता है, जिनमें से प्रत्येक का प्रतिनिधित्व करता है। संभावना है कि छवि उन 1000 श्रेणियों में से एक का सदस्य है जिसकी मॉडल भविष्यवाणी करता है।

ऐसे मॉडल के लिए, आप मॉडल दुभाषिया के इनपुट और आउटपुट को नीचे दिखाए अनुसार कॉन्फ़िगर करेंगे:

तीव्र

let ioOptions = ModelInputOutputOptions()
do {
    try ioOptions.setInputFormat(index: 0, type: .float32, dimensions: [1, 224, 224, 3])
    try ioOptions.setOutputFormat(index: 0, type: .float32, dimensions: [1, 1000])
} catch let error as NSError {
    print("Failed to set input or output format with error: \(error.localizedDescription)")
}

उद्देश्य सी

FIRModelInputOutputOptions *ioOptions = [[FIRModelInputOutputOptions alloc] init];
NSError *error;
[ioOptions setInputFormatForIndex:0
                             type:FIRModelElementTypeFloat32
                       dimensions:@[@1, @224, @224, @3]
                            error:&error];
if (error != nil) { return; }
[ioOptions setOutputFormatForIndex:0
                              type:FIRModelElementTypeFloat32
                        dimensions:@[@1, @1000]
                             error:&error];
if (error != nil) { return; }

इनपुट डेटा पर अनुमान लगाएं

अंत में, मॉडल का उपयोग करके अनुमान लगाने के लिए, अपना इनपुट डेटा प्राप्त करें, डेटा पर कोई भी परिवर्तन करें जो आपके मॉडल के लिए आवश्यक हो सकता है, और एक Data ऑब्जेक्ट बनाएं जिसमें डेटा शामिल हो।

उदाहरण के लिए, यदि आपका मॉडल छवियों को संसाधित करता है, और आपके मॉडल में [BATCH_SIZE, 224, 224, 3] फ़्लोटिंग-पॉइंट मानों के इनपुट आयाम हैं, तो आपको निम्न उदाहरण के अनुसार छवि के रंग मानों को फ़्लोटिंग-पॉइंट रेंज में स्केल करना पड़ सकता है :

तीव्र

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 }

let inputs = ModelInputs()
var inputData = Data()
do {
  for row in 0 ..< 224 {
    for col in 0 ..< 224 {
      let offset = 4 * (col * context.width + row)
      // (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(&bytes, &normalizedRed, elementSize)
      inputData.append(&bytes, count: elementSize)
      memcpy(&bytes, &normalizedGreen, elementSize)
      inputData.append(&bytes, count: elementSize)
      memcpy(&ammp;bytes, &normalizedBlue, elementSize)
      inputData.append(&bytes, count: elementSize)
    }
  }
  try inputs.addInput(inputData)
} catch let error {
  print("Failed to add input: \(error)")
}

उद्देश्य सी

CGImageRef image = // Your input image
long imageWidth = CGImageGetWidth(image);
long imageHeight = CGImageGetHeight(image);
CGContextRef context = CGBitmapContextCreate(nil,
                                             imageWidth, imageHeight,
                                             8,
                                             imageWidth * 4,
                                             CGColorSpaceCreateDeviceRGB(),
                                             kCGImageAlphaNoneSkipFirst);
CGContextDrawImage(context, CGRectMake(0, 0, imageWidth, imageHeight), image);
UInt8 *imageData = CGBitmapContextGetData(context);

FIRModelInputs *inputs = [[FIRModelInputs alloc] init];
NSMutableData *inputData = [[NSMutableData alloc] initWithCapacity:0];

for (int row = 0; row < 224; row++) {
  for (int col = 0; col < 224; col++) {
    long offset = 4 * (col * imageWidth + row);
    // 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.
    // (Ignore offset 0, the unused alpha channel)
    Float32 red = imageData[offset+1] / 255.0f;
    Float32 green = imageData[offset+2] / 255.0f;
    Float32 blue = imageData[offset+3] / 255.0f;

    [inputData appendBytes:&red length:sizeof(red)];
    [inputData appendBytes:&green length:sizeof(green)];
    [inputData appendBytes:&blue length:sizeof(blue)];
  }
}

[inputs addInput:inputData error:&error];
if (error != nil) { return nil; }

अपना मॉडल इनपुट तैयार करने के बाद (और यह पुष्टि करने के बाद कि मॉडल उपलब्ध है), इनपुट और इनपुट/आउटपुट विकल्पों को अपने मॉडल दुभाषिया की run(inputs:options:completion:) विधि में पास करें।

तीव्र

interpreter.run(inputs: inputs, options: ioOptions) { outputs, error in
    guard error == nil, let outputs = outputs else { return }
    // Process outputs
    // ...
}

उद्देश्य सी

[interpreter runWithInputs:inputs
                   options:ioOptions
                completion:^(FIRModelOutputs * _Nullable outputs,
                             NSError * _Nullable error) {
  if (error != nil || outputs == nil) {
    return;
  }
  // Process outputs
  // ...
}];

आप लौटाए गए ऑब्जेक्ट के output(index:) विधि को कॉल करके आउटपुट प्राप्त कर सकते हैं। उदाहरण के लिए:

तीव्र

// Get first and only output of inference with a batch size of 1
let output = try? outputs.output(index: 0) as? [[NSNumber]]
let probabilities = output??[0]

उद्देश्य सी

// Get first and only output of inference with a batch size of 1
NSError *outputError;
NSArray *probabilites = [outputs outputAtIndex:0 error:&outputError][0];

आप आउटपुट का उपयोग कैसे करते हैं यह उस मॉडल पर निर्भर करता है जिसका आप उपयोग कर रहे हैं।

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

तीव्र

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 0 ..< labels.count {
  if let probability = probabilities?[i] {
    print("\(labels[i]): \(probability)")
  }
}

उद्देश्य सी

NSError *labelReadError = nil;
NSString *labelPath = [NSBundle.mainBundle pathForResource:@"retrained_labels"
                                                    ofType:@"txt"];
NSString *fileContents = [NSString stringWithContentsOfFile:labelPath
                                                   encoding:NSUTF8StringEncoding
                                                      error:&labelReadError];
if (labelReadError != nil || fileContents == NULL) { return; }
NSArray<NSString *> *labels = [fileContents componentsSeparatedByString:@"\n"];
for (int i = 0; i < labels.count; i++) {
    NSString *label = labels[i];
    NSNumber *probability = probabilites[i];
    NSLog(@"%@: %f", label, probability.floatValue);
}

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

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

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