<jupyter_start><jupyter_text>বাংলা সেন্টিমেন্ট অ্যানালাইসিস, টেন্সর-ফ্লো হাব দিয়েএখনো ড্রাফট পর্যায়ে আছে  আমরা প্রায় বইয়ের শেষ পর্যায়ে চলে এসেছি। এতক্ষণ আমরা যা শিখেছি - সবগুলোর কিছু কিছু অংশ নিয়ে এই শেষ টিউটোরিয়াল। আগের সেন্টিমেন্ট অ্যানালাইসিস এ আমরা যে ধরনের সাধারণ লাইব্রেরি ব্যবহার করেছি সেগুলোকে কিভাবে প্রি-ট্রেইনড মডেল, ট্রান্সফার লার্নিং এই জিনিসগুলোকে ব্যবহার করে আরো উন্নত করা যায় সেটা নিয়ে আলাপ করছি এখানে। মাঝখান দিয়ে আমরা টেন্সর-ফ্লো সার্ভিং এবং এপিআই নিয়ে কাজ করেছি। এর পাশে আমরা টেন্সর-ফ্লো হাব যেখানে মডেলগুলোকে ট্রান্সফার লার্নিং দিয়ে “সেভড-মডেল” করে রাখা যায় সেই ফরম্যাটগুলো নিয়ে আলাপ করেছি। এদিকে টেন্সর-ফ্লো হাব যেখানে আমাদের প্রি-ট্রেইনড মডেলগুলোকে মডিউল হিসেবে রেখেছি যাকে বিভিন্ন এপিআই দিয়ে কানেক্ট করা যায়। আজকের গল্পের বেশিরভাগ হচ্ছে এই টেন্সর-ফ্লো হাব নিয়ে।    আমাদের আজকের কাজ১. ওয়ার্ড২ভেক প্রি-ট্রেইনড এমবেডিং ডাউনলোড করে নেব। ২.  ট্রেনিং এর জন্য দুটো লেবেলড ডেটাসেট ডাউনলোড করে নেই। একটা পজিটিভ আরেকটা নেগেটিভ সেন্টিমেন্টের ফাইল। দেখে নেই ভিতরে কি আছে?৩. টেন্সর ফ্লো হাব থেকে আগে থেকে তৈরি করা ওয়ার্ড এমবেডিং কনভার্টার/এক্সপোর্টার স্ক্রিপ্ট নামাবো যেটা ১. এ ডাউনলোড করা ওয়ার্ড এমবেডিংগুলোকে টেন্সর-ফ্লো হাব টেক্সট এমবেডিং মডিউলে এক্সপোর্ট করে দেবে। ৪. ওয়ার্ড২ভেক প্রি-ট্রেইনড এমবেডিং ফাইল এবং ওয়ার্ড এমবেডিং কনভার্টার/এক্সপোর্টার স্ক্রিপ্ট দুটো একই ডাইরেক্টরিতে থাকবে। আমাদের ওয়ার্ড এমবেডিং এর .txt অথবা .vec (বিশেষ করে ফাস্টটেক্সট) ফাইল থেকে  এক্সপোর্টার স্ক্রিপ্ট এমবেডিংগুলোর ভেক্টর পড়ে সেটাকে এক্সপোর্ট করবো  “সেভড-মডেলে”। ৫.  টেন্সর-ফ্লো হাব এই  “সেভড-মডেল”কে লোড করবে মডিউল হিসেবে যা আমাদেরকে মডেলকে সেন্টিমেন্ট অ্যানালাইসিস করবে। ৬. একটা সিকোয়েন্সিয়াল মডেল তৈরি  করবো, সেখানে ডেটাসেট বড় হওয়ায় একটা জেনারেটর ফাংশন ব্যবহার করে সেটার দৈবচয়নের ভিত্তিতে শাফলিং এবং দরকারি  ব্যাচিং করবো। এখানে ব্যবহার করবো টেন্সর ফ্লো ডেটাসেটের tf.data.Dataset.from_generator মেথড। এটা ট্রেনিং এর জন্য দরকার।৭. ট্রেনিং করে মডেল ‘সেভ’ করবো। এখানে যেকোন লেয়ারের মতো model.add দিয়ে আমাদের টেক্সট এমবেডিং মডিউলকে যোগ করা যায় এই ছোট সিকোয়েন্সিয়াল মডেলে। ৮. সবশেষে টেস্টিং। কয়েকটা বাক্যকে প্রেডিক্ট মেথডে পাঠালে সেটার দুটো ক্লাস (পজিটিভ/নেগেটিভ) আমাদেরকে জানিয়ে দেবে।  দরকারি লাইব্রেরিগুলো লোড অথবা ইনস্টল করে নেই<jupyter_code>!pip install -q tensorflow-gpu==2.0.0-beta1
# !pip install -q tensorflow-gpu==1.15
import tensorflow as tf
import tensorflow_hub as hub
import numpy as np
import os
from sklearn.metrics import classification_report
from gensim.models import Word2Vec

