<jupyter_start><jupyter_text>অ্যান্ড্রয়েড অ্যাপের জন্য "এমনিস্ট" হাতে লেখা ডিজিট চিনতে মডেল ট্রেনিং (২) হালের ফ্যাশন 'এমনিস্ট' ডেটাসেট নিয়ে কাজ করলেও আমার মন পড়েছিল কিভাবে আসল 'এমনিস্ট' নিয়ে কাজ করা যায়। সেই সুযোগটা নিলাম এই মোবাইল অ্যাপ এর জন্য মডেল তৈরি করতে গিয়ে। একই কোড কাজ করবে এখানে, ফ্যাশন এমনিস্টএর মতো। শুধুমাত্র অ্যাডঅন, মডেলটাকে কনভার্ট করবো টেন্সরফ্লো লাইটে - মোবাইল ডিভাইসে চালানোর জন্য<jupyter_code># শুধুমাত্র টেন্সরফ্লো ২.x এর জন্য
try:
  # %tensorflow_version only exists in Colab.
  %tensorflow_version 2.x
except Exception:
  pass

from __future__ import absolute_import, division, print_function, unicode_literals

# টেন্সরফ্লো ২.x এবং tf.keras
import tensorflow as tf
from tensorflow import keras

# সাহায্যকারী লাইব্রেরি
import numpy as np
import matplotlib.pyplot as plt
import random

print(tf.__version__)<jupyter_output>TensorFlow 2.x selected.
2.1.0-rc1<jupyter_text>ডাউনলোড করি "এমনিস্ট" ডেটাসেটএকই ৬০,০০০ এবং ১০,০০০ ট্রেনিং এবং টেস্ট ইমেজ তবে এবার হাতেলেখা ০ থেকে ৯ পর্যন্ত ইংরেজি সংখ্যা। ০ থেকে ৯ সংখ্যা মানে আগের মতো ১০টা ক্লাস।আগের মতো ইমেজগুলো ২৮ x ২৮ পিক্সেলের গ্রেস্কেল ইমেজ। ছবি দেখুন।![MNIST sample](https://github.com/khanhlvg/DigitClassifier/raw/master/images/mnist.png)<jupyter_code># কেরাস থেকে এপিআই দিয়ে ডাউনলোড করে দেখাচ্ছি, টিএফডিএস নয়, ভ্যারিয়েশন
# ট্রেনিং এবং টেস্ট ডেটাসেট
mnist = keras.datasets.mnist
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
# আগের মতো নর্মালাইজ করে ০ থেকে ১ এর মধ্যে রাখছি
train_images = train_images / 255.0
test_images = test_images / 255.0
print('Pixels are normalized')<jupyter_output>Pixels are normalized<jupyter_text>টেন্সরফ্লো মডেল তৈরি ডিজিট ক্লাসিফাই করার জন্যএকদম আগের মতো। কোন পার্থক্য় নেই।<jupyter_code># শুরুতে মডেল আর্কিটেকচার ডিফাইন করছি
model = keras.Sequential([
  keras.layers.InputLayer(input_shape=(28, 28)),
  keras.layers.Reshape(target_shape=(28, 28, 1)),
  keras.layers.Conv2D(filters=12, kernel_size=(3, 3), activation=tf.nn.relu),
  keras.layers.MaxPooling2D(pool_size=(2, 2)),
  keras.layers.Flatten(),
  keras.layers.Dense(10, activation=tf.nn.softmax)
])

# মডেলকে ট্রেইন করতে হবে, তার আগে কম্পাইল
model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

# ডিজিট ক্লাসিফিকেশন মডেল ট্রেনিং
model.fit(train_images, train_labels, epochs=5)<jupyter_output>Train on 60000 samples
Epoch 1/5
60000/60000 [==============================] - 11s 177us/sample - loss: 0.2655 - accuracy: 0.9264
Epoch 2/5
60000/60000 [==============================] - 4s 67us/sample - loss: 0.1035 - accuracy: 0.9708
Epoch 3/5
60000/60000 [==============================] - 4s 72us/sample - loss: 0.0759 - accuracy: 0.9785
Epoch 4/5
60000/60000 [==============================] - 4s 68us/sample - loss: 0.0626 - accuracy: 0.9818
Epoch 5/5
60000/60000 [==============================] - 4s 68us/sample - loss: 0.0540 - accuracy: 0.9839<jupyter_text>মডেলের সামারি<jupyter_code>model.summary()<jupyter_output>Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
reshape (Reshape)            (None, 28, 28, 1)         0         
_________________________________________________________________
conv2d (Conv2D)              (None, 26, 26, 12)        120       
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 13, 13, 12)        0         
_________________________________________________________________
flatten (Flatten)            (None, 2028)              0         
_________________________________________________________________
dense (Dense)                (None, 10)                20290     
=================================================================
Total params: 20,410
Trainable params: 20,410
Non-trainable params: 0
____________________________________________________[...]<jupyter_text>এখানে যে বাড়তি ডাইমেনশন আছে **None** শেপ দিয়ে প্রতিটা লেয়ারে, সেটা আসলে ব্যাচ ডাইমেনশন। যেহেতু ডেটা ব্যাচে প্রসেস হয়, সেকারণে টেন্সরফ্লো নিজে থেকে যোগ করে দেয়।  মডেলের ইভালুয়েশনটেস্ট ডেটাসেট দিয়ে কেমন কাজ করে?<jupyter_code>test_loss, test_acc = model.evaluate(test_images, test_labels)

