স্প্যাম ফিল্টারিং মেশিন লার্নিং মডেল ব্যবহার করতে আপনার অ্যাপ আপডেট করুন

1. আপনি শুরু করার আগে

এই কোডল্যাবে, আপনি মোবাইল টেক্সট ক্লাসিফিকেশন কোডল্যাবগুলির সাথে শুরু করুন পূর্বে তৈরি করা অ্যাপটি আপডেট করবেন।

পূর্বশর্ত

  • এই কোডল্যাবটি মেশিন লার্নিং-এ নতুন অভিজ্ঞ ডেভেলপারদের জন্য ডিজাইন করা হয়েছে।
  • কোডল্যাব একটি ক্রমিক পথের অংশ। আপনি যদি ইতিমধ্যে একটি মৌলিক মেসেজিং স্টাইল অ্যাপ তৈরি বা মন্তব্য স্প্যাম মেশিন লার্নিং মডেল তৈরি না করে থাকেন, তাহলে দয়া করে থামুন এবং এখনই করুন৷

আপনি কি করবেন [নির্মাণ বা শিখবেন]

  • আপনি শিখবেন কীভাবে আপনার অ্যাপে আপনার কাস্টম মডেলকে একীভূত করবেন, আগের ধাপে তৈরি।

আপনি কি প্রয়োজন হবে

  • অ্যান্ড্রয়েড স্টুডিও, বা আইওএসের জন্য কোকোপডস

2. বিদ্যমান অ্যান্ড্রয়েড অ্যাপ খুলুন

আপনি কোডলাব 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. খোলে মেনুতে, আপনি (ম্যাকে) ফাইন্ডারে প্রকাশ দেখতে পাবেন। এটি নির্বাচন করুন। (উইন্ডোজে এটা বলবে Show in Explorer , উবুন্টুতে বলবে Show in Files ।)

e61aaa3b73c5ab68.png

ফাইলের অবস্থান দেখানোর জন্য ফাইন্ডার চালু হবে (উইন্ডোজে ফাইল এক্সপ্লোরার , লিনাক্সে ফাইল )।

  1. এই ডিরেক্টরিতে labels.txt , model.tflite এবং vocab ফাইলগুলি কপি করুন৷

14f382cc19552a56.png

  1. অ্যান্ড্রয়েড স্টুডিওতে ফিরে যান, এবং আপনি সেগুলি আপনার সম্পদ ফোল্ডারে উপলব্ধ দেখতে পাবেন।

150ed2a1d2f7a10d.png

4. TensorFlow Lite ব্যবহার করতে আপনার build.gradle আপডেট করুন

TensorFlow Lite ব্যবহার করতে, এবং TensorFlow Lite টাস্ক লাইব্রেরি যা এটি সমর্থন করে, আপনাকে আপনার build.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. New > Java Class নির্বাচন করুন এবং এটিকে 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;
    }

}

এই ক্লাসটি টেনসরফ্লো লাইট ইন্টারপ্রেটারকে একটি মোড়ক প্রদান করবে, মডেলটি লোড করবে এবং আপনার অ্যাপ এবং মডেলের মধ্যে ডেটা আদান-প্রদান পরিচালনার জটিলতাকে বিমূর্ত করবে।

load() পদ্ধতিতে, এটি মডেল পাথ থেকে একটি নতুন NLClassifier টাইপ ইনস্ট্যান্ট করবে। মডেল পাথ হল মডেলের নাম, model.tfliteNLClassifier টাইপ হল টেক্সট টাস্ক লাইব্রেরির অংশ, এবং এটি আপনার স্ট্রিংকে টোকেনে রূপান্তর করে, সঠিক ক্রম দৈর্ঘ্য ব্যবহার করে, এটিকে মডেলে পাস করে এবং ফলাফল পার্স করে আপনাকে সাহায্য করে।

(এগুলি সম্পর্কে আরও বিশদ বিবরণের জন্য, একটি মন্তব্য স্প্যাম মেশিন লার্নিং মডেল তৈরি করুন পুনরায় দেখুন৷)

শ্রেণীবিভাগটি শ্রেণীবদ্ধ পদ্ধতিতে সঞ্চালিত হয়, যেখানে আপনি এটি একটি স্ট্রিং পাস করেন এবং এটি একটি List প্রদান করবে। যখন আপনি একটি স্ট্রিং স্প্যাম কিনা তা নির্ধারণ করতে চান এমন সামগ্রীকে শ্রেণিবদ্ধ করতে মেশিন লার্নিং মডেলগুলি ব্যবহার করার সময়, নির্ধারিত সম্ভাব্যতা সহ সমস্ত উত্তর ফেরত দেওয়া সাধারণ৷ উদাহরণস্বরূপ, যদি আপনি এটিকে স্প্যামের মতো একটি বার্তা পাঠান, তাহলে আপনি 2টি উত্তরের একটি তালিকা ফিরে পাবেন; একটি সম্ভাব্যতা সহ যে এটি স্প্যাম, এবং একটি সম্ভাব্যতা সহ যে এটি নয়৷ স্প্যাম/স্প্যাম নয় বিভাগগুলি, তাই প্রত্যাবর্তিত 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)