# দেখি কি কি আসলে আছে? 
print("Version: ", tf.__version__)
print("Eager mode: ", tf.executing_eagerly())
print("Hub version: ", hub.__version__)
print("GPU is", "available" if tf.test.is_gpu_available() else "NOT AVAILABLE")
tf.__version__
# বাড়তি ওয়ার্নিং ফেলে দিচ্ছি, আপনাদের কাজের সময় লাগবে না 
import warnings
warnings.filterwarnings("ignore")<jupyter_output><empty_output><jupyter_text>এই সেন্টিমেন্ট অ্যানালাইসিসে কেরাস লেয়ারে “সেভড-মডেল” ব্যবহার করব যাতে প্রি-ট্রেইনড মডেলগুলোকে ব্যবহার করা যায়। যেগুলোতে আগে থেকে এমবেডিংগুলো বানানো আছে। আমাদের টেন্সর-ফ্লো হাব (tensorflow_hub) লাইব্রেরিটা হাব-কেরাস (hub.KerasLayer) ক্লাস দিচ্ছে যা একটা “ইউআরএল” অথবা ফাইল সিস্টেম থেকে “সেভড-মডেলে”র কম্পিউটেশন এবং প্রি-ট্রেইনড ওয়েট বের করে নিয়ে আসবে। এখানে আমরা টেন্সর-ফ্লো ২ এর “সেভড-মডেল”কে পুনরায় ব্যবহার করবো লো-লেভেল hub.load() এপিআই এবং hub.KerasLayer এর wrapper দিয়ে।আমাদের বাংলা ভাষার জন্য কিছু প্রি-ট্রেইনড ওয়ার্ড এমবেডিং ব্যবহার করবো যাতে ব্যাপারটা সহজ হয়। এর আগেও আমরা প্রি-ট্রেইনড ওয়ার্ড এমবেডিং ব্যবহার করার জন্য ওয়ার্ড২ভেক এবং ফাস্টটেক্সট ব্যবহার করেছি। আপনারা তো জানেন, ফেইসবুক ফাস্টটেক্সটে বাংলাসহ ১৫৭টা ভাষার প্রি-ট্রেইনড ওয়ার্ড ভেক্টর ছেড়েছে বেশ কিছুদিন হলো। তবে, ওয়ার্ড২ভেক অতোটা খারাপ নয়। এই মডেলেও আপনারা ওয়ার্ড২ভেকের জায়গায় ফাস্টটেক্সট ব্যবহার করে দেখতে পারেন।আমরা ইচ্ছা করলে 'বার্ট' (BERT) অথবা 'ফ্লেয়ার' ব্যবহার করতে পারতাম, তবে এই ফ্রেমওয়ার্কগুলো বুঝলে বাকিগুলো কাজ করা সহজ হবে।<jupyter_code>hub_url = "https://tfhub.dev/google/tf2-preview/nnlm-en-dim128/1"
embed = hub.KerasLayer(hub_url)
embeddings = embed(["A long sentence.", "single-word", "http://example.com"])
print(embeddings.shape, embeddings.dtype)<jupyter_output>(3, 128) <dtype: 'float32'><jupyter_text>এখানে সাধারণ কেরাস লেয়ার দিয়ে একটা টেক্সট ক্লাসিফায়ার বানানো সমস্যা নয়।<jupyter_code>model = tf.keras.Sequential([
    embed,
    tf.keras.layers.Dense(16, activation="relu"),
    tf.keras.layers.Dense(1, activation="sigmoid"),
])<jupyter_output><empty_output><jupyter_text>ওয়ার্ড২ভেক ওয়ার্ড এমবেডিং ডাউনলোড চেষ্টা করছি এতো বড় ফাইল কোথাও হোস্ট করতে। যেহেতু ফাইলটা ২.৫ গিগাবাইটের মতো, এটাকে ভাগ করে নিয়েছি দুটো অংশে। কম্প্রেসড হিসেবে প্রায় ১ গিগাবাইট। দুটো ফাইলকে ডাউনলোড করে যোগ করে নিয়েছি।<jupyter_code>!wget https://bitbucket.org/r_hassan/datasets/raw/9caa4f67c34540e601cbad4de68d4786271b782c/bn-wiki-word2vec-300.txt.tgz.aa
!wget https://bitbucket.org/r_hassan/datasets/raw/9caa4f67c34540e601cbad4de68d4786271b782c/bn-wiki-word2vec-300.txt.tgz.ab
# ফাইল কনক্যাটেনেট করে যোগ করে 'টার' থেকে এক্সট্র্যাক্ট 