print('Test accuracy:', test_acc)<jupyter_output>10000/10000 [==============================] - 1s 68us/sample - loss: 0.0647 - accuracy: 0.9801
Test accuracy: 0.9801<jupyter_text>কেরাস মডেল থেকে টেন্সরফ্লো লাইটে কনভার্ট করছি এখানে ডিজিট ক্লাসিফায়ার মডেলকে টিএফ লাইট ফরম্যাটে আনছি।<jupyter_code># কনভার্টারের ব্যবহার
converter = tf.lite.TFLiteConverter.from_keras_model(model)
tflite_float_model = converter.convert()

# মডেলের সাইজ কিলোবাইটে
float_model_size = len(tflite_float_model) / 1024
print('Float model size = %dKBs.' % float_model_size)<jupyter_output>Float model size = 81KBs.<jupyter_text>টেন্সরফ্লো লাইট মডেল ডাউনলোড করছি এখানেএই মডেলটাকে ডাউনলোড করছি এখানে যাতে এটাকে অ্যান্ড্রয়েড অ্যাপে ঢুকিয়ে কাজ করতে পারি। এটাকে কপি করে রাখতে হবে দরকারী ফোল্ডারে।mnist.tflite ফাইলটা একবারে ডাউনলোড না হলে শুধুমাত্র এই সেলটাকে আবার চালাতে হবে।<jupyter_code># ফাইলটাকে সেভ করে রাখি এখানে mnist.tflite হিসেবে
f = open('mnist.tflite', "wb")
f.write(tflite_float_model)
f.close()

# ডাউনলোড করি mnist.tflite হিসেবে
from google.colab import files
files.download('mnist.tflite')

print('`mnist.tflite` has been downloaded')<jupyter_output>`mnist.tflite` has been downloaded
{'fraction_non_alphanumeric': 0.22670579603815114, 'fraction_numerical': 0.050256786500366836, 'mean_word_length': 5.1407657657657655, 'pattern_counts': {'":': 0, '<': 22, '<?xml version=': 0, '>': 22, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 3, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '7', 'dir': 'jupyter-structured-clean-dedup', 'id': '659203', 'license': 'MIT', 'n_tokens_mistral': 3264, 'n_tokens_neox': 3483, 'n_words': 480, 'path': 'digitclassifier.ipynb', 'repo_name': 'laziestcoder/tf_lite_android', 'size': '5452'}