Catch up on highlights from Firebase at Google I/O 2023. Learn more

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

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

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

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

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

    तीव्र

    import Firebase

    उद्देश्य सी

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

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

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

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

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

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

Firebase पर मॉडल होस्ट करें

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

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

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

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

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

मॉडल लोड करें

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

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

अगर आपने अपने मॉडल को Firebase के साथ होस्ट किया है, तो एक 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"];

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

तीव्र

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];

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

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

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

तीव्र

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

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

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

उदाहरण के लिए, एक फ़्लोटिंग-पॉइंट छवि वर्गीकरण मॉडल N 224x224 तीन-चैनल (आरजीबी) छवियों के बैच का प्रतिनिधित्व करते हुए Float मानों की एक N x224x224x3 सरणी इनपुट के रूप में ले सकता है, और आउटपुट के रूप में 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 किट उन्हें स्थानीय स्टोरेज में मानक क्रमबद्ध प्रोटोबफ प्रारूप में संग्रहीत करता है।

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