!cat bn-wiki-word2vec-300.txt.tgz.* | tar xzf -
# প্রথম কয়েক লাইন দেখলেই বুঝবেন কি বলতে চাচ্ছি - ওয়ার্ড এমবেডিং ভেক্টর
# শুরুতে বাংলা শব্দটা, এরপরে ভেক্টর

!head -7 bn-wiki-word2vec-300.txt<jupyter_output>669605 300
এবং -0.93040687 0.60418844 0.6206399 0.15345214 -0.5920706 1.4105053 -0.19125229 1.9424365 -0.28456318 0.86637765 -0.34657523 0.008341969 0.91945136 0.33013958 -1.6456839 -1.6953105 1.9161752 1.1476667 0.17091753 0.3958588 1.0207202 -0.8163486 0.32261878 -0.30720857 -0.6554219 -1.7145324 -1.6113459 0.29473424 -0.8452265 0.18330733 1.047255 0.22511762 0.822286 0.16025306 0.66336554 1.0438149 0.6023638 -0.64874256 1.5032426 1.5895689 0.75842565 -1.2870961 0.079544045 0.3080709 0.32782224 -0.7009649 0.15249959 -1.027652 0.8451291 -0.32714248 0.42230263 -1.4003234 -0.59839815 -0.67217594 1.072765 0.2526819 0.16195725 -1.2569925 -0.5837513 -1.1979657 -0.6138971 0.79471904 -0.9409709 1.2761021 0.89106756 0.53292865 2.2675922 -0.13259064 0.15469204 1.3745763 -0.5177524 0.41830626 0.5299528 -0.40102947 -0.42628673 -1.0313057 0.55274475 -0.88331276 0.21075027 1.387416 0.5721329 0.35013482 -0.21881458 -2.7000587 -1.14341 1.7165354 1.2415577 -0.13076034 0.9847175 -1.4681516 0.35087734 [...]<jupyter_text>সেন্টিমেন্ট অ্যানালাইসিস এর ট্রেইিং ফাইলদুটো ফাইল, একটা নেগেটিভ আরেকটা পজিটিভ। bangla-sentiment.neg ফাইলে সব নেগেটিভ, সেদিক থেকে bangla-sentiment.pos ফাইলে সব পজিটিভ বাক্য। লেবেলিং করেছেন আমাদের মতো মানুষ। তবে ভালো ডেটাসেট খুঁজছি আমি। এমুহুর্তে এই ডেটাসেট দিয়ে সাহায্য করেছেন সোসিয়ান, বিশেষ করে তারেক আল মুনতাসির। সোশ্যাল মিডিয়াতে মানুষ কি লেখেন সেটার ওপর আমাদের কন্ট্রোল নেই। তাই এই ডেটাসেটে কি লেখা আছে সেটা নিয়ে আমরা মাথা ঘামাবো না। রিসার্চের জন্য ব্যবহার হিসেবে ধরে নিচ্ছি আমরা।<jupyter_code>!wget https://github.com/raqueeb/datasets/raw/master/bangla-sentiment.pos
!wget https://github.com/raqueeb/datasets/raw/master/bangla-sentiment.neg

