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

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

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

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

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

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

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

आपको इनकी ज़रूरत होगी

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

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

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

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

इसे TextClassificationOnMobile->Android पाथ में देखा जा सकता है.

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

इसके खुलने के बाद, आप चरण 2 पर जाने के लिए तैयार हैं.

3. मॉडल फ़ाइल और मेटाडेटा आयात करें

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

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

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

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

d7c3e9f21035fc15.png

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

2137f956a1ba4ef0.png

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

ae858835e1a90445.png

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

e61aaa3b73c5ab68.png

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

  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 व्यू के प्रोजेक्ट एक्सप्लोरर में, इसे अपने Gredle स्क्रिप्ट सेक्शन में ढूंढें. सही जवाब को .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. आपको स्क्रीन के बीच में एक डायलॉग दिखेगा, जिसमें आपको पैकेज का नाम डालने के लिए कहा जाएगा. इसे मौजूदा पैकेज के नाम के आखिर में जोड़ें. (यहां इसे helpers कहा जाता है.)

3b9f1f822f99b371.png

  1. इसके बाद, प्रोजेक्ट एक्सप्लोरर में helpers फ़ोल्डर पर राइट क्लिक करें.
  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 टाइप, टेक्स्ट टास्क लाइब्रेरी का हिस्सा है. यह आपकी स्ट्रिंग को टोकन में बदलने, सही क्रम लंबाई का इस्तेमाल करके, उसे मॉडल में पास करने, और नतीजों को पार्स करने में आपकी मदद करता है.

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

कैटगरी तय करने का तरीका, कैटगरी तय करने का होता है. इसमें उस स्ट्रिंग को पास किया जाता है और इससे 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 उन्हें अंग्रेज़ी वर्णमाला के क्रम में लगाता है, इसलिए 'गलत' आइटम 0 होगा और सही का मान आइटम 1 होगा.)

  1. वैल्यू True होने की संभावना का स्कोर पाने के लिए, [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 को इंस्टॉल करने के बाद, TextClassify ऐप्लिकेशन के लिए .xcproject वाली डायरेक्ट्री में Podfile नाम की फ़ाइल बनाएं. इस फ़ाइल की सामग्री इस तरह से दिखनी चाहिए:
target 'TextClassificationStep2' do
  use_frameworks!

  # Pods for NLPClassifier
    pod 'TensorFlowLiteSwift'

end

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

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

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

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

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

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

1ee9eaa00ee79859.png

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

b63502b23911fd42.png

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

20b7cb603d49b457.png

9. वोकैब लोड करें

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

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

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

आइए, उस कोड को एक्सप्लोर करते हैं. शब्दावली लोड करके शुरू करें.

  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 ऐप्लिकेशन में, एक ही अवधि का इस्तेमाल किया हो.

आपने पहले TensorFlow Lite Model Maker के लिए, Colab में 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 टाइप का ऐक्सेस मिला.

कोड को इस तरह से शुरू करें (अब भी 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()

शुरू करने के बाद, नतीजे देखने के लिए अनुवादक का आउटपुट देखा जा सकता है.

ये रॉ वैल्यू (हर न्यूरॉन चार बाइट) होंगी, जिन्हें आपको पढ़कर उन्हें बदलना होगा. इस खास मॉडल में दो आउटपुट न्यूरॉन हैं, इसलिए आपको आठ बाइट में पढ़ने की ज़रूरत होगी. इन्हें पार्स करने के लिए, फ़्लोट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. बधाई हो!

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

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