स्पैम फ़िल्टर करने वाले मशीन लर्निंग मॉडल का इस्तेमाल करने के लिए, अपने ऐप्लिकेशन को अपडेट करें

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

इस कोडलैब में, आपको वह ऐप्लिकेशन अपडेट करना होगा जिसे आपने मोबाइल पर टेक्स्ट की कैटगरी तय करने की सुविधा के साथ शुरुआत करने वाले पिछले कोडलैब में बनाया था.

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

  • इस कोडलैब को, मशीन लर्निंग के बारे में नए डेवलपर के लिए डिज़ाइन किया गया है.
  • कोडलैब, क्रम से लगाए गए पाथवे का हिस्सा है. अगर आपने अब तक बुनियादी मैसेजिंग स्टाइल वाला ऐप्लिकेशन बनाने या टिप्पणी के लिए स्पैम का पता लगाने वाला मशीन लर्निंग मॉडल बनाने का कोर्स पूरा नहीं किया है, तो कृपया अभी इसे पूरा करें.

आप क्या बनाएंगे [बनाएं या सीखें]

  • आपको अपने ऐप्लिकेशन में, कस्टम मॉडल को जोड़ने का तरीका पता चलेगा. यह मॉडल, पिछले चरणों में बनाया गया है.

आपको किन चीज़ों की ज़रूरत होगी

  • Android Studio या iOS के लिए CocoaPods

2. मौजूदा Android ऐप्लिकेशन खोलना

कोडलैब (कोड बनाना सीखना) 1 का पालन करके या इस डेटा स्टोर करने की जगह को क्लोन करके और TextClassificationStep1 से ऐप्लिकेशन लोड करके कोड पाया जा सकता है.

git clone https://github.com/googlecodelabs/odml-pathways

यह आपको TextClassificationOnMobile->Android पाथ में दिखेगा.

पूरा हो चुका कोड, आपके लिए TextClassificationStep2 के तौर पर भी उपलब्ध है.

इसके खुलने के बाद, दूसरे चरण पर जाएं.

3. मॉडल फ़ाइल और मेटाडेटा इंपोर्ट करना

टिप्पणी की स्पैम की पहचान करने वाला मशीन लर्निंग मॉडल बनाने वाले कोडलैब में, आपने .TFLITE मॉडल बनाया है.

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

ऐसेट डायरेक्ट्री बनाकर, इसे अपने प्रोजेक्ट में जोड़ें.

  1. प्रोजेक्ट नेविगेटर का इस्तेमाल करके, पक्का करें कि सबसे ऊपर Android चुना गया हो.
  2. ऐप्लिकेशन फ़ोल्डर पर राइट क्लिक करें. नई > डायरेक्ट्री चुनें.

d7c3e9f21035fc15.png

  1. नई डायरेक्ट्री डायलॉग में, src/main/assets चुनें.

2137f956a1ba4ef0.png

आपको ऐप्लिकेशन में एक नया ऐसेट फ़ोल्डर दिखेगा.

ae858835e1a90445.png

  1. ऐसेट पर राइट क्लिक करें.
  2. इसके बाद, आपको Mac पर Finder में दिखाएं विकल्प दिखेगा. उसे चुनें. (Windows पर, Explorer में दिखाएं लिखा होगा. Ubuntu पर, फ़ाइलों में दिखाएं लिखा होगा.)

e61aaa3b73c5ab68.png

फ़ाइलों की जगह दिखाने के लिए, Finder (Windows पर File Explorer, Linux पर Files) लॉन्च होगा.

  1. labels.txt, model.tflite, और vocab फ़ाइलों को इस डायरेक्ट्री में कॉपी करें.

14f382cc19552a56.png

  1. Android Studio पर वापस जाएं. आपको ये फ़ाइलें ऐसेट फ़ोल्डर में दिखेंगी.

150ed2a1d2f7a10d.png

4. TensorFlow Lite का इस्तेमाल करने के लिए, अपने build.gradle को अपडेट करें

TensorFlow Lite और उससे काम करने वाली TensorFlow Lite टास्क लाइब्रेरी का इस्तेमाल करने के लिए, आपको अपनी build.gradle फ़ाइल अपडेट करनी होगी.