# দেখি এই ফাইলটাতে কি আচ্ছে প্রথম ৫ লাইনে?

!head -5 bangla-sentiment.pos
# বাকি ফাইলটাতে?

!head -5 bangla-sentiment.neg
# কি কি ডাউনলোড করলাম?

!ls -al<jupyter_output>total 3395692
drwxr-xr-x 1 root root       4096 Nov 23 03:21 .
drwxr-xr-x 1 root root       4096 Nov 23 03:06 ..
-rw-r--r-- 1 root root     363162 Nov 23 03:21 bangla-sentiment.neg
-rw-r--r-- 1 root root     220062 Nov 23 03:21 bangla-sentiment.pos
-rw-r--r-- 1 root root 2496996336 Nov 14 09:58 bn-wiki-word2vec-300.txt
-rw-r--r-- 1 root root  492830720 Nov 23 03:20 bn-wiki-word2vec-300.txt.tgz.aa
-rw-r--r-- 1 root root  486748692 Nov 23 03:20 bn-wiki-word2vec-300.txt.tgz.ab
drwxr-xr-x 1 root root       4096 Nov 21 16:30 .config
drwxr-xr-x 1 root root       4096 Nov 21 16:30 sample_data<jupyter_text>দুটো ফাইলের মোট বাক্য কতো আছে?দুভাবে দেখতে পারি। সাধারণ পাইথন ফাইল অপারেশন।<jupyter_code>preprocessed_text_file_path = 'bangla-sentiment.pos'
lines_from_file = []
with open(preprocessed_text_file_path, encoding='utf8') as text_file:
    for line in text_file:
        lines_from_file.append(line)
# পজিটিভ ফাইলের লাইন সংখ্যা

len(lines_from_file)
preprocessed_text_file_path = 'bangla-sentiment.neg'
lines_from_file = []
with open(preprocessed_text_file_path, encoding='utf8') as text_file:
    for line in text_file:
        lines_from_file.append(line)
# নেগেটিভ ফাইলের লাইন সংখ্যা

len(lines_from_file)
# সব এক জায়গায় নিয়ে আসি

all_sentences = []
with open('bangla-sentiment.pos', encoding='utf8') as f:
    all_sentences.extend([(line.strip(), 'positive') for line in f])
        
with open('bangla-sentiment.neg', encoding='utf8') as f:
    all_sentences.extend([(line.strip(), 'negative') for line in f])
# all_sentences এর প্রথম পাঁচ লাইন

all_sentences[:5]
# কতগুলো পজিটিভ আর কতো নম্বর লাইন থেকে নেগেটিভ শুরু হয়েছে?

pos_count = 0
neg_count = 0
for sentence, label in all_sentences:
  if label =='positive':
      pos_count +=1
  else:
      neg_count +=1
print(pos_count)
print(neg_count)
# নেগেটিভ লাইন শুরুর প্রথম পাঁচ লাইনে কি আছে?

