এই বইটার একটা বড় ফিচার হচ্ছে, প্রতিটা মেশিন/ডিপ লার্নিং প্রোডাক্ট তৈরির পাইপলাইনে প্রতিটা ট্রান্সফরমেশন, প্রসেসিং/প্রি-প্রসেসিং নিজে 'হাতেকলমে' করে দেখে বুঝে নেবেন। একজন বলেছেন অথবা বইয়ের থিওরির ধারণা থেকে বিশ্বাস করবেন, সেটা ফেলে দিয়ে নিজে হাতে করে বুঝে নেবেন প্রতিটা স্টেপ। আর সেকারণে এই নোটবুকগুলো খুব ইম্পর্ট্যান্ট। নিজে হাতে চালিয়ে দেখবেন যতক্ষণ না বুঝছেন। সময়ের সাথে 'আপডেটেড' এই নোটবুকগুলো নিয়ে 'প্র্যাকটিস' এবং 'প্র্যাকটিস' আপনাকে নিয়ে যাবে অন্য উচ্চতায়।
যেহেতু গিটবুকে নোটবুক ঠিকমতো রেন্ডার হয়না, সেকারণে গুগল কোলাব এবং গিটহাবে দেখা উচিৎ। গিটহাব লিংক:
মনে আছে ছোট্ট রকিব এবং তার ফুপিমার গল্পের কথা? আমি আগের বই “শূন্য থেকে পাইথন মেশিন লার্নিং” বইটার কথা বলছিলাম। সেখানে গল্পটা ছিল এরকম, কোন এক রাত্রে যখন সবাই গরমে কাহিল, তখন ওই সময়ে কত টেম্পারেচার সেটা নিয়ে কথা হচ্ছিল ছোট্ট রকিবের গ্রামের দাদা বাড়িতে। ফুঁপিমা বলছিলেন, বাইরের বসার ঘরের সেই বড় থার্মোমিটার না দেখেও তখনকার টেম্পারেচার আন্দাজ করা যাবে ঝিঁঝিঁপোকার ডাক থেকে। সবাই অবাক, সবার প্রশ্ন কিভাবে?
বোঝা গেল যে ঝিঁঝিঁপোকার ডাকের সাথে তাপমাত্রা একটা সম্পর্ক আছে। তাপমাত্রা বাড়লে ঝিঁঝিঁপোকার ডাকার ফ্রিকোয়েন্সি বেড়ে যায়। এবং এই ডাকার ফ্রিকোয়েন্সি তাপমাত্রা সাথে অনেকটাই লিনিয়ার। মানে, তাপমাত্রা বাড়লে ডাকের ফ্রিকুয়েন্সি বাড়ে। ব্যাপারটাকে উল্টো করে ধরলে বলা যায়, ঝিঁঝিঁপোকার ডাককে ঠিকমত গুনতে পারলে ওই মুহূর্তের তাপমাত্রা বের করা সম্ভব হবে। ফুঁপিমা এর নোটবুক থেকে দেখা গেল, উনি একেকদিনের ঝিঁঝিঁপোকার ডাক এবং তাপমাত্রা পাশাপাশি লিখে সেটার মধ্যে একটা যোগসুত্র বের করেছিলেন সেগুলোকে প্লট করে। পুরো ১ মিনিটের ডাক রেকর্ড না করে তার প্রতি ১৫ সেকেন্ডের ঝিঁঝিঁপোকার ডাক এর সাথে তাপমাত্রাকে প্লটিংয়েই বোঝা গেল সেই লিনিয়ার সম্পর্ককে।
ঝিঁঝিঁপোকার ডাক বেড়ে যাওয়া মানে তাপমাত্রা বেড়ে যাওয়া। সেখান থেকে একটা ফর্মুলা বের করেছিলেন ওই সময়। ওই ফর্মুলা দিয়ে আমাদেরকে কেউ ঝিঁঝিঁপোকার ডাক এর সংখ্যা বললে তার করেসপন্ডিং ওই সময়ে কত তাপমাত্রা হবে সেটা বের করা যাবে ওই ফর্মুলা দিয়ে। তাহলে তো আর সেটা মেশিন লার্নিং হলো না। ফর্মুলা হচ্ছে একটা রুল বেইজড সিস্টেম, যা মেশিন ডেটা থেকে শেখে না। আমি এই মুহূর্তে ফর্মুলাটা আমাদের মেশিনের কাছে আগে থেকে বলছি না, কারণ আমাদের ফুঁপিমা নোটবুক থেকে ডেটা সরাসরি মেশিনে দিয়ে দেবো - সে তার ফর্মুলা বের করতে পারে কিনা? যদি সে ইনপুট ডেটা থেকেই ফর্মুলা বের করতে পারে তাহলে আমরা বুঝে যাবো আমাদের মেশিন শিখছে। সে একটা লার্নিং মেশিন। ডেটা পাল্টে গেলে আবার সে নতুন ফর্মুলা দেবে।
রাজি তো? আবারো বলছি - আমরা মেশিনকে আগে থেকে ফর্মুলা বলবো না। দেখি সে ফর্মুলা বের করতে পারে কিনা?
প্রবলেম স্টেটমেন্ট
আমরা ঝিঝি পোকার 15 সেকেন্ডের ডাকের সংখ্যা বলবো, মেশিন কে আমাদেরকে বলতে হবে এখনকার তাপমাত্রা কত? এই মুহূর্তে আমাদের কাছে 55 টা রেকর্ড আছে যেখানে 15 সেকেন্ডের ঝিঝি পোকার ডাকের করেসপন্ডিং তাপমাত্রা দেয়া আছে টেবিলে। আপনারা শূন্য থেকে পাইথন মেশিন লার্নিং বইটা দেখতে পারেন। পাশাপাশি সেই ডাটা সেটের লিংক নিচে দেয়া হল।
ব্যাপারটাকে আমি তিন ভাবে করতে পারি।
শুধুমাত্র এটুকু বলতে পারি, প্রথম দুটো মেশিন লার্নিং নয়।
শুরুতেই ডিপেন্ডেন্সিগুলোকে ইমপোর্ট
১. প্রথমেই টেন্সর-ফ্লো, এটাকে আমরা tf বলবো সুবিধার জন্য।
২. টেন্সর-ফ্লো আর নামপাই খুব কাছের জিনিস। নামপাইকে শর্ট করে np, যা আমাদেরকে দেবে C++ এর গতি।
import tensorflow as tfimport numpy as np
টেন্সর-ফ্লো ২.০
আগে দেখে নেই আমাদের টেন্সর-ফ্লো এর কতো ভার্সন ইনস্টল করা আছে। অন্য ভার্সন থাকলে সেটাকে আপগ্রেড করে নেবো নতুন ভার্শনে।
tf.__version__
'1.14.0'
আপগ্রেড করে নিচ্ছি ২.০তে। এমুহুর্তে দরকার না থাকলেও আমরা পুরো বইটা টেন্সর-ফ্লো ২.০ দিয়ে সাঁজাতে চাই প্লাটফর্মের কনসিস্টেন্সির জন্য।
শুরুতেই আমরা ডাটাগুলোকে দুটো লিস্টে ভাগ করি। প্রথম লিস্ট 'chirp15s' যেখানে আমরা ১৫ সেকেন্ডে ঝিঁঝিঁ পোকার ডাকের সংখ্যা রেকর্ড করেছি। প্রথম দুটো রেকর্ড দেখলে বোঝা যায় ঝিঁঝিঁপোকা ১৫ সেকেন্ডে ৪৪ এবং ৪৬ বার ডেকেছে। পরের লিস্টে হচ্ছে তাপমাত্রা, যা সেলসিয়াস "temp_celsius" রেকর্ড করা হয়েছে। সেলসিয়াস মানে আমাদের সেন্টিগ্রেড। বোঝার সুবিধার জন্য এখানে একটা ফর লুপে আমরা ঝিঁঝিঁপোকার ডাক এর পাশাপাশি তাপমাত্রা ফেলে দিচ্ছি।
44.0 Chirps in 15 Seconds = 26.944 degrees Celsius (C)
46.4 Chirps in 15 Seconds = 25.833 degrees Celsius (C)
43.6 Chirps in 15 Seconds = 25.556 degrees Celsius (C)
35.0 Chirps in 15 Seconds = 23.056 degrees Celsius (C)
35.0 Chirps in 15 Seconds = 21.389 degrees Celsius (C)
32.6 Chirps in 15 Seconds = 20.0 degrees Celsius (C)
28.9 Chirps in 15 Seconds = 18.889 degrees Celsius (C)
27.7 Chirps in 15 Seconds = 18.333 degrees Celsius (C)
25.5 Chirps in 15 Seconds = 16.389 degrees Celsius (C)
20.375 Chirps in 15 Seconds = 13.889 degrees Celsius (C)
12.5 Chirps in 15 Seconds = 12.778 degrees Celsius (C)
37.0 Chirps in 15 Seconds = 24.583 degrees Celsius (C)
37.5 Chirps in 15 Seconds = 23.333 degrees Celsius (C)
36.5 Chirps in 15 Seconds = 23.333 degrees Celsius (C)
36.2 Chirps in 15 Seconds = 22.5 degrees Celsius (C)
33.0 Chirps in 15 Seconds = 18.889 degrees Celsius (C)
43.0 Chirps in 15 Seconds = 25.278 degrees Celsius (C)
46.0 Chirps in 15 Seconds = 25.833 degrees Celsius (C)
29.0 Chirps in 15 Seconds = 20.278 degrees Celsius (C)
31.7 Chirps in 15 Seconds = 20.278 degrees Celsius (C)
31.0 Chirps in 15 Seconds = 20.0 degrees Celsius (C)
28.75 Chirps in 15 Seconds = 18.889 degrees Celsius (C)
23.5 Chirps in 15 Seconds = 15.0 degrees Celsius (C)
32.4 Chirps in 15 Seconds = 21.111 degrees Celsius (C)
31.0 Chirps in 15 Seconds = 20.556 degrees Celsius (C)
29.5 Chirps in 15 Seconds = 19.444 degrees Celsius (C)
22.5 Chirps in 15 Seconds = 16.25 degrees Celsius (C)
20.6 Chirps in 15 Seconds = 14.722 degrees Celsius (C)
35.0 Chirps in 15 Seconds = 22.222 degrees Celsius (C)
33.1 Chirps in 15 Seconds = 21.667 degrees Celsius (C)
31.5 Chirps in 15 Seconds = 20.556 degrees Celsius (C)
28.8 Chirps in 15 Seconds = 19.167 degrees Celsius (C)
21.3 Chirps in 15 Seconds = 15.556 degrees Celsius (C)
37.8 Chirps in 15 Seconds = 23.889 degrees Celsius (C)
37.0 Chirps in 15 Seconds = 22.917 degrees Celsius (C)
37.1 Chirps in 15 Seconds = 22.5 degrees Celsius (C)
36.2 Chirps in 15 Seconds = 21.111 degrees Celsius (C)
31.4 Chirps in 15 Seconds = 19.722 degrees Celsius (C)
30.2 Chirps in 15 Seconds = 18.889 degrees Celsius (C)
31.3 Chirps in 15 Seconds = 20.556 degrees Celsius (C)
26.1 Chirps in 15 Seconds = 17.222 degrees Celsius (C)
25.2 Chirps in 15 Seconds = 17.222 degrees Celsius (C)
23.66 Chirps in 15 Seconds = 16.111 degrees Celsius (C)
22.25 Chirps in 15 Seconds = 16.667 degrees Celsius (C)
17.5 Chirps in 15 Seconds = 13.611 degrees Celsius (C)
15.5 Chirps in 15 Seconds = 12.778 degrees Celsius (C)
14.75 Chirps in 15 Seconds = 11.111 degrees Celsius (C)
15.0 Chirps in 15 Seconds = 11.667 degrees Celsius (C)
14.0 Chirps in 15 Seconds = 10.0 degrees Celsius (C)
18.5 Chirps in 15 Seconds = 11.111 degrees Celsius (C)
27.7 Chirps in 15 Seconds = 18.333 degrees Celsius (C)
26.0 Chirps in 15 Seconds = 17.222 degrees Celsius (C)
21.7 Chirps in 15 Seconds = 15.0 degrees Celsius (C)
12.5 Chirps in 15 Seconds = 10.417 degrees Celsius (C)
12.5 Chirps in 15 Seconds = 9.5833 degrees Celsius (C)
ডেটা ভিজ্যুয়ালাইজেশন
১. আমরা পুরো ডাটাসেটকে এক্স এবং ওয়াই এক্সিসে প্লট করতে পারি। যেহেতু আমরা আগেই দেখেছি ঝিঁঝিঁপোকার ডাক এবং তাপমাত্রার সম্পর্কটা লিনিয়ার, সেখানে একটা 'বেস্ট ফিট লাইন' আমাদেরকে ভবিষ্যৎ যে কোনো ডাকের সংখ্যার করেসপন্ডিং তাপমাত্রা দেখাতে পারবে। এক্স অ্যাক্সিস যদি ঝিঁঝিঁপোকার ডাকের সংখ্যা হয় তাহলে ওয়াই এক্সিসে তারপর করেসপন্ডিং তাপমাত্রা পাওয়া যাবে।
২. নতুন ঝিঁঝিঁপোকার ডাক এর সংখ্যা যেটা এখানে নেই, সেটাও এই প্লটিং এ এক্স এক্সিসের যে অংশটা ওয়াই এক্সিসের এর সঙ্গে স্পর্শ করেছে সেটাই প্রেডিক্টেড তাপমাত্রা হবে।
তবে, এই ছবিতে আমরা সেটা না দেখিয়ে সামনে দেখানোর প্ল্যান করছি।
import matplotlib.pyplot as pltX = chips_15sy = temp_celsiusplt.scatter(X, y, color='red')plt.show()
৩. আমাদের যেহেতু ৫৫টা রেকর্ড আছে, আর রেকর্ডগুলো প্লট করলে প্রায় একটা সরল রেখা হয়, তাহলে কি একটা সরলরেখার ইকুয়েশন বের করতে পারি আমরা? সরলরেখার ইকুয়েশনে আমরা ওয়াই ভ্যালু, মানে আমাদের 'প্রেডিক্টেড' তাপমাত্রা বের করতে চাইলে, এক্স ভ্যালুতে ঝিঁঝিঁপোকার ডাক এর সংখ্যা বসালেই তো উত্তর পাবার কথা, ঠিক না? সরলরেখার ইকুয়েশন যদি y = mx + b হয় তাহলে তো 'm' যাকে আমরা স্লোপ বা ঢাল বলছি, সেটা বের করা যাবে না? এর পাশাপাশি ওয়াই ইন্টারসেপ্ট 'b' পাওয়াটা তো কঠিন কিছু না। এই পুরো ব্যাপারটা আমরা দু ভাবে করতে পারি। প্রথমটা সাধারণ অংক, ফর্মুলা থেকে, পরেরটা আমরা দেখবো পাইথন দিয়ে। কোনটাই মেশিন লার্নিং নয়।
আমরা সরল রেখার অংক মানে ইকুয়েশন (y = mx + b) নিয়ে আলাপ করছি। আগের বই "শূন্য থেকে পাইথন মেশিন লার্নিং" বইয়ে বড় করে আলাপ করেছিলাম আগে।
এই ফর্মুলাটা নিরেট অংকে করি
কোন মেশিন লার্নিং নয়
আমাদের ৫৫টা ডেটাপয়েন্ট থেকে অংকে ফর্মুলাতে নিয়ে আসি। সরল রেখার অংক। ফর্মুলা নিচে দেখুন।
আমাদের "chips_15s" মানে X এর সব ভ্যালুগুলোকে যোগ করি।
from statistics import meandefbest_fit_slope_and_intercept(X,y): m = (((mean(X)*mean(y)) -mean(X*y)) / ((mean(X)*mean(X)) -mean(X*X))) b =mean(y)- m*mean(X)return m, bm, b =best_fit_slope_and_intercept(X,y)print(m,b)
0.49543811977958857 4.458638516454446
y = mx + b এর হিসেবে
y = 0.49543811977958857X + 4.458638516454446
একদম কাছাকাছি।
বেস্ট ফিট লাইন
আমরা একটা রিগ্রেশন লাইন টেনে ফেলি। ধরুন ১৫ সেকেন্ডের ঝিঁঝিঁপোকার ৪১ ডাকের প্রেডিকশন কি হবে? Y এক্সিসের বরাবর রেখাটা এক্স এক্সিসের কোথায় স্পর্শ করেছে সেটা দেখলেই কিন্তু পাওয়া যাবে।
# regression_line = [(m*x)+b for x in X]regression_line = []for x in X: regression_line.append((m*x)+b)plt.scatter(X,y,color='red')plt.plot(X, regression_line)plt.show()
মেশিন লার্নিং কিছু টার্মিনোলোজি
ফিচার — আমাদের মডেলের ইনপুট ডেটা। আমাদের এখানে একটা ভ্যালু - ১৫ সেকেন্ডে ঝিঁঝিঁপোকার ডাকের সংখ্যা।
লেবেল — যেই আউটপুটটা আমাদের মডেল শিখে প্রেডিক্ট করবে। আমাদের এখানে তাপমাত্রা।
এক্সাম্পল — ইনপুট/আউটপুট ডেটার একটা জোড়া, যা দরকার পড়ছে ট্রেনিং এর সময়। আমাদের এখানে chips_15s এবং temp_celsius অ্যারে থেকে দুটো ডেটা একটা ইনডেক্সে দেখলে (44.000,26.944) পাওয়া যাবে।
মেশিন লার্নিং মডেল
আমরা সাইকিট-লার্ন দিয়েও এই জিনিসটা করতে পারতাম। তবে, যেহেতু আমরা ডিপ লার্নিং মানে টেন্সর-ফ্লো নিয়ে কাজ করতে চাই, সেকারণে আমাদের শুরুতে ফোকাস থাকবে একটা সাধারণ মডেলে। বিশেষ করে বোঝার ক্ষেত্রে। একটা লিনিয়ার মডেলে নিউরাল নেটওয়ার্ক দরকার নেই, বরং নন-লিনিয়ার মডেলের জন্য দরকার নিউরাল নেটওয়ার্ক। সেগুলো নিয়ে সামনে আলাপ হবে।
৪. আমাদের কাছে যেই ডাটা আছে, সেটাকে মেশিন লার্নিং মডেলে ঢুকিয়ে দেবো, দেখি মেশিন লার্নিং মডেল এর থেকে কোনো ফর্মুলা বের করতে পারে কিনা? পাশাপাশি আমরা একটা অজানা ভ্যালু দিয়ে দেখতে চাইবো সেখান থেকে প্রেডিক্টেড ভ্যালু জানাতে পারে কিনা? তাহলেই তো আমাদের কাজ হয়ে যায়, কি বলেন? আমরা যদি আমাদের ডিপ লার্নিং লাইব্রেরি টেন্সর-ফ্লোকে ঝিঁঝিঁ পোকার ডাক এর সংখ্যা এবং তার করেসপন্ডিং তাপমাত্রা দিয়ে দেই, তাহলে যদি সে ফর্মুলা দিতে পারে, তখন আমরা বলতে পারব আমাদের মেশিন লার্নিং মডেল ডেটা থেকে শিখেছে। যদি ডাটা থেকে নিজে নিজেই ফর্মুলা বের করতে পারে সেটাই কিন্তু শেখা, মানে মেশিন লার্নিং।
আমাদের এই মডেল তৈরি করতে ডিপ লার্নিং অথবা টেন্সর-ফ্লো লাগবে না। তবে ডিপ লার্নিং ফ্রেমওয়ার্ক নিয়ে ধারণা পাবার জন্য একটা অগভীর মানে 'শ্যালো' এক লেয়ারের, এক নিউরনের নেটওয়ার্ক বানানোর চেষ্টা করবো।
নিউরাল নেটওয়ার্কের ৫ ষ্টেপ লাইফ সাইকেল - কেরাস দিয়ে
টেন্সর-ফ্লো ডিপ লার্নিং ফ্রেমওয়ার্ক হিসেবে একটু কমপ্লেক্স। সাইকিট-লার্ন এপিআইএর মতো এতো কম হাইপার-প্যারামিটার নিয়ে তাকে চালানো দুস্কর। যেহেতু ফ্রেমওয়ার্কটা অনেক শক্তিশালী, সেকারণে আমরা এটাকে এক্সেস করবো একটা হাই-লেভেল এপিআই দিয়ে যার কাজ হচ্ছে এই ভেতরের কমপ্লেক্সিটিকে লুকিয়ে রাখবে আমাদের কাছ থেকে। একারণে টেন্সর-ফ্লো ২.০ শুরুতেই যুক্ত করে নিয়েছে কেরাসকে। কেরাস দিয়ে ৯০%এর বেশি কাজ করা সম্ভব।
মডেলের ধারণা
এখন আমরা একটা মডেল তৈরি করতে চাই। মেশিন লার্নিং মডেল তবে জিনিসটা হবে খুবই সিম্প্লিস্টিক। একটা নিউরাল নেটওয়ার্ক। এখন কথা আসতে পারে নিউরাল নেটওয়ার্ক কি? (সামনে বিস্তারিত লিখেছি) নিউরন নেটওয়ার্ক আসলে কিছু অ্যালগরিদমের সেট যেটাকে কিছুটা তৈরি করা হয়েছে মানুষের মস্তিষ্কের নিউরাল এর ধারণার ওপর ভিত্তি করে। মানুষের মস্তিষ্কের সেই নিউরালকে আমরা নিয়ে এসেছি মেশিন লার্নিং এ। কারণ দুটোর কাজই এক। মেশিন লার্নিং এর যে নিউরাল নেটওয়ার্ক ব্যবহার করছি তার কাজ হচ্ছে বিভিন্ন লেয়ারে প্যাটার্ন ধরতে পারা। মানুষ যেমন তার হাজারো সেন্সর ডাটা আমাদের মস্তিষ্কে পাঠাচ্ছে, সেরকমভাবে নিউরাল নেটওয়ার্কের সবচেয়ে ছোট ইউনিট হচ্ছে একটা 'পারসেপ্ট্রন'। এই 'পারসেপ্ট্রন'গুলো যেভাবে প্যাটার্ন বুঝতে পারে তা সব সংখ্যার ভেক্টরে থাকে। আমাদের ইনপুট হিসেবে সেটা ছবি, শব্দ, লেখা অথবা টাইম সিরিজ হতে পারে - তবে সবকিছুকেই পাল্টে ফেলতে হবে সংখ্যায়।
বিভিন্ন লেয়ারে ফিচার এক্সট্রাকশন
সাধারণত: নিউরাল নেটওয়ার্কগুলো আমাদেরকে ডেটাকে বিভিন্ন গ্রুপে ক্লাস্টার করে দেয়। আমাদের ইনপুট ডাটার ওপর ভিত্তি করে সেটার ক্লাসিফিকেশন/রিগ্রেশন হবে শেষ লেয়ারে। ধরা যাক আমাদের কাছে বেশ কিছু 'লেবেল ছাড়া' ডাটা আছে। নিউরাল নেটওয়ার্কগুলো এই লেবেল ছাড়া ডাটাগুলোকে তাদের মধ্যে বিভিন্ন মিল/সঙ্গতি/অসঙ্গতি দেখে সেগুলোকে আলাদা করে গ্রুপিং করে সে। এরপর তাকে একটা লেবেল সহ ডাটাসেট দিলে সেই ট্রেনিং থেকে ফিচারগুলোকে 'এক্সট্রাক্ট' করতে পারে। নিউরাল নেটওয়ার্ক এর একটা বড় কাজ হচ্ছে বিভিন্ন লেয়ারে বিভিন্ন ফিচার এক্সট্রাক্ট করে সে। (সামনে বিস্তারিত আলাপ করেছি) সবশেষে একটা মানুষকে যদি ক্লাসিফাই করতে হয়, মানে চিনতে হয়, তাহলে সেটা শুরু হবে সেই পিক্সেল থেকে যার পর মানুষের মুখের একেকটা ফিচারের কোনা, মানে নাক, মুখ বানানোর জন্য যা যা ফিচার লাগবে সেগুলোকে সে এক্সট্রাক্ট করবে তার নিচের লেয়ার থেকে।
ছোট্ট একটা মডেল
শুরুতেই একটু অংক। ডিপ লার্নিং একটা এন্ড টু এন্ড ইকোসিস্টেম, বিশেষ করে আমরা যখন টেন্সর-ফ্লো এনভায়রমেন্ট ব্যবহার করব। আমাদের এই নিউরাল নেটওয়ার্ক আউটপুটের সাথে ইনপুটের একটা চমৎকার ম্যাপিং করে। এর কাজ হচ্ছে ডাটার মধ্যে কোরিলেশন বের করা। অনেকে এইজন্য এর নাম বলে থাকেন 'ইউনিভার্সাল অ্যাপ্রক্সিমেটর'। কারণ এর কাজ হচ্ছে একটা অজানা ফাংশন f(x) = y এর ভ্যালুকে ধারণা করা, x আর y হচ্ছে তার ইনপুট এবং আউটপুট। আগের বইয়ে আলাপ করা হয়েছে। মেশিন লার্নিং এর এই শেখার প্রসেসে, নিউরাল নেটওয়ার্ক খুঁজে পায় তার আসল ফাংশন, যেটাকে আমরা বলতে পারি একটা প্রসেস যা x থেকে থেকে ইনপুট নিয়ে আপডেট করবে y কে।
উদাহরণ কি দেব একটা? f(x) = 2x + 9 = y এর মত অসংখ্য উদাহরণ নিয়ে আলাপ করব সামনে।
হাতেকলমে মডেল তৈরি
যেহেতু আমরা একটা খুবই সহজ মডেল তৈরি করছি সেটাকে ডিপ লার্নিং এর ভাষায় আমরা বলছি ‘ডেন্স’ নেটওয়ার্ক। মানে একটার সাথে আরেকটার সরাসরি কানেকশন। গায়ে গায়ে লেগে থাকা। নেটওয়ার্কের একেকটা পারসেপ্ট্রন আরেকটার সাথে সম্পূর্ণভাবে কানেক্টেড থাকে। এর জন্যই একে বলা হচ্ছে 'ডেন্স'। 'ডেন্স'লি কানেক্টেড। (সামনে বিস্তারিত বলেছি) ‘ডেন্স’এর মডেল একেকটার সাথে স্ট্যাক করে কানেক্টেড মডেল। সেখানে আমরা ব্যবহার করবো "সিকোয়েন্সিয়াল", মানে একটার পর আরেকটা।
নিউরাল নেটওয়ার্ক তৈরি করতে আমাদের এটার লেয়ারগুলোর কনফিগারেশন বলতে হবে। লেয়ার ঠিকমতো কনফিগার করা হলে আমরা মডেলকে কম্পাইল করব। আগের ছবিতেও দেখেছেন এই জিনিসটা। যেহেতু আমাদের সমস্যা একটা লিনিয়ার রিগ্রেশন এর মত, মানে একটা সরল রেখার ইকুয়েশনের মত, সে কারণে আমাদের নেটওয়ার্কে একটা লেয়ার প্রয়োজন। সঙ্গে একটা নিউরন। সামনে দরকার মতো আমরা আরো কিছু লেয়ার নিয়ে আলাপ করব।
লেয়ারের কনফিগারেশন
একটা নিউরাল নেটওয়ার্কের বেসিক বিল্ডিং ব্লক হচ্ছে লেয়ার। লেয়ারগুলোতে যে ডেটা ফিড করানো হয় সেখান থেকে সে ডেটার রিপ্রেজেন্টেশনগুলোকে ঠিকমতো এক্সট্রাক্ট করে নিয়ে নেয় একেকটা লেয়ারে। বেশিরভাগ ডিপ লার্নিং মডেলগুলোর লেয়ার একটার সাথে আরেকটার কানেকশন ডেটাগুলোকে ঠিকমতো বুঝতে সাহায্য করে (ভিন্ন চ্যাপ্টার আছে সামনে)। যেহেতু আমাদের সমস্যাটা খুবই সহজ সে কারণে কিন্তু আমাদের এই নেটওয়ার্কে একটা লেয়ার হলেই চলবে। এই একটা লেয়ারে আমরা একটা নিউরন চালাবো।
তৈরি করি একটা লেয়ার
শুরুতেই লেয়ারটার নাম দিয়ে দিচ্ছি l0। মনে আছে scikit-learn এর কথা? সেই একইভাবে আমরা টেন্সর-ফ্লো একটা এপিআই কল করব আমাদের এই 'ডেন্স' লেয়ারের জন্য। যেহেতু আমরা সরাসরি টেন্সর-ফ্লো এর সাথে কথা বলতে চাইবো না এই মুহূর্তে, অবশ্যই সেটা বেশ কমপ্লেক্স, তাই একটা হাই লেভেল হেল্পার এপিআই দিয়ে এক্সেস করব নিচের কঠিন টেন্সর-ফ্লোকে। এখন আমরা শুধু মনে রাখি 'কেরাস' হচ্ছে আমাদের সেই হাই-লেভেল এপিআই যা টেন্সর-ফ্লো এর কম্প্লেক্সিটি লুকিয়ে রাখে। সবচেয়ে বড় কথা হচ্ছে টেন্সর-ফ্লো ২.০ এর সঙ্গে ইন-বিল্ট এসেছে এই 'কেরাস এপিআই'।
একটা লেয়ার তৈরি করি
আমাদের লেয়ার l0 মানে লেয়ার জিরো। এটাকে তৈরি করছি tf.keras.layers.Denseকে ইন্সট্যান্সিয়েট করে। ইন্সট্যান্সিয়েট ব্যাপারটা আমরা আলাপ করেছি সাইকিট-লার্নের আগের বইতে। নিচের কনফিগারেশনগুলো দেখি।
এখানে একটা ইনপুট, একটা লেয়ার, একটা নিউরন, এবং একটা আউটপুট। ছবি দেখুন। ইনপুটে একটা ভ্যালু, input_shape=[1], এটা একটা ১ ডাইমেনশনের একটা সংখ্যা।
input_shape=[1] — Input এর অর্থ হচ্ছে ইনপুট লেয়ার এ একটা ভ্যালু সে এক্সপেক্ট করছে। সিঙ্গেল ভ্যালু। সেই হিসেবে আমরা এটাকে বলছি এক ডাইমেনশনের একটা অ্যারে যার একটাই সদস্য। যেহেতু এটা এই মডেলের প্রথম এবং একটাই লেয়ার সে কারণে এই ইনপুট শেপ হচ্ছে পুরো মডেলিং ইনপুট শেপ। আমাদের এই সিঙ্গেল ভ্যালু হচ্ছে একটা ফ্লোটিং পয়েন্ট সংখ্যা, যা আসলে 15 সেকেন্ডে ঝিঁঝিঁপোকার ডাকের সংখ্যা।
units=1 — এই সংখ্যা দিয়ে আমরা বোঝাতে চাচ্ছি কতগুলো নিউরন হবে ওই লেয়ারে। আমাদের এই নিউরনের সংখ্যা বলে দেয় কতগুলো ইন্টারনাল ভ্যারিয়েবল সেই লেয়ারকে চেষ্টা করতে হবে শিখতে সমস্যাটা সমাধান করতে। সেটা নির্ভর করছে কতগুলো ইনপুট যুক্ত আছে সেই নিউরনের সাথে। মিতু এটাই এই মডেলের সব শেষ লেয়ার, আমাদের মডেলের আউটপুটের সাইজও কিন্তু ১। সারাদিন আউটপুট হচ্ছে একটা সিঙ্গেল ফ্লোট ভ্যালু ডিগ্রী সেলসিয়াস। ঝিঝি পোকা কত ডাক দিলে তার করেসপন্ডিং তাপমাত্রা। এটা যখন কয়েকটা লেয়ারের নেটওয়ার্ক হবে তাহলে সেই লেয়ারের সাইজ এবং সেপ একি হতে হবে পরবর্তী লেয়ারের input_shape।
যখন আমরা লেয়ারগুলোকে ডিফাইন করে ফেললাম এখন তাদেরকে মডেল এ যোগ করার পালা। আমরা যখন সিকুয়েন্সিয়াল মডেলকে আমাদের লেয়ারের আর্গুমেন্ট চেপে ধরে নেব তখন একটার পর আরেকটা লেয়ার কানেক্টেড থাকবে যেভাবে আমরা একটা থেকে আরেকটা লিস্ট করতে থাকবো। এখানে আমরা কেরাসের "সিকোয়েন্সিয়াল" ক্লাস ব্যবহার করছি।
কোরাসে নিউরাল নেটওয়ার্কগুলো ডিফাইন করা থাকে লেয়ারের সিকোয়েন্স হিসেবে। এই লেয়ারের কনটেইনার হচ্ছে "সিকোয়েন্সিয়াল" ক্লাস।
এই মডেলটার কিন্তু একটাই লেয়ার l0 ।
model = tf.keras.Sequential([l0])
আরেক ভাবেও করা যায়
আমরা যদি আগে থেকে মডেলকে ডিফাইন করি, তাহলে লেয়ারগুলোকে ভেতরে ফেলা যায়। এটা একটা ভালো প্রোগ্রামিং স্টাইল।
model = tf.keras.Sequential([ tf.keras.layers.Dense(units=1, input_shape=[1])])
মডেল কম্পাইলেশন, সঙ্গে থাকছে লস এবং অপটিমাইজার ফাংশন
ট্রেনিং এর আগে আমাদের মডেলকে কম্পাইল করে নিতে হবে। মডেলকে কম্পাইল করতে গেলে আমাদের নিচের দুটো ফাংশন কে ডিফাইন করতে হবে:
লস ফাংশন — এটা নিয়ে আমরা আগের বইতে আলাপ করেছিলাম। আমাদের যেটা আউটকাম আসার কথা সেখান থেকে প্রেডিকশন কত দূরে? আমাদের কাজ হচ্ছে এই দূরত্বটাকে ঠিকমতো মাপা। এই দুটোর মাঝখানে যে দূরত্ব সেটা কি আমরা লস বলছি। মনে আছে আমরা এর আগে কিভাবে 'মিন স্কোয়ারড এরর' বের করেছিলাম, আগের বইতে? অংকে।
অপটিমাইজার ফাংশন — আমাদের নিউরাল নেটওয়ার্কের যে ইন্টার্নাল ভ্যালুগুলো আছে সেগুলোকে কমিয়ে আনার জন্য এই ফাংশন।
এই ফাংশনগুলো সাধারণত ব্যবহার হয় ট্রেনিং এর সময়। দুটোর কাজ কিন্তু প্রাসঙ্গিক। প্রথমটার কাজ হচ্ছে প্রতিটা পয়েন্টে কত লস হচ্ছে সেটা বের করা, পরেরটা সেটাকে ধরে সেই লসকে কমিয়ে নিয়ে আসে। এই যে আমরা প্রতিটা পয়েন্টে লস ক্যালকুলেট করি, মানে ট্রেনিং ডেটার আসল ‘আউটকাম’ থেকে প্রেডিকশন কত দূরে আছে, আর সেই দুটোকে কমিয়ে নিয়ে আসতে যা কাজ করতে হয় এই দুটো ফাংশনকে - সেটাকে আমরা ট্রেনিং বলতে পারি।
আমাদের এই ট্রেনিং এর সময় "model.fit()" ‘অপটিমাইজার’ ফাংশন মডেলের যে ইন্টারনাল ভ্যারিয়েবলগুলো (ওয়েট) আছে সেগুলোর মধ্যে দূরত্বকে কমিয়ে আনার জন্য যা যা এডজাস্টমেন্ট দরকার সেগুলো করে সে। সে ততক্ষণ এই কাজ করতে থাকে (ওই ইন্টারনাল ভেরিয়েবলগুলোর মধ্যে যা যা এডজাস্টমেন্ট দরকার) যতক্ষণ পর্যন্ত আমাদের মডেলের ভেতরের আসল ইকুয়েশনের সমান না হয়। আমাদের ইকুয়েশন হচ্ছে ১৫ সেকেন্ডে ঝিঝি পোকার ডাকের সংখ্যার সাথে ওই সময়ের তাপমাত্রার একটা সম্পর্ক বের করা। এটা বের করতে পারলে আমাদের কাজ হাসিল।
আমরা এতক্ষণ যে ইন্টারনাল ভেরিয়েবলগুলোর কথা বললাম সেগুলো কিন্তু ইনপুট এর সাথে তার ‘করেসপন্ডিং’ ‘ওয়েট’। এগুলো নিয়ে আমরা নিউরাল নেটওয়ার্কের ‘পারসেপট্রন’ নিয়ে যখন আলাপ করব তখন বোঝা যাবে। আমাদের ডিপ লার্নিং ফ্রেমওয়ার্ক টেন্সর-ফ্লো এর ব্যাকএন্ডে কিছু বড় বড় অংকের অ্যানালাইসিস করে এই এডজাস্টমেন্ট টিউনিং করার জন্য। এর ব্যাকএন্ডে যে অংকটা আছে সেটাকে আমরা বলছি ‘গ্রেডিয়েন্ট ডিসেন্ট’। সেটা নিয়েও আলাপ করব সামনে।
আপনি যদি ভালোভাবে দেখেন আমাদের এখানে যে লস ফাংশন ব্যবহার করেছি সেটা হচ্ছে ‘মিন স্কোয়ারড এরর’। সাইকিট-লার্ন বইটাতে এটা নিয়ে বেশ বড় একটা অংক করেছিলাম। পাশাপাশি ‘অপটিমাইজার’ এর ক্ষেত্রে ‘অ্যাডাম’ ব্যবহার করেছি যা আসলে এ ধরনের মডেলের জন্য ভালোভাবেই কাজ করে। এটা একটা লেটেস্ট ট্রেন্ড, সুন্দর কাজ করে। ‘অ্যাডাম’ মানে এডাপ্টিভ মোমেন্ট এস্টিমেশন। তবে এছাড়াও আমরা অন্যান্য প্যারামিটারগুলো নিয়েও সামনে আলাপ করব।
‘অপটিমাইজার’ এর ভেতরের আরেকটা অংশ নিয়ে এখনই আলাপ করলে ব্যাপারটা সামনে সহজ হয়ে যাবে। এখানে দেখুন আমরা 0.1 যে সংখ্যাটা ব্যবহার করেছি, সেটা আসলে ‘লার্নিং রেট’। কি হারে মডেল শিখছে। এটা মডেলের ভেতরে যখন ইন্টারনাল ভেরিয়েবল বা ওয়েট নিজেদের মধ্যে এডজাস্ট করে সেটা একটা স্টেপ সাইজ ধরে করে। হাটিহাটি পা পা করে। পাহাড় থেকে নামার মতো। এই সংখ্যাটা যদি খুব কম হয় তাহলে একটা মডেল ট্রেইন করতে অনেক বেশি ‘আইটারেশন’ লাগবে। আবার সংখ্যাটা বড় হলে মডেলের অ্যাক্যুরেসি কমে যাবে। তাহলে মধ্য়পন্থা। হাতে কলমের একটা বড় মজা হচ্ছে হাইপার প্যারামিটারগুলোকে টিউন করার জন্য আমাদের ভ্যালুগুলো দিয়ে কিছুটা ট্রায়াল দিতে হবে। তবে ইন্ডাস্ট্রি স্ট্যান্ডার্ড অনুযায়ী এটার একটা ডিফল্ট ভ্যালু আছে যা ০.০০১ থেকে ০.১ পর্যন্ত ভালো কাজ করে।
মডেলের ট্রেনিং
Scikit-learn এর মত এখানেও আমরা মডেলকে ট্রেইন করবো ফিট "fit" মেথডকে কল করে। ট্রেনিং এর সময় আমাদের মডেল ১৫ সেকেন্ডের ঝিঁঝিঁ পোকার ডাক এর সংখ্যার সাথে বর্তমান যে ইন্টার্নাল ভেরিয়েবলগুলো আছে (যাকে আমরা বলছি ওয়েট) তাদেরকে ব্যবহার করে এবং তার আউটপুট ভ্যালু যেটাকে আমরা বলছি বর্তমান তাপমাত্রা - এ দুটোর মধ্যে একটা ক্যালকুলেশন করে এদের মধ্যে রিলেশনশিপ এডজাস্ট করতে থাকে। যেহেতু শুরুতেই এই ওয়েটগুলোকে দৈব চয়নের ভিত্তিতে সেট করা হয় সে কারণে শুরুর দিকে তাদের আউটপুট আসল ভ্যালুর কাছাকাছি না আসার সম্ভাবনা বেশি। সে কারণে আমাদের যে আসল আউটপুট (ট্রেনিং ডেটা থেকে) আর যে আউটপুটটা এখন ক্যালকুলেট করা হলো লস ফাংশন দিয়ে, সেটাকে অপটিমাইজার ফাংশন পই পই করে বলে দেয় কিভাবে ওয়েটগুলোকে এডজাস্ট করবে সামনে।
এই পুরো ব্যাপারটা মানে পুরো সাইকেলকে আমরা বলছি ১. একটা ক্যালকুলেশন, ২. তার সঙ্গে মিলিয়ে দেখা, ৩. এর পাশাপাশি ওয়েটগুলোর যে এডজাস্টমেন্ট এই তিনটা জিনিসকে ম্যানেজ করে আমাদের এই ফিট মেথড। Scikit-learn এর মত একই ধরনের আর্গুমেন্ট তবে সঙ্গে আরো কয়েকটা এলিমেন্ট এসেছে নতুন করে। আমাদের প্রথম আর্গুমেন্ট হচ্ছে ইনপুট আর পরের আর্গুমেন্টটা হচ্ছে আমরা যেটা পেতে চাই। একদম scikit-learn। এরপরের আর্গুমেন্ট হচ্ছে ইপক (epochs), মানে পুরো ট্রেনিং ডাটা কতবার পুরোপুরি আগা থেকে গোড়া পর্যন্ত চালাবে, শেষে হচ্ছে ভার্বস (verbose) আর্গুমেন্ট যেটা নির্ধারণ করে আমাদের আউটপুটে বাড়তি ইনফরমেশন দিবে কি দিবেনা।
# X = chips_15s# y = temp_celsius# history = model.fit(chips_15s, temp_celsius, epochs=500, verbose=True)history = model.fit(X, y, epochs=500, verbose=True)
আমরা সামনের জুপিটার/কোলাব নোটবুকে আরো উদাহরণ দেখবো। ঘাবড়াবেন না।
ট্রেনিং এর সাথে লস কমানোর একটা ছবি
বরাবরের মতো ফিট মেথডটার আউটপুট একটা অবজেক্ট এ ফেরত পাঠাচ্ছি। এখানকার অবজেক্টের নাম বলছি হিস্ট্রি, সেটা যে কোন নামেই হতে পারে। এখন এই অবজেক্টকে ঠিকমতো প্লট করলে বোঝা যাবে প্রতিটা ট্রেনিং এর সাথে কিভাবে মডেলের লস কমে আসে। শুরুর দিকের বেশি লস - মানে হচ্ছে আমরা যে তাপমাত্রাকে প্রেডিক্ট করতে চাচ্ছি, তার থেকে ট্রেনিং ডাটাবেজে যে তাপমাত্রা আছে সেটা আসলে বেশি ছিল। বেশি ইপকের সাথে সাথে কমে এসেছে সেই লস এর মাত্রা।
আগের বইয়ের মত আমরা এখানে ‘ম্যাটপ্লটলিব’ লাইব্রেরি ব্যবহার করছি ডেটা ভিজুয়ালাইজেশন এর জন্য। ভালোভাবে লক্ষ্য করলেই বোঝা যাবে আমাদের মডেল শুরুতেই কিন্তু কমিয়ে নিয়েছে লসের মাত্রা, তবে মাঝে সেটা একটু কমে গিয়েছিল যার শেষের দিকে সেটা একদম শূন্যের কাছাকাছি চলে গিয়েছে। এর মানে হচ্ছে মডেলটা অনেকটাই ভালো পারফরম্যান্স দেবে।
import matplotlib.pyplot as pltplt.xlabel('Epoch Number')plt.ylabel("Loss Level")plt.plot(history.history['loss'])
[<matplotlib.lines.Line2D at 0x7f8efbd80748>]
মডেলকে দিয়ে প্রেডিক্ট করাই তাপমাত্রা
আমাদের হাতে চলে এলো এমন একটা মডেল যাকে ট্রেইন করা হয়েছে আমাদের ১৫ সেকেন্ডের ঝিঁঝিঁপোকার ডাকের সংখ্যার সাথে তার করেসপন্ডিং তাপমাত্রা। তাহলে তো আমরা একটা অজানা ১৫ সেকেন্ডের ঝিঁঝিঁ পোকার ডাক এর সংখ্যা দিলে মডেল বলে দিতে পারবে ওই মুহূর্তের তাপমাত্রা। ভুল বললাম?
আমাদেরকে দেখতে হবে কোন ডাটাটা সেই ৫৫টা রেকর্ড এর মধ্যে নেই।
৩৪, মানে ১৫ সেকেন্ডের ঝিঁঝিঁপোকার ডাকের সংখ্যা = ৩৪
এখন প্রেডিক্ট করতে হবে ওই সময়ে তাপমাত্রা কতো ছিলো? পারবোনা?
print(model.predict([34]))
[[21.205147]]
এর আসল উত্তর হবে $34 \times 0.49543811976 + 4.45863851637 = 21.303534$, এর মানে হচ্ছে আমাদের মডেল একদম প্রায় মিলিয়ে দিয়েছে।
আমাদের মডেল ডেন্স লেয়ারে ইন্টারনাল ভ্যারিয়েবল (ওয়েট)গুলোকে সেভাবেই টিউন করেছে যাতে ঠিক তাপমাত্রাটা বলতে পারে যদি কেউ ১৫ সেকেন্ডের ওই সময়ের ঝিঁঝিঁপোকার ডাকের সংখ্যা দিতে পারেন।
তাহলে ফর্মুলা কোথায়?
আমরা অনেক্ষন ডেন্স লেয়ারের ভেতর ইন্টারনাল ভ্যারিয়েবলের কথা বলেছি। সেটা কি খালি চোখে দেখা যাবে না? অবশ্যই যাবে।
কেরাসের লেয়ারের_নাম.get_weights() দিলেই চলে আসবে নামপাই অ্যারের লিস্ট হিসেবে।
আমাদের প্রথম ভ্যারিয়েবল m হচ্ছে ~0.4954 আর পরেরটা মানে b হচ্ছে ~4.4586. এর অর্থ হচ্ছে আমাদের মেশিন লার্নিং মডেল ইনপুট ডেটা থেকে ফর্মুলা বের করে ফেলেছে। এটাই চাইছিলাম আমরা। যেহেতু এটা মাত্র একটা লেয়ার, একটা নিউরন - সেকারণে এর আউটকাম এসেছে একটা লাইনের ইকুয়েশনের মতো।