Android प्रोजेक्ट में अक्सर एक से ज़्यादा होते हैं, इसलिए पक्का करें कि ऐप्लिकेशन लेवल एक ही हो. Android व्यू के प्रोजेक्ट एक्सप्लोरर में, इसे अपने Gradle स्क्रिप्ट सेक्शन में ढूंढें. सही आइकॉन को .app के साथ लेबल किया जाएगा, जैसा कि यहां दिखाया गया है:

6426051e614bc42f.png

आपको इस फ़ाइल में दो बदलाव करने होंगे. पहला, सबसे नीचे मौजूद डिपेंडेंसी सेक्शन में है. TensorFlow Lite की टास्क लाइब्रेरी के लिए, इस तरह से implementation टेक्स्ट जोड़ें:

implementation 'org.tensorflow:tensorflow-lite-task-text:0.1.0'

इस लेख को लिखे जाने के बाद, वर्शन नंबर बदल सकता है. इसलिए, नए वर्शन के बारे में जानने के लिए, https://www.tensorflow.org/lite/inference_with_metadata/task_library/nl_classifier पर जाएं.

टास्क लाइब्रेरी के लिए भी, SDK टूल का वर्शन कम से कम 21 होना चाहिए. android > default config में जाकर, इस सेटिंग को 21 पर सेट करें:

c100b68450b8812f.png

अब आपके पास सभी डिपेंडेंसी हैं. इसलिए, कोडिंग शुरू करें!

5. हेल्पर क्लास जोड़ना

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

  1. उस पैकेज के नाम पर दायां क्लिक करें जिसमें आपका MainActivity कोड है.
  2. नया > पैकेज चुनें.

d5911ded56b5df35.png

  1. आपको स्क्रीन के बीच में एक डायलॉग दिखेगा, जिसमें आपको पैकेज का नाम डालने के लिए कहा जाएगा. इसे मौजूदा पैकेज के नाम के आखिर में जोड़ें. (यहां इसे हेल्पर कहा जाता है.)

3b9f1f822f99b371.png

  1. इसके बाद, प्रोजेक्ट एक्सप्लोरर में हेल्पर फ़ोल्डर पर राइट क्लिक करें.
  2. नया > Java क्लास चुनें और इसे TextClassificationClient नाम दें. अगले चरण में, आपको फ़ाइल में बदलाव करना होगा.

आपकी TextClassificationClient हेल्पर क्लास इस तरह दिखेगी (हालांकि, आपके पैकेज का नाम अलग हो सकता है.)

package com.google.devrel.textclassificationstep1.helpers;

public class TextClassificationClient {
}
  1. इस कोड की मदद से फ़ाइल अपडेट करें:
package com.google.devrel.textclassificationstep2.helpers;

import android.content.Context;
import android.util.Log;
import java.io.IOException;
import java.util.List;

import org.tensorflow.lite.support.label.Category;
import org.tensorflow.lite.task.text.nlclassifier.NLClassifier;

public class TextClassificationClient {
    private static final String MODEL_PATH = "model.tflite";
    private static final String TAG = "CommentSpam";
    private final Context context;

    NLClassifier classifier;

    public TextClassificationClient(Context context) {
        this.context = context;
    }

    public void load() {
        try {
            classifier = NLClassifier.createFromFile(context, MODEL_PATH);
        } catch (IOException e) {
            Log.e(TAG, e.getMessage());
        }
    }

    public void unload() {
        classifier.close();
        classifier = null;
    }

    public List<Category> classify(String text) {
        List<Category> apiResults = classifier.classify(text);
        return apiResults;
    }

}

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

load() तरीके में, यह मॉडल पाथ से एक नया NLClassifier टाइप इंस्टैंशिएट करेगा. मॉडल पाथ, मॉडल का नाम होता है: model.tflite. NLClassifier टाइप, टेक्स्ट टास्क लाइब्रेरी का हिस्सा है. यह आपकी स्ट्रिंग को टोकन में बदलने, सही क्रम लंबाई का इस्तेमाल करके, उसे मॉडल में पास करने, और नतीजों को पार्स करने में आपकी मदद करता है.