all_sentences[2040:2045]<jupyter_output><empty_output><jupyter_text>প্রিট্রেইনড এমবেডিং এক্সপোর্টার স্ক্রিপ্ট ডাউনলোড টেন্সর-ফ্লো এর একটা বড় সুবিধা হচ্ছে মডেলের মধ্যে লার্নিং ট্রান্সফার করা যায়। এই ক্লাস মডিউল (নিচে দেখুন) মডেলের গ্রাফের হার্ডডিস্কের সেভ করা একটা অংশ যাকে এক্সপোর্ট করা যায় আরেক জায়গায়।শুরুতেই বলেছিলাম আমরা টেন্সর-ফ্লো হাবের একটা প্রিট্রেইনড এমবেডিং এক্সপোর্টার স্ক্রিপ্ট ব্যবহার করবো - ওয়ার্ড এমবেডিং থেকে টেক্সট এমবেডিং মডিউল বের করতে সেটাকে পাঠিয়ে দেবো ক্লাসিফায়ার ট্রেইন করতে। ফাস্টটেক্সট দিয়ে আরেকটা উদাহরন (সেন্টিমেন্ট অ্যানালাইসিস নয়, টেক্সট ক্লাসিফিকেশন) দেয়া আছে নিচের লিঙ্কে। আমরা ফাস্টটেক্সট ব্যবহার করতে চাইলে শুধুমাত্র ফাস্টটেক্সট ভেক্টর ফাইলটা ব্যবহার করলেই হবে।আমাদের এক্সপোর্টার স্ক্রিপ্ট আছে https://github.com/tensorflow/hub/tree/master/examples/text_embeddings_v2, ডাউনলোড করে রাখি একই ডিরেক্টরিতে। একটা সেভড মডেলে কি থাকে? টেন্সর-ফ্লো এর দরকারী ডেটা সঙ্গে মডেলের ওয়েট এবং গ্রাফ যাতে মডেলটা আবার তৈরি করা যেতে পারে। এই সেভড মডেল থেকে নিয়ে আসবো ওয়ার্ড এমবেডিংগুলো। টেন্সর-ফ্লো হাবের কাজ হচ্ছে এই সেভড মডেলকে লোড করে মডিউল হিসেবে যাকে দরকার হবে [hub.KerasLayer](https://www.tensorflow.org/hub/api_docs/python/hub/KerasLayer) এ। সেকয়েন্সিয়াল লেয়ারে এই কেরাস লেয়ার ভালোই কাজ করছে।<jupyter_code>!wget https://raw.githubusercontent.com/tensorflow/hub/master/examples/text_embeddings_v2/export_v2.py
# !wget https://raw.githubusercontent.com/tensorflow/hub/master/examples/text_embeddings/export.py<jupyter_output>--2019-11-23 03:22:39--  https://raw.githubusercontent.com/tensorflow/hub/master/examples/text_embeddings_v2/export_v2.py
Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 172.16.17.32, 192.168.3.11, 172.16.31.10, ...
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|172.16.17.32|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 7603 (7.4K) [text/plain]
Saving to: ‘export_v2.py’


export_v2.py          0%[                    ]       0  --.-KB/s               
export_v2.py        100%[===================>]   7.42K  --.-KB/s    in 0s      

2019-11-23 03:22:39 (170 MB/s) - ‘export_v2.py’ saved [7603/7603]<jupyter_text>এক্সপোর্টার দিয়ে এমবেডিং ফাইল নেবার সময় ওয়ার্ড২ভেক বা ফাস্টটেক্সট এর হেডারটা অনেক বড় হয় বলে সেটাকে ফেলে দিতে পারি। বিশেষ করে লোকাল মেশিনে বা গুগল কোলাবে এটা একটা বাড়তি সমস্যা।<jupyter_code>!python export_v2.py --embedding_file=/content/bn-wiki-word2vec-300.txt --export_path=text_embedding --num_lines_to_ignore=1 
# !python export.py --embedding_file=/content/bn-wiki-word2vec-300.txt --export_path=text_embedding --num_lines_to_ignore=1 --preprocess_text=True
# সেভড মডেলের একটা কমান্ড লাইন ইন্টারফেস আছে দেখার জন্য, এখনো কিছু আসেনি এখানে

!saved_model_cli show --dir text_embedding --all<jupyter_output>/usr/local/lib/python3.6/dist-packages/tensorflow/python/framework/dtypes.py:516: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.
  _np_qint8 = np.dtype([("qint8", np.int8, 1)])
/usr/local/lib/python3.6/dist-packages/tensorflow/python/framework/dtypes.py:517: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.
  _np_quint8 = np.dtype([("quint8", np.uint8, 1)])
