iOS पर मशीन लर्निंग किट की मदद से अनुमान लगाने के लिए, TensorFlow Lite मॉडल का इस्तेमाल करें

मशीन लर्निंग का इस्तेमाल करने के लिए, TensorFlow Lite मॉडल.

ML Kit, TensorFlow Lite मॉडल का इस्तेमाल सिर्फ़ iOS 9 और नया.

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

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

    Swift

    import Firebase

    Objective-C

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

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

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

Firebase पर मॉडल होस्ट करके, मॉडल को अपडेट किया जा सकता है. हालांकि, इसके लिए कोई हैं और आप इन कामों के लिए Remote Config और A/B Testing का इस्तेमाल कर सकते हैं उपयोगकर्ताओं के अलग-अलग सेट को डाइनैमिक तौर पर अलग-अलग मॉडल दिखाते हैं.

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

मॉडल को अपने ऐप्लिकेशन के साथ बंडल करके, अपने ऐप्लिकेशन की एमएल (मशीन लर्निंग) सुविधाओं को पक्का किया जा सकता है Firebase से होस्ट किया गया मॉडल उपलब्ध न होने पर भी काम करता है.

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

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

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

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

ऐप्लिकेशन के साथ बंडल मॉडल

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

मॉडल लोड करें

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

Firebase के होस्ट किए गए मॉडल को कॉन्फ़िगर करना

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

Swift

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

Objective-C

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

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

Swift

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

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

Objective-C

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

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

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

लोकल मॉडल कॉन्फ़िगर करना

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

Swift

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

Objective-C

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

अपने मॉडल की मदद से अनुवादक बनाएं

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

अगर आपके पास सिर्फ़ लोकल-बंडल किया गया मॉडल है, तो बस CustomLocalModel को पास करें modelInterpreter(localModel:) के लिए आपत्ति है:

Swift

let interpreter = ModelInterpreter.modelInterpreter(localModel: localModel)

Objective-C

FIRModelInterpreter *interpreter =
    [FIRModelInterpreter modelInterpreterForLocalModel:localModel];

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

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

Swift

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

Objective-C

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

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

ऑब्ज़र्वर को डिफ़ॉल्ट में अटैच करके मॉडल डाउनलोड स्थिति का पता लगाया जा सकता है सूचना केंद्र. पक्का करें कि ऑब्ज़र्वर में, self के लिए कमज़ोर रेफ़रंस का इस्तेमाल किया गया हो ब्लॉक है, क्योंकि डाउनलोड होने में कुछ समय लग सकता है और मूल ऑब्जेक्ट डाउनलोड पूरा होने पर खाली हो जाएगा. उदाहरण के लिए:

Swift

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]
    // ...
}

Objective-C

__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 वैल्यू का Nx224x224x3 अरे, जो N 224x224 तीन चैनल वाली (आरजीबी) इमेज और आउटपुट के तौर पर, 1,000 Float वैल्यू. हर वैल्यू, इस बात की संभावना बताती है कि इमेज में शामिल है या नहीं यह मॉडल, 1,000 कैटगरी का अनुमान लगाता है.

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

Swift

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

Objective-C

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

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 }

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

Objective-C

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:) तरीका.

Swift

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

Objective-C

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

ऑब्जेक्ट के output(index:) तरीके को कॉल करके आउटपुट मिल सकता है वापस किया जाता है. उदाहरण के लिए:

Swift

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

Objective-C

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

आउटपुट का इस्तेमाल करने का तरीका, इस्तेमाल किए जा रहे मॉडल पर निर्भर करता है.

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

Swift

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

Objective-C

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 Kit, ML Kit, उन्हें मानक क्रमिक प्रोटोबफ़ फ़ॉर्मैट में इसमें सेव करता है: लोकल स्टोरेज.

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