শুধুমাত্র 2টি বিভাগ আছে, False এবং True

. (টেনসরফ্লো এগুলিকে বর্ণানুক্রমিকভাবে সাজায়, তাই মিথ্যা হবে আইটেম 0, এবং সত্য হবে আইটেম 1।)

  1. মানটি True হওয়ার সম্ভাবনার জন্য স্কোর পেতে, আপনি ফলাফলগুলি দেখতে পারেন[1].স্কোর এইরকম:
    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 লাইট মডেল ব্যবহার করতে আপনার iOS অ্যাপ আপডেট করুন

আপনি কোডলাব 1 অনুসরণ করে বা এই রেপো ক্লোন করে এবং TextClassificationStep1 থেকে অ্যাপটি লোড করে এর জন্য কোড পেতে পারেন। আপনি TextClassificationOnMobile->iOS পাথে এটি খুঁজে পেতে পারেন।

সমাপ্ত কোডটি আপনার জন্য TextClassificationStep2 হিসাবেও উপলব্ধ।

বিল্ড একটি কমেন্ট স্প্যাম মেশিন লার্নিং মডেল কোডল্যাবে, আপনি একটি খুব সাধারণ অ্যাপ তৈরি করেছেন যা ব্যবহারকারীকে একটি UITextView এ একটি বার্তা টাইপ করতে দেয় এবং এটি কোনো ফিল্টারিং ছাড়াই একটি আউটপুটে পাস করে।

পাঠানোর আগে পাঠ্যে মন্তব্য স্প্যাম শনাক্ত করতে এখন আপনি একটি TensorFlow Lite মডেল ব্যবহার করতে সেই অ্যাপটিকে আপডেট করবেন। শুধুমাত্র একটি আউটপুট লেবেলে পাঠ্য রেন্ডার করে এই অ্যাপে পাঠানোর অনুকরণ করুন (কিন্তু একটি বাস্তব অ্যাপে একটি বুলেটিন বোর্ড, একটি চ্যাট বা অনুরূপ কিছু থাকতে পারে)।

শুরু করতে, আপনাকে ধাপ 1 থেকে অ্যাপটির প্রয়োজন হবে, যা আপনি রেপো থেকে ক্লোন করতে পারেন।

TensorFlow Lite অন্তর্ভুক্ত করতে, আপনি CocoaPods ব্যবহার করবেন। আপনি যদি এইগুলি ইতিমধ্যে ইনস্টল না করে থাকেন, তাহলে আপনি https://cocoapods.org/- এ নির্দেশাবলীর সাহায্যে তা করতে পারেন।

  1. আপনার একবার CocoaPods ইনস্টল হয়ে গেলে, TextClassification অ্যাপের জন্য .xcproject এর মতো একই ডিরেক্টরিতে Podfile নামের একটি ফাইল তৈরি করুন। এই ফাইলের বিষয়বস্তু এই মত হওয়া উচিত:
target 'TextClassificationStep2' do
  use_frameworks!

  # Pods for NLPClassifier
    pod 'TensorFlowLiteSwift'

end

আপনার অ্যাপের নাম "TextClassificationStep2" এর পরিবর্তে প্রথম লাইনে হওয়া উচিত।

টার্মিনাল ব্যবহার করে, সেই ডিরেক্টরিতে নেভিগেট করুন এবং pod install চালান। এটি সফল হলে, আপনার কাছে পডস নামে একটি নতুন ডিরেক্টরি থাকবে এবং আপনার জন্য একটি নতুন .xcworkspace ফাইল তৈরি করা হবে৷ আপনি ভবিষ্যতে এটি .xcproject এর পরিবর্তে ব্যবহার করবেন।

যদি এটি ব্যর্থ হয়, অনুগ্রহ করে নিশ্চিত করুন যে আপনার কাছে একই ডিরেক্টরিতে পডফাইল আছে যেখানে .xcproject ছিল। ভুল ডিরেক্টরির পডফাইল, বা ভুল টার্গেট নাম, সাধারণত প্রধান অপরাধী!

8. মডেল এবং Vocab ফাইল যোগ করুন

আপনি যখন TensorFlow Lite মডেল মেকার দিয়ে মডেল তৈরি করেছিলেন, তখন আপনি মডেলটি ( model.tflite হিসাবে) এবং ভোকাব ( vocab.txt হিসাবে) আউটপুট করতে সক্ষম হয়েছিলেন।

  1. ফাইন্ডার থেকে আপনার প্রোজেক্ট উইন্ডোতে টেনে এনে সেগুলোকে আপনার প্রোজেক্টে যোগ করুন। লক্ষ্য যোগ করুন চেক করা হয়েছে নিশ্চিত করুন:

1ee9ea00ee79859.png

আপনার কাজ হয়ে গেলে, আপনার প্রকল্পে সেগুলি দেখতে হবে:

b63502b23911fd42.png

  1. আপনার প্রোজেক্ট নির্বাচন করে (উপরের স্ক্রিনশটে, এটি নীল আইকন TextClassificationStep2 ), এবং বিল্ড ফেজ ট্যাবটি দেখে বান্ডিলে সেগুলি যোগ করা হয়েছে কিনা তা দুবার চেক করুন (যাতে সেগুলি একটি ডিভাইসে স্থাপন করা হয়)

20b7cb603d49b457.png

9. Vocab লোড করুন

NLP শ্রেণীবিভাগ করার সময়, মডেলটিকে ভেক্টরে এনকোড করা শব্দ দিয়ে প্রশিক্ষিত করা হয়। মডেলটি নাম এবং মানগুলির একটি নির্দিষ্ট সেট সহ শব্দগুলিকে এনকোড করে যা মডেল ট্রেন হিসাবে শেখা হয়। অনুগ্রহ করে মনে রাখবেন যে বেশিরভাগ মডেলের বিভিন্ন শব্দভান্ডার থাকবে, এবং প্রশিক্ষণের সময় তৈরি করা আপনার মডেলের জন্য ভোকাব ব্যবহার করা আপনার জন্য গুরুত্বপূর্ণ। এই vocab.txt ফাইলটি আপনি এইমাত্র আপনার অ্যাপে যোগ করেছেন।

আপনি এনকোডিং দেখতে Xcode ফাইল খুলতে পারেন. "গান" এর মত শব্দগুলি 6 এবং "ভালোবাসা" 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. একটি স্ট্রিংকে টোকেনগুলির একটি অনুক্রমে পরিণত করুন

আপনার ব্যবহারকারীরা একটি বাক্য হিসাবে শব্দ টাইপ করবে যা একটি স্ট্রিং হয়ে যাবে। বাক্যের প্রতিটি শব্দ, অভিধানে উপস্থিত থাকলে, ভোকাবে সংজ্ঞায়িত শব্দের মূল মানটিতে এনকোড করা হবে।

একটি NLP মডেল সাধারণত একটি নির্দিষ্ট ক্রম দৈর্ঘ্য গ্রহণ করে। 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. শ্রেণীবিভাগ করুন

একটি বাক্যকে শ্রেণীবদ্ধ করার জন্য, এটিকে প্রথমে বাক্যের শব্দগুলির উপর ভিত্তি করে টোকেনগুলির একটি ক্রমে রূপান্তর করতে হবে। এটি ধাপ 9 এ করা হবে।

আপনি এখন বাক্যটি নেবেন এবং মডেলটিতে প্রেরণ করবেন, মডেলটিকে বাক্যটির উপর অনুমান করতে হবে এবং ফলাফলগুলি পার্স করতে হবে।

এটি 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, যাতে এটি একটি টেনসরে প্রেরণ করা যায়। টেনসরফ্লো লাইট পড, সেইসাথে দোভাষী প্রয়োগ করার সময়, আপনি একটি টেনসর প্রকারে অ্যাক্সেস পেয়েছেন।

কোডটি এভাবে শুরু করুন (এখনও শ্রেণীবদ্ধ 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 বাইট) যা আপনাকে পড়তে এবং রূপান্তর করতে হবে। যেহেতু এই বিশেষ মডেলটিতে 2টি আউটপুট নিউরন রয়েছে, তাই আপনাকে 8 বাইটে পড়তে হবে যা পার্সিংয়ের জন্য Float32-এ রূপান্তরিত হবে। আপনি নিম্ন স্তরের মেমরি নিয়ে কাজ করছেন, তাই 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) ?? []

এখন স্প্যামের গুণমান নির্ধারণ করতে ডেটা পার্স করা তুলনামূলকভাবে সহজ৷ মডেলটিতে 2টি আউটপুট রয়েছে, প্রথমটি সম্ভাব্যতা সহ যে বার্তাটি স্প্যাম নয়, দ্বিতীয়টি সম্ভাব্যতা সহ। সুতরাং আপনি স্প্যাম মান খুঁজে পেতে 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. সুইফট এক্সটেনশন যোগ করুন

উপরের কোডটি ডেটা টাইপের একটি এক্সটেনশন ব্যবহার করেছে যাতে আপনি একটি 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. অভিনন্দন!

আপনি এখন একটি খুব সাধারণ অ্যাপ তৈরি করেছেন যা স্প্যাম ব্লগে ব্যবহৃত ডেটার উপর প্রশিক্ষিত মডেল ব্যবহার করে মন্তব্য স্প্যামের জন্য পাঠ্য ফিল্টার করে৷

সাধারণ বিকাশকারী জীবনচক্রের পরবর্তী ধাপ হল আপনার নিজের সম্প্রদায়ে পাওয়া ডেটার উপর ভিত্তি করে মডেলটি কাস্টমাইজ করতে কী লাগবে তা অন্বেষণ করা। আপনি পরবর্তী পাথওয়ে কার্যকলাপে এটি কিভাবে করতে হবে তা দেখতে পাবেন।