/usr/local/lib/python3.6/dist-packages/tensorflow/python/framework/dtypes.py:518: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.
  _np_qint16 = np.dtype([("qint16", np.int16, 1)])
/usr/local/lib/python3.6/dist-packages/tensorflow/python/framework/dtypes.py:519: FutureWarning: Passing (type, 1) or [...]<jupyter_text>hub.KerasLayer ব্যবহার হচ্ছে, তবে আমাদের এমবেডিং মডিউলে trainable=False সেট করা হয়েছে যাতে এমবেডিং ওয়েটগুলো আপডেট না হয় ট্রেনিং এর সময়। তবে আমরা দুটোই টেস্ট করবো।<jupyter_code># এই মডিউলটা ফ্রিজ করা আছে, মনে আছে ট্রান্সফার লার্নিং এর কথা?
# পাশাপাশি hub.KerasLayer এর আর্গুমেন্টগুলো দেখুন 
# __init__(
#    spec,
#    trainable=False,
#    name='module',
#    tags=None
#)

embedding_path = "text_embedding"
embedding_layer = hub.KerasLayer(embedding_path, trainable=True)
# embedding_layer = hub.KerasLayer(embedding_path, trainable=False)
print(embedding_layer)<jupyter_output><tensorflow_hub.keras_layer.KerasLayer object at 0x7f51cc418128><jupyter_text>বাংলা শব্দকে embedding_layerয়ে পাঠিয়ে দিয়ে দেখিবাংলা শব্দগুলোকে কিভাবে পাঠাবো এই নতুন মডিউলে? নিচের উদাহরন দেখুন। বাক্যের মধ্যে শব্দগুলোকে ভাগ করছে স্পেস দেখে। একটা বাক্যের ব্যাচ করে এক ডাইমেনশনের টেন্সর দেখাচ্ছে আমাদের shape এট্রিবিউটে। এখানে বাক্য আর শব্দ এমবেডিং নিয়ে একটা চিন্তা আছে তবে সেটা আসবে নিচের উদাহরন থেকে।```tf.nn.embedding_lookup_sparse(    params,    sp_ids,    sp_weights,    combiner=None,    max_norm=None,    name=None)```এর মানে হচ্ছে embedding_layer ইনপুট হিসেবে বাংলা শব্দ নিয়ে এমবেডিং বের করে দিচ্ছে ঠিকমতো।<jupyter_code>embedding_layer(['ভালো আছি'], ['আমরা']).shape<jupyter_output><empty_output><jupyter_text>টেন্সর-ফ্লো এর জন্য তৈরি করি ডেটাসেট  আপনার মনে আছে, আমাদের all_sentences এর মধ্যে প্রথম দিকে পজিটিভ আর শেষের দিকে নেগেটিভ সেন্টিমেন্টের বাক্য ছিলো। এখন এই ডেটা দিয়ে ট্রেনিং করালে ভারসাম্য থাকবে না। তাই শুরুতে দৈবচয়নের মাধ্যমে শাফল করে নেই। আমরা কাজ করবো একটা জেনারেটর নিয়ে।  জেনারেটর দিয়ে ডেটাসেট তৈরিতে শুরুতে আমরা একটা জেনারেটর ফাংশন বানিয়ে দিলে সেটা প্রতিটা বাক্য এবং তার করেসপন্ডিং লেবেল থেকে একটা পুরো এক্সাম্পল (ডেটা + লেবেল) তৈরি করে দেবে। এরপর সেটাকে tf.data.Dataset.from_generator পাঠালে সেটার কি ধরনের আউটপুট চাই সেটা বললে হবে। জেনারেটরের একটা উদাহরণ দেখি। generator বানিয়ে সেটা পাঠাচ্ছি from_generator এর মধ্যে। ```@staticmethodfrom_generator(    generator,    output_types,    output_shapes=None,    args=None)```এর ব্যবহার?```import itertoolstf.compat.v1.enable_eager_execution()def gen():  for i in itertools.count(1):    yield (i, [1] * i)ds = tf.data.Dataset.from_generator(    gen, (tf.int64, tf.int64), (tf.TensorShape([]), tf.TensorShape([None])))for value in ds.take(2):  print value (1, array([1])) (2, array([1, 1]))```<jupyter_code>import random