(इन बारे में ज़्यादा जानकारी के लिए, 'स्पैम टिप्पणी करने की सुविधा देने वाला मशीन लर्निंग मॉडल' पर फिर से जाएं.

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

अब आपके पास हेल्पर क्लास है, तो अपने MainActivity पर वापस जाएं और अपने टेक्स्ट की कैटगरी तय करने के लिए इसे अपडेट करें. आपको यह अगले चरण में दिखेगा!

6. टेक्स्ट को अलग-अलग कैटगरी में बांटना

अपने MainActivity में, आपको सबसे पहले वे हेल्पर इंपोर्ट करने होंगे जिन्हें आपने अभी-अभी बनाया है!

  1. MainActivity.kt के सबसे ऊपर, अन्य इंपोर्ट के साथ-साथ ये जोड़ें:
import com.google.devrel.textclassificationstep2.helpers.TextClassificationClient
import org.tensorflow.lite.support.label.Category
  1. इसके बाद, आपको हेल्पर लोड करने होंगे. onCreate में, setContentView लाइन के ठीक बाद, हेल्पर क्लास को इंस्टैंशिएट और लोड करने के लिए, इन लाइनों को जोड़ें:
val client = TextClassificationClient(applicationContext)
client.load()

फ़िलहाल, आपके बटन का onClickListener ऐसा दिखना चाहिए:

btnSendText.setOnClickListener {
     var toSend:String = txtInput.text.toString()
     txtOutput.text = toSend
 }
  1. इसे इस तरह अपडेट करें:
btnSendText.setOnClickListener {
    var toSend:String = txtInput.text.toString()
    var results:List<Category> = client.classify(toSend)
    val score = results[1].score
    if(score>0.8){
        txtOutput.text = "Your message was detected as spam with a score of " + score.toString() + " and not sent!"
    } else {
        txtOutput.text = "Message sent! \nSpam score was:" + score.toString()
    }
    txtInput.text.clear()
}

ऐसा करने पर, सिर्फ़ उपयोगकर्ता के इनपुट को दिखाने से लेकर, उसकी कैटगरी तय करने तक की सुविधा बदल जाती है.

  1. इस लाइन की मदद से, उपयोगकर्ता की डाली गई स्ट्रिंग को मॉडल में पास किया जाता है. इससे आपको नतीजे मिलते हैं:
var results:List<Category> = client.classify(toSend)

इसमें सिर्फ़ दो कैटगरी हैं False और True

. (TensorFlow उन्हें वर्णमाला के क्रम में क्रम से लगाता है, इसलिए False आइटम 0 और True आइटम 1 होगा.)

  1. वैल्यू True होने की संभावना का स्कोर पाने के लिए, results[1].score को इस तरह देखा जा सकता है:
    val score = results[1].score
  1. थ्रेशोल्ड वैल्यू (इस मामले में 0.8) चुनें. इससे यह तय होता है कि अगर 'सही' कैटगरी का स्कोर थ्रेशोल्ड वैल्यू (0.8) से ज़्यादा है, तो मैसेज स्पैम है. अगर ऐसा नहीं है, तो मैसेज स्पैम नहीं है और उसे भेजा जा सकता है:
    if(score>0.8){
        txtOutput.text = "Your message was detected as spam with a score of " + score.toString() + " and not sent!"
    } else {
        txtOutput.text = "Message sent! \nSpam score was:" + score.toString()
    }
  1. मॉडल को इस्तेमाल करने का तरीका यहां देखें. "सामान खरीदने के लिए मेरे ब्लॉग पर जाएं!" मैसेज को स्पैम के तौर पर फ़्लैग किया गया, क्योंकि:

1fb0b5de9e566e.png

इसके उलट, "नमस्ते, मज़ेदार ट्यूटोरियल, धन्यवाद!" मैसेज को स्पैम के तौर पर मार्क किए जाने की संभावना बहुत कम थी:

73f38bdb488b29b3.png

7. TensorFlow Lite मॉडल का इस्तेमाल करने के लिए, अपने iOS ऐप्लिकेशन को अपडेट करना

कोडलैब (कोड बनाना सीखना) 1 का पालन करके या इस डेटा स्टोर करने की जगह को क्लोन करके और TextClassificationStep1 से ऐप्लिकेशन लोड करके कोड पाया जा सकता है. यह आपको TextClassificationOnMobile->iOS पाथ में दिखेगा.

हो गया कोड, आपके लिए TextClassificationStep2 के तौर पर भी उपलब्ध है.

स्पैम टिप्पणी का पता लगाने के लिए मशीन लर्निंग मॉडल बनाने वाले कोडलैब में, आपने एक बहुत ही आसान ऐप्लिकेशन बनाया था. इसकी मदद से, उपयोगकर्ता UITextView में कोई मैसेज टाइप कर सकता था और उसे बिना किसी फ़िल्टर के आउटपुट में भेज सकता था.

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

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

TensorFlow Lite को शामिल करने के लिए, आपको CocoaPods का इस्तेमाल करना होगा. अगर आपने ये पहले से इंस्टॉल नहीं किए हैं, तो https://cocoapods.org/ पर दिए गए निर्देशों का पालन करके ऐसा किया जा सकता है.

  1. CocoaPods इंस्टॉल करने के बाद, TextClassification ऐप्लिकेशन के लिए .xcproject की डायरेक्ट्री में Podfile नाम की फ़ाइल बनाएं. इस फ़ाइल का कॉन्टेंट कुछ ऐसा दिखना चाहिए:
target 'TextClassificationStep2' do
  use_frameworks!

  # Pods for NLPClassifier
    pod 'TensorFlowLiteSwift'

end

पहली लाइन में आपके ऐप्लिकेशन का नाम होना चाहिए, न कि "TextClassificationStep2."

Terminal का इस्तेमाल करके, उस डायरेक्ट्री पर जाएं और pod install चलाएं. अगर यह प्रोसेस पूरी हो जाती है, तो आपके पास Pods नाम की एक नई डायरेक्ट्री और एक नई .xcworkspace फ़ाइल बन जाएगी. आने वाले समय में, .xcproject के बजाय इसका इस्तेमाल किया जाएगा.

अगर ऐसा नहीं होता है, तो कृपया पक्का करें कि आपके पास उसी डायरेक्ट्री में Podfile है, जिसमें .xcproject मौजूद था. आम तौर पर, गलत डायरेक्ट्री में मौजूद podfile या टारगेट का गलत नाम, इस गड़बड़ी की मुख्य वजह होती है!

8. मॉडल और शब्दावली फ़ाइलें जोड़ें

जब आपने TensorFlow Lite मॉडल मेकर की मदद से मॉडल बनाया, तब आपने मॉडल (model.tflite के तौर पर) और वोकैब (vocab.txt के तौर पर) का आउटपुट दिया.

  1. उन्हें Finder से अपनी प्रोजेक्ट विंडो में खींचकर छोड़कर, अपने प्रोजेक्ट में जोड़ें. पक्का करें कि टारगेट में जोड़ें विकल्प पर सही का निशान लगा है:

1ee9eaa00ee79859.png

सभी चरणों को पूरा करने के बाद, आपको अपने प्रोजेक्ट में ये बदलाव दिखेंगे:

b63502b23911fd42.png

  1. पक्का करें कि वे बंडल में जोड़े गए हों, ताकि उन्हें किसी डिवाइस पर डिप्लॉय किया जा सके. इसके लिए, अपना प्रोजेक्ट चुनें (ऊपर दिए गए स्क्रीनशॉट में, यह नीला आइकॉन TextClassificationStep2 है) और बिल्ड के चरण टैब देखें:

20b7cb603d49b457.png

9. शब्दावली लोड करना

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

कोड को देखने के लिए, फ़ाइल को Xcode में खोला जा सकता है. "song" जैसे शब्दों को 6 और "love" को 12 में बदल दिया जाता है. असल में, क्रम फ़्रीक्वेंसी के क्रम में होता है. इसलिए, डेटासेट में "मैं" सबसे ज़्यादा बार इस्तेमाल किया गया शब्द था. इसके बाद, "जांच करें" का नंबर आता है.

जब आपके उपयोगकर्ता शब्दों में टाइप करते हैं, तब आपको उन्हें क्लासिफ़ाइड किए जाने वाले मॉडल में भेजने से पहले, इस शब्दावली से कोड में बदलना होगा.

आइए, उस कोड के बारे में जानें. शब्दावली लोड करके शुरू करें.

  1. डिक्शनरी को सेव करने के लिए, क्लास लेवल का वैरिएबल तय करें:
var words_dictionary = [String : Int]()
  1. इसके बाद, इस शब्दकोश में शब्दावली लोड करने के लिए, कक्षा में func बनाएं:
func loadVocab(){
    // This func will take the file at vocab.txt and load it into a has table
    // called words_dictionary. This will be used to tokenize the words before passing them
    // to the model trained by TensorFlow Lite Model Maker
    if let filePath = Bundle.main.path(forResource: "vocab", ofType: "txt") {
        do {
            let dictionary_contents = try String(contentsOfFile: filePath)
            let lines = dictionary_contents.split(whereSeparator: \.isNewline)
            for line in lines{
                let tokens = line.components(separatedBy: " ")
                let key = String(tokens[0])
                let value = Int(tokens[1])
                words_dictionary[key] = value
            }
        } catch {
            print("Error vocab could not be loaded")
        }
    } else {
        print("Error -- vocab file not found")

    }
}
  1. आप इसे viewDidLoad से कॉल करके चला सकते हैं:
override func viewDidLoad() {
    super.viewDidLoad()
    txtInput.delegate = self
    loadVocab()
}

10. किसी स्ट्रिंग को टोकन के क्रम में बदलना

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

आम तौर पर, एनएलपी मॉडल, तय सीक्वेंस की लंबाई स्वीकार करता है. ragged tensors का इस्तेमाल करके बनाए गए मॉडल के लिए, कुछ अपवाद हैं. हालांकि, ज़्यादातर मामलों में आपको यह समस्या ठीक दिखेगी. मॉडल बनाते समय, आपने इस अवधि की जानकारी दी थी. पक्का करें कि आपने iOS ऐप्लिकेशन में भी उसी लंबाई का इस्तेमाल किया हो.

आपने पहले जिस Colab for TensorFlow Lite Model Maker का इस्तेमाल किया था उसमें डिफ़ॉल्ट रूप से 20 का इस्तेमाल किया गया था. इसलिए, यहां भी इसे सेट अप करें:

let SEQUENCE_LENGTH = 20

यह func जोड़ें, जो स्ट्रिंग को लोअरकेस में बदल देगा और उसमें से विराम चिह्न हटा देगा:

func convert_sentence(sentence: String) -> [Int32]{
// This func will split a sentence into individual words, while stripping punctuation
// If the word is present in the dictionary it's value from the dictionary will be added to
// the sequence. Otherwise we'll continue

// Initialize the sequence to be all 0s, and the length to be determined
// by the const SEQUENCE_LENGTH. This should be the same length as the
// sequences that the model was trained for
  var sequence = [Int32](repeating: 0, count: SEQUENCE_LENGTH)
  var words : [String] = []
  sentence.enumerateSubstrings(
    in: sentence.startIndex..<sentence.endIndex,options: .byWords) {
            (substring, _, _, _) -> () in words.append(substring!) }
  var thisWord = 0
  for word in words{
    if (thisWord>=SEQUENCE_LENGTH){
      break
    }
    let seekword = word.lowercased()
    if let val = words_dictionary[seekword]{
      sequence[thisWord]=Int32(val)
      thisWord = thisWord + 1
    }
  }
  return sequence
}

ध्यान दें कि क्रम Int32 होगा. इसे जान-बूझकर चुना गया है, क्योंकि TensorFlow Lite में वैल्यू पास करने के लिए, आपको कम लेवल की मेमोरी का इस्तेमाल करना होगा. साथ ही, TensorFlow Lite, स्ट्रिंग सीक्वेंस में मौजूद पूर्णांकों को 32-बिट पूर्णांक के तौर पर इस्तेमाल करता है. इससे, मॉडल में स्ट्रिंग पास करने के दौरान आपका काम थोड़ा आसान हो जाएगा.

11. कैटगरी तय करना

किसी वाक्य को कैटगरी में बांटने के लिए, उसे पहले वाक्य में मौजूद शब्दों के आधार पर, टोकन के क्रम में बदलना होगा. यह नया खाता, नौवें चरण में बनाया गया होगा.

अब आपको वाक्य को मॉडल में डालना होगा, ताकि मॉडल उस वाक्य के बारे में अनुमान लगा सके और नतीजों को पार्स कर सके.

इसके लिए, TensorFlow Lite इंटरप्रेटर का इस्तेमाल किया जाएगा. आपको इसे इंपोर्ट करना होगा:

import TensorFlowLite

func से शुरू करें, जो आपके क्रम को लेता है, जो Int32 टाइप का कलेक्शन था:

func classify(sequence: [Int32]){
  // Model Path is the location of the model in the bundle
  let modelPath = Bundle.main.path(forResource: "model", ofType: "tflite")
  var interpreter: Interpreter
  do{
    interpreter = try Interpreter(modelPath: modelPath!)
  } catch _{
    print("Error loading model!")
    return
  }

ऐसा करने पर, बंडल से मॉडल फ़ाइल लोड हो जाएगी और इसके साथ किसी अनुवादक को शुरू किया जाएगा.

अगले चरण में, क्रम में सेव की गई मेमोरी को myData, नाम के बफ़र में कॉपी किया जाएगा, ताकि इसे टेंसर में पास किया जा सके. TensorFlow Lite पॉड और अनुवादक मोड को लागू करने पर, आपको Tensor टाइप का ऐक्सेस मिला.

कोड को इस तरह शुरू करें (अभी भी classify func में है):

let tSequence = Array(sequence)
let myData = Data(copyingBufferOf: tSequence.map { Int32($0) })
let outputTensor: Tensor

अगर आपको copyingBufferOf पर गड़बड़ी का कोई मैसेज मिलता है, तो चिंता न करें. इसे बाद में एक एक्सटेंशन के तौर पर लागू किया जाएगा.

अब इंटरप्रेटर पर टेंसर को असाइन करने का समय आ गया है. इसके बाद, अभी-अभी बनाए गए डेटा बफ़र को इनपुट टेंसर में कॉपी करें और फिर अनुमान लगाने के लिए इंटरप्रेटर को चालू करें:

do {
  // Allocate memory for the model's input `Tensor`s.
  try interpreter.allocateTensors()

  // Copy the data to the input `Tensor`.
  try interpreter.copy(myData, toInputAt: 0)

  // Run inference by invoking the `Interpreter`.
  try interpreter.invoke()

अनुरोध पूरा होने के बाद, नतीजे देखने के लिए इंटरप्रेटर का आउटपुट देखा जा सकता है.

ये रॉ वैल्यू (हर न्यूरॉन के लिए 4 बाइट) होंगी. इसके बाद, आपको इन्हें पढ़कर बदलना होगा. इस खास मॉडल में दो आउटपुट न्यूरॉन हैं, इसलिए आपको आठ बाइट में पढ़ने की ज़रूरत होगी. इन्हें पार्स करने के लिए, फ़्लोट32 में बदल दिया जाएगा. आपको लो लेवल की मेमोरी की समस्या आ रही है, इसलिए unsafeData.

// Get the output `Tensor` to process the inference results.
outputTensor = try interpreter.output(at: 0)
// Turn the output tensor into an array. This will have 2 values
// Value at index 0 is the probability of negative sentiment
// Value at index 1 is the probability of positive sentiment
let resultsArray = outputTensor.data
let results: [Float32] = [Float32](unsafeData: resultsArray) ?? []

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

let positiveSpamValue = results[1]
var outputString = ""
if(positiveSpamValue>0.8){
    outputString = "Message not sent. Spam detected with probability: " + String(positiveSpamValue)
} else {
    outputString = "Message sent!"
}
txtOutput.text = outputString

आपकी सुविधा के लिए, यहां पूरा तरीका दिया गया है:

func classify(sequence: [Int32]){
  // Model Path is the location of the model in the bundle
  let modelPath = Bundle.main.path(forResource: "model", ofType: "tflite")
  var interpreter: Interpreter
  do{
    interpreter = try Interpreter(modelPath: modelPath!)
    } catch _{
      print("Error loading model!")
      Return
  }
  
  let tSequence = Array(sequence)
  let myData = Data(copyingBufferOf: tSequence.map { Int32($0) })
  let outputTensor: Tensor
  do {
    // Allocate memory for the model's input `Tensor`s.
    try interpreter.allocateTensors()

    // Copy the data to the input `Tensor`.
    try interpreter.copy(myData, toInputAt: 0)

    // Run inference by invoking the `Interpreter`.
    try interpreter.invoke()

    // Get the output `Tensor` to process the inference results.
    outputTensor = try interpreter.output(at: 0)
    // Turn the output tensor into an array. This will have 2 values
    // Value at index 0 is the probability of negative sentiment
    // Value at index 1 is the probability of positive sentiment
    let resultsArray = outputTensor.data
    let results: [Float32] = [Float32](unsafeData: resultsArray) ?? []

    let positiveSpamValue = results[1]
    var outputString = ""
    if(positiveSpamValue>0.8){
      outputString = "Message not sent. Spam detected with probability: " + 
                      String(positiveSpamValue)
    } else {
      outputString = "Message sent!"
    }
    txtOutput.text = outputString

  } catch let error {
    print("Failed to invoke the interpreter with error: \(error.localizedDescription)")
  }
}

12. Swift एक्सटेंशन जोड़ना

ऊपर दिए गए कोड ने डेटा टाइप के एक्सटेंशन का इस्तेमाल किया है, ताकि आप Int32 कलेक्शन के रॉ बिट को Data में कॉपी कर सकें. उस एक्सटेंशन का कोड यहां दिया गया है:

extension Data {
  /// Creates a new buffer by copying the buffer pointer of the given array.
  ///
  /// - Warning: The given array's element type `T` must be trivial in that it can be copied bit
  ///     for bit with no indirection or reference-counting operations; otherwise, reinterpreting
  ///     data from the resulting buffer has undefined behavior.
  /// - Parameter array: An array with elements of type `T`.
  init<T>(copyingBufferOf array: [T]) {
    self = array.withUnsafeBufferPointer(Data.init)
  }
}

लो लेवल मेमोरी का इस्तेमाल करते समय, "असुरक्षित" डेटा का इस्तेमाल किया जाता है. साथ ही, ऊपर दिए गए कोड में आपको असुरक्षित डेटा के कलेक्शन को शुरू करना होता है. इस एक्सटेंशन की मदद से, ये काम किए जा सकते हैं:

extension Array {
  /// Creates a new array from the bytes of the given unsafe data.
  ///
  /// - Warning: The array's `Element` type must be trivial in that it can be copied bit for bit
  ///     with no indirection or reference-counting operations; otherwise, copying the raw bytes in
  ///     the `unsafeData`'s buffer to a new array returns an unsafe copy.
  /// - Note: Returns `nil` if `unsafeData.count` is not a multiple of
  ///     `MemoryLayout<Element>.stride`.
  /// - Parameter unsafeData: The data containing the bytes to turn into an array.
  init?(unsafeData: Data) {
    guard unsafeData.count % MemoryLayout<Element>.stride == 0 else { return nil }
    #if swift(>=5.0)
    self = unsafeData.withUnsafeBytes { .init($0.bindMemory(to: Element.self)) }
    #else
    self = unsafeData.withUnsafeBytes {
      .init(UnsafeBufferPointer<Element>(
        start: $0,
        count: unsafeData.count / MemoryLayout<Element>.stride
      ))
    }
    #endif  // swift(>=5.0)
  }
}

13. iOS ऐप्लिकेशन चलाना

ऐप्लिकेशन को चलाएं और उसकी जांच करें.

अगर सब कुछ ठीक रहा, तो आपको अपने डिवाइस पर ऐप्लिकेशन ऐसा दिखेगा:

74cbd28d9b1592ed.png

"ऑनलाइन ट्रेडिंग सीखने के लिए मेरी किताब खरीदें!" मैसेज भेजने पर, ऐप्लिकेशन .99% की संभावना के साथ स्पैम का पता चलने की चेतावनी भेजता है!

14. बधाई हो!

अब आपने एक बहुत आसान ऐप्लिकेशन बना लिया है. यह स्पैम टिप्पणी के टेक्स्ट को फ़िल्टर करने के लिए एक ऐसे मॉडल का इस्तेमाल करता है जिसे ब्लॉग को स्पैम भेजने के लिए इस्तेमाल किए गए डेटा के हिसाब से ट्रेनिंग दी गई थी.

डेवलपर के लाइफ़साइकल के अगले चरण में, यह पता लगाना होता है कि अपनी कम्यूनिटी में मिले डेटा के आधार पर, मॉडल को कस्टमाइज़ करने के लिए क्या करना होगा. अगली पाथवे गतिविधि में, आपको यह तरीका पता चलेगा.