def generator():
    random.shuffle(all_sentences)    
    for sentence, label in all_sentences:
        if label =='positive':
            label = tf.keras.utils.to_categorical(1, num_classes=2)
        else:
            label = tf.keras.utils.to_categorical(0, num_classes=2)
        sentence_tensor = tf.constant(sentence, dtype=tf.dtypes.string)
        yield sentence_tensor, label<jupyter_output><empty_output><jupyter_text>প্রতিটা এক্সাম্পল এখানে একটা বাক্যের টুপল যা dtype=tf.dtypes.string এবং লেবেলটা হচ্ছে ওয়ান হট এনকোডেড। ডেটাসেট তৈরিতে একটা ট্রেনিং এবং ভ্যালিডেশন সেট লাগবে। কিভাবে করা যায়?```train_data = data.take(train_size)validation_data = data.skip(train_size)```<jupyter_code>def make_dataset(train_size):
  data = tf.data.Dataset.from_generator(generator=generator, 
                                        output_types=(tf.string, tf.float32))
  train_size = 4000
  train_data = data.take(train_size)
  validation_data = data.skip(train_size)
  return train_data, validation_data
# ৮০-২০% ভাগ করে ডেটাসেট তৈরি

train_data, validation_data = make_dataset(0.80)
# একটা ব্যাচ দেখি, যেখানে ২টা এলিমেন্ট থাকবে train_data থেকে 
# এরকম বেশ কয়েকটা উদাহরন দেখি নিচে

next(iter(train_data.batch(2)))
sentences_in_a_single_batch, labels_in_a_single_batch = next(iter(train_data.batch(2)))
sentences_in_a_single_batch
sentences_in_a_single_batch.shape
labels_in_a_single_batch.shape
sentence, label = next(iter(train_data.take(1)))
# numpy()কে ডিকোড করতে হবে ইউনিকোডে, তা না হলে স্ট্রিংকে বাইট হিসেবে পাঠাবে

sentence.numpy().decode('utf8')
# to_categorical() এর কনভার্সনের পর লেবেল
label.numpy()<jupyter_output><empty_output><jupyter_text>মডেল ট্রেনিং  এই মডেল আগেও তৈরি করেছি আমরা। এখানে এমবেডিং লেয়ারকে ঢুকিয়ে দিয়েছি শুরুতেই। ```model.add(embedding_layer)```tf.data থেকে স্যাম্পলকে ব্যাচ করে পাঠানো হবে মডেলে।LSTM নিয়ে কাজ করবো সামনে।  ডেন্স লেয়ার দিয়ে মডেলLSTM দিয়ে কাজ করানোর চেষ্টা চলছে।<jupyter_code>def create_model():
  model = tf.keras.Sequential()
  model.add(embedding_layer)
  # model.add(tf.keras.layers.Flatten())
  # model.add(tf.keras.layers.SpatialDropout1D(0.2))
  # model.add(tf.keras.layers.LSTM(100, dropout=0.2, recurrent_dropout=0.2))
  # model.add(Dense(13, activation='softmax'))
  model.add(tf.keras.layers.Dense(256, activation="relu"))
  model.add(tf.keras.layers.Dense(128, activation="relu"))
  model.add(tf.keras.layers.Dense(2, activation="softmax"))
  model.compile(optimizer="adam",loss="categorical_crossentropy",metrics=['acc'])
  return model
from tensorflow.keras.callbacks import TensorBoard
log_dir="logs/fit/"
tensorboard_callback = tf.keras.callbacks.TensorBoard(log_dir=log_dir, histogram_freq=1)

model = create_model()<jupyter_output><empty_output><jupyter_text>ট্রেনিং ১০ ইপক দিয়ে<jupyter_code>batch_size = 256
history = model.fit(train_data.batch(batch_size), 
                    validation_data=validation_data.batch(batch_size), 
                    epochs=10,callbacks=[tensorboard_callback])
model.summary()<jupyter_output>Model: "sequential_1"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
keras_layer_1 (KerasLayer)   multiple                  200881800 
_________________________________________________________________
dense_2 (Dense)              multiple                  77056     
_________________________________________________________________
dense_3 (Dense)              multiple                  32896     
_________________________________________________________________
dense_4 (Dense)              multiple                  258       
=================================================================
Total params: 200,992,010
Trainable params: 200,992,010
Non-trainable params: 0
_________________________________________________________________<jupyter_text>মডেলকে সেভ করে রাখি ভবিষ্যত কাজে<jupyter_code>tf.saved_model.save(model, export_dir="my_model")<jupyter_output>INFO:tensorflow:Assets written to: my_model/assets<jupyter_text>প্রেডিকশনদেখুন আমাদের প্রেডিক্ট মেথড কি বের করে নিয়ে আসে? চেষ্টা করুন নতুন নতুন শব্দ দিয়ে। নিচের sents এর মধ্যে আপনার পছন্দের বাক্যটা লিখে চেষ্টা করুন। ১ হচ্ছে পজিটিভ ০ হচ্ছে নেগেটিভ।<jupyter_code>sents = ['আমারা খুবি খুশি অফারটির জন্য', 'বই পড়তে অনেক পছন্দ করি', 'আজকের ঘটনা আমাকে মনে কষ্ট দিয়েছে', 'কাজটা খুব খারাপ হয়েছে', 
         'আমি দেশকে খুব ভালবাসি', 'এই বইটা বেশ ভালো লাগছে', 'একটা দুর্ঘটনা ঘটে গেল',
         'আজকে একটা অসাধারণ অভিজ্ঞতা হলো', 'আমাদের কাজ করতে বেশ কষ্ট হয়', 'বিদ্যুতের ঘাটতি হলে কারখানার কাজ কমে যায়',
         'ঢাকা-সিলেটসহ আশপাশের সড়কের যানবাহন চলাচল বন্ধ হয়ে যায়',]
pred_dataset = tf.data.Dataset.from_tensor_slices(sents)
prediction = model.predict(np.array(sents))

for sentence, pred_sentiment in zip(sents, prediction.argmax(axis=1)):
  print("Sentence:{} - predicted: {}".format(sentence, pred_sentiment))<jupyter_output>Sentence:আমারা খুবি খুশি অফারটির জন্য - predicted: 1
Sentence:বই পড়তে অনেক পছন্দ করি - predicted: 1
Sentence:আজকের ঘটনা আমাকে মনে কষ্ট দিয়েছে - predicted: 0
Sentence:কাজটা খুব খারাপ হয়েছে - predicted: 0
Sentence:আমি দেশকে খুব ভালবাসি - predicted: 1
Sentence:এই বইটা বেশ ভালো লাগছে - predicted: 1
Sentence:একটা দুর্ঘটনা ঘটে গেল - predicted: 0
Sentence:আজকে একটা অসাধারণ অভিজ্ঞতা হলো - predicted: 1
Sentence:আমাদের কাজ করতে বেশ কষ্ট হয় - predicted: 0
Sentence:বিদ্যুতের ঘাটতি হলে কারখানার কাজ কমে যায় - predicted: 0
Sentence:ঢাকা-সিলেটসহ আশপাশের সড়কের যানবাহন চলাচল বন্ধ হয়ে যায় - predicted: 0<jupyter_text>চালু করি আমাদের টেন্সরবোর্ডকে<jupyter_code>%reload_ext tensorboard
%tensorboard --logdir logs/fit<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.2183242506811989, 'fraction_numerical': 0.0652491241728299, 'mean_word_length': 4.900947459086994, 'pattern_counts': {'":': 0, '<': 62, '<?xml version=': 0, '>': 63, 'https://': 10, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 4, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '17', 'dir': 'jupyter-structured-clean-dedup', 'id': '122625', 'license': 'MIT', 'n_tokens_mistral': 14530, 'n_tokens_neox': 15879, 'n_words': 2010, 'path': 'final_sentiment_analysis_v2.ipynb', 'repo_name': 'shamimreza/TensorFlow2', 'size': '20559'}