রিকারেন্ট নিউরাল নেটওয়ার্কসের গল্প
ছবিতে বিকালের নাস্তা এবং কিছু অংক
প্রতিবারই গল্পের বই লিখতে শুরু করলে সেটা কিভাবে যেন টেকনিক্যাল বই হয়ে যায়। আমার ধারণা, হয়তোবা গল্পের শেষমেষ (শেষ হয়ে হইল না শেষ - রবীন্দ্রনাথ ও ছোটগল্পের ধারণা) মেলানো কঠিন বলেই সেটাকে টেকনিক্যাল দিকে মোড় নেওয়া সহজ। আজকের গল্প আমার স্ত্রী এবং বাচ্চাদের নিয়ে - যারা আমার জীবনের ‘রিকারেন্ট নিউরাল নেটওয়ার্কস’। যাদের ইনপুট আমার আজকের আউটপুট।
‘স্বাতী’ চমৎকারভাবে বিকালের নাস্তা তৈরি করে বাচ্চাদের জন্য। আমিও সামিল হই মাঝে মাঝে। বিশেষ করে, অফিস থেকে আগে ফিরতে পারলে। প্রতিদিনের নাস্তা, তবে একেক দিন একেক রকম। আর, সেটা তিন ধরনের আইটেমের মধ্যেই সীমাবদ্ধ। একদিন লুচি এবং আলুর দম। আলুটা কেমন করে যেন মুখে দেওয়ার আগেই গলে যায়। লিখতে লিখতেই এখনই জিভে জল চলে আসছে। পরের দিন - সালাদ খিচুড়ি। খিচুড়ির মধ্যে সামান্য জল বেশি, সঙ্গে কিছু সবজি। তার উপর দিয়ে সালাদের টপ-আপ। গন্ধে পুরো বাসা মৌ মৌ করতে থাকে। তার পরের দিন ব্রেড দিয়ে পিজা। সাধারণ পাউরুটির উপর টমেটো, ক্যাপসিকাম, ইত্যাদি তবে ‘মোজারেলা চিজ’ দিয়ে গ্রিল করা। বাসার পিজা বলে তার স্টাইলই আলাদা। ছবিতে লেখার সুবিধার্থে আমরা এই তিনটা আইটেমকে লিখব “লুচি”, “খিচুড়ি” এবং “পিজা”।
তবে, স্বাতী কোন দিন কোনটা রান্না করবে সেটার পেছনে একটা ছোটখাটো ‘রুল’ আছে। বাসার একটা নিয়ম নীতি আছে না? যেদিন আকাশে মেঘ অথবা বৃষ্টির একটু ভাব আছে সেদিন সে ‘সালাদ-খিচুড়ি’ রান্না করে। অন্যান্য রোদ্দুরস্নাত দিনে ‘লুচি-দম’ই সই। এই রুলের ধারণা থেকে আমরা একটা ‘নিউরাল নেটওয়ার্ক’ তৈরি দিতে পারি। আমার আগের ‘হাতেকলমে পাইথন ডিপ লার্নিং’ বইটাতে ‘নিউরাল নেটওয়ার্ক’ এবং তার ‘রি-প্রেজেন্টেশন’ নিয়ে অনেক আলাপ করেছি। বই না থাকলে নেই, বইয়ের সবই অনলাইনে আছে।
যেকোনো নিউরাল নেটওয়ার্কের মত এই নতুন নেটওয়ার্কেও একটা ইনপুট এবং একটা আউটপুট আছে। এখানে ইনপুট ‘রৌদ্রস্নাত দিন’ হলে আউটপুট হচ্ছে ‘লুচি’ আইটেম। তেমনি, বৃষ্টির দিন ইনপুট হলে আউটপুট হবে ‘খিচুড়ি’। এই রুলগুলোকে অংকে নিয়ে আসতে চাইলে কি করা যায়? ঠিক ধরেছেন, যন্ত্র তো আর খাবারের আইটেম অথবা রোদ-বৃষ্টি বুঝবে না, তাদের জন্য তৈরি করতে হবে ভেক্টর। এখন প্রশ্ন আসতে পারে ‘ভেক্টর’ কি?
ভেক্টর এবং ‘ওয়ান হট’ শব্দ রিপ্রেজেন্টেশন
কম্পিউটার যেহেতু সরাসরি ভাষা বোঝে না, সে কারণে তাকে হাতেকলমে বুঝিয়ে দিতে হবে কোনটা কি খাবারের আইটেম অথবা কাকে ‘রোদ’ অথবা কাকে ‘বৃষ্টি’ বলা যায়। শুধুমাত্র সংখ্যা দিয়ে এগুলো বোঝানো যেতে পারে তবে সেখানে কিছু উদ্ভাবনা নিয়ে আসলে যন্ত্রের জন্য ব্যাপারটা বুঝতে সুবিধা হয়। সরাসরি বললে ভেক্টর হচ্ছে কিছু সংখ্যার লিস্ট যা দিয়ে যেকোনো শব্দকে ‘রিপ্রেজেন্ট’ করা যায়। আমরা এমন একটা ফরম্যাট তৈরি করে দেব যাতে কম্পিউটার এই সংখ্যার লিস্টগুলোকে স্ট্যাটিসটিক্যাল মডেলের জন্য ‘কম্পিউট’ করতে পারে। ভাষার প্রতিটি শব্দই সংখ্যার লিস্ট হয়ে কম্পিউটারে যায় অ্যালগরিদমের ঢোকার আগে। কম্পিউটার এই তিনটা আইটেমকে কিভাবে বুঝতে পারে সেটার একটা ছবি দেখি বামে। শুরুর ছবিটা।
একটা ভোকাবুলারি, তিনটা শব্দ। আমরা শুধুমাত্র সংখ্যা ০ এবং ১ দিয়ে রিপ্রেজেন্ট করতে গেলে আমাদের তিনটা শব্দের ভেক্টরকে যদি ভোকাবুলারির পুরো লেনথ ধরি, তাহলে এর প্রতিটা ‘অবজারভেশন’কে (মনে আছে ‘শুন্য থেকে পাইথন মেশিন লার্নিং’ বইটার কথা?) একটা ম্যাট্রিক্সে রিপ্রেজেন্ট করলে যেখানে সারির সংখ্যা = ভোকাবুলারির লেনথ এবং কলাম = রেকর্ড অর্থাৎ অবজারভেশনের লেনথ হলে যেখানে যেই ভোকাবুলারির শব্দটা থাকবে সেখানে সংখ্যা ১ বসিয়ে বাকিটা সংখ্যা ০ বসিয়ে দিলে যন্ত্র বুঝতে পারবে। শুধুমাত্র এই ১ এবং ০ এর ব্যবহার করে এভাবে ভাষার শব্দগুলোকে রিপ্রেজেন্ট করা যায়। একে আমরা ‘ওয়ান হট’ শব্দ রিপ্রেজেন্টেশন বলি। এই ‘এনকোডারে’র কাজ দেখবেন সামনে।
ভেক্টরের কাজ হচ্ছে আমাদের এই খাবারের সাথে দুটো আবহাওয়ার ভ্যারিয়েশনগুলোকে একটা ‘ম্যাপ’ করে দেওয়া - যাতে কম্পিউটার সেই সংখ্যার লিস্ট এর মধ্যে সংখ্যা ১ এর প্লেসমেন্টের ভ্যারিয়েশন থেকে ওই আইটেমটাকে চিনতে পারবে। আমাদের ভাষার মধ্যে প্রতিটা শব্দকে এ ধরনের সংখ্যার লিস্ট দিয়ে ওয়ার্ড এমবেডিং অর্থাৎ শব্দের এমবেডিং তৈরি করা যায়। উপরের ডানের ছবিটা দেখুন। আমরা যেহেতু ভেক্টর দিয়ে শুরু করেছি - এই তিনটা শব্দের ভেক্টরগুলো হচ্ছে, লুচি [১, ০, ০], খিচুড়ি [০, ১, ০] এবং পিজা [০, ০, ১]।
এটা একটা ‘এন’ সংখ্যক ডাইমেনশন যার মাধ্যমে যন্ত্র সেই শব্দটার অর্থ এবং কন্টেক্সট জানতে পারবে সংখ্যার বিভিন্ন প্লেসমেন্ট দিয়ে। ওই এম্বেডিং এ প্রতিটা শব্দ ইউনিক হবে যাতে এক একটা শব্দ থেকে আরেকটা শব্দ কতো কাছে বা দুরে সেটা বোঝা যায়। যন্ত্রের ভাষায় এই একেকটা শব্দের জন্য শব্দের এম্বেডিং ওই শব্দটার অর্থ বের করার চেষ্টা করে তার আশেপাশের অন্যান্য শব্দের কাছাকাছি অথবা দূরের ধারণা থেকে।
২ নম্বর ছবিটা আবার দেখুন। এখানে আমরা একটু উল্টা পথে হাঁটবো। শুরুতে একটা ‘ওয়ান হট’ এনকোডিং তৈরি করে সেখান থেকে ভেক্টর গুলোকে আলাদা করব। ৩ নম্বর ছবিটা দেখুন।
আমাদের এখানে যেহেতু তিন ধরনের নাস্তার কথা বলছি সে কারণে এর ভেতরের লেন্থ হবে ৩। এর পাশাপাশি আবহাওয়ার জন্য দুটি ভেক্টর যার লেন্থ হচ্ছে ২। ফলে কম্বিনেশন ১, ০ এবং ০, ১। একটা সাধারণ নিউরাল নেটওয়ার্ক দেখি। একটা ইনপুট একটা আউটপুট। মাঝে নিউরাল নোড।
আমাদের নিউরাল নেটওয়ার্ককে যখন ইনপুট হিসেবে [১, ০] (রৌদ্রস্নাত দিন) ঢুকবে তখন তার আউটপুট হবে ভেক্টর ১, ০, ০ যার অর্থ হচ্ছে ‘লুচি’। ঐদিন লুচি রান্না করবে স্বাতী। আবার যেদিন বৃষ্টির দিন (ভেক্টর ০, ১) পড়বে ইনপুটে সেখানে আউটপুট ভেক্টর হিসেবে বের হবে [০, ১, ০] অর্থাৎ খিচুড়ি।
নিউরাল নেটওয়ার্ক এবং ম্যাট্রিক্স মাল্টিপ্লিকেশন
নিউরাল নেটওয়ার্কে এই কাজটি কিভাবে হবে? সোজা উত্তর, ম্যাট্রিক্স মাল্টিপ্লিকেশন। স্কুলে করে এসেছি আমরা। মনে না থাকলেও সমস্যা নেই। ইনপুট থেকে আউটপুট বুঝলেই হলো। তবে, ভেতরে ঢুকতে চাইলে ম্যাট্রিক্স মাল্টিপ্লিকেশন নিয়ে খান একাডেমির অসাধারণ কিছু ভিডিও দেখতে পারেন। আসল কথা হচ্ছে - মেশিন লার্নিংয়ের ভেতরে সব অংক। সেই বেসিক অংকগুলো দেখতে 'শুন্য থেকে পাইথন মেশিন লার্নিং' বইটা দেখতে পারেন।
একটা পরিস্থিতিকে আমরা উপরের ৭ নম্বর ছবিতে প্লট করি। একপাশে আমরা রাখছি রৌদ্রস্নাত দিন এবং বৃষ্টি দিনের ভেক্টর। তার সামনে রাখছি দুটো খাবারের ভেক্টর, পাশাপাশি। আমরা খাবারের ভেক্টরের সাথে যখন রৌদ্রস্নাত দিনের ভেক্টরকে ‘ম্যাট্রিক্স মাল্টিপ্লিকেশন’ করি তখন তার ফলাফল হয় যেই ভেক্টর হয় সেটার ‘করেসপন্ডিং’ নাস্তার আইটেম হচ্ছে লুচি। ৮ নম্বর ছবি দেখুন।
এরপরের ভেক্টর [০, ১] যেটা বৃষ্টির দিন তাকে খাবারের ভেক্টরের সাথে ‘ম্যাট্রিক্স মাল্টিপ্লিকেশন’ করলে তার ফলাফল আসে [০, ১, ০] খিচুড়ি।
এই ফলাফল দুটোকে আমরা ছবিতে প্লট করলে দেখব রোদ্দুরের ভেক্টরের সাথে লুচির ভেক্টর এবং বৃস্টির সাথে খিচুড়ির ভেক্টরের একটা ‘লিনিয়ার’ সম্পর্ক আছে। এখন পরের নিউরাল নেটওয়ার্কের ভেতরের ছবি নিয়ে কথা বলি।
নিউরাল নেটওয়ার্ক নোড এবং এজ (লিংক), [যার ভ্যালু 'ওয়েট']
এখন এই জিনিসগুলোকে নিউরাল নেটওয়ার্কের ‘ম্যাট্রিক্সে’ প্লট না করে 'নোড' এবং 'ওয়েট' ধরে আগাই। বামের ম্যাট্রিক্সটাকে ডানের নিউরাল নেটওয়ার্ক ডায়াগ্রামে প্লট করি। এখানে দু'ধরনের ‘অ্যারো’ অর্থাৎ তীর চিহ্ন আছে। কালো রঙ্গের লেবেল হচ্ছে ১ আর হালকা রঙের তীর চিহ্ন এর লেবেলের মান হচ্ছে ০। এগুলো 'ওয়েট' অর্থাৎ একটা ভ্যালু দেয়া আছে।
এখন রৌদ্রস্নাত দিনের [১, ০] ভেক্টরকে সরাসরি নিউরাল নেটওয়ার্কের প্রথম নোডের লেয়ারে বসিয়ে দিলে যেটা ‘এজ’ অর্থাৎ শেষাংশ (ওয়েট) সাথে ম্যাট্রিক্সের ‘গুন’ হয়ে তার ফলাফল পাওয়া যাবে পরের তিন নিউরনের লেয়ারে। এটাই ‘ম্যাট্রিক্স মাল্টিপ্লিকেশন’। এখানে ফলাফল হিসেবে ভেক্টর [১, ০, ০] পাচ্ছি যার করেসপন্ডিং নাস্তা হচ্ছে লুচি।
আচ্ছা, বৃষ্টির ভেক্টরে কী নাস্তা হতে পারে? নিজেই করে ফেলি। আগের মতো আমরা বৃষ্টির দিনের ভেক্টর [০, ১] প্রথম লেয়ারের নোডে বসলে তার ফলাফল আসবে [০, ১, ০] যেটাকে আমরা বলছি খিচুড়ি।
‘সিকোয়েন্স’ ধরে কাজ - আউটপুট আসছে ইনপুটে
এর মধ্যেই কোভিড-১৯ মহামারী চলে এলো। সেই লকডাউনে অল্প করে বিকালের নাস্তা বানানোর প্রস্তাবনা দিল স্বাতী। একই ধরনের নাস্তা থাকবে, তবে সেটার পরিমাণ হয়তোবা কিছুটা কমবে বাজারের ওপর নির্ভর করে। তবে সেটাকে আবহাওয়ার সাথে সংযুক্ত না করে বিকেলের নাস্তাগুলোকে ‘সিকোয়েন্স’ আকারে রান্না করবে স্বাতী।
প্রথম দিন লুচি রান্না হলে পরের দিন খিচুড়ি। খিচুড়ি যেদিন রান্না হবে তার পরের দিন রান্না হবে পিজা। পিজার পরের দিন আবার ফিরে আসবে লুচিতে। এতে কোন দিন কোন আইটেমটা রান্না হবে সেটার পেডিকসন করতে আমার এবং বাচ্চাদের সমস্যা হবে না কারণ আমরা দেখে নেব এর আগের দিন কোনটা রান্না হয়েছিল। আমরা এটাকে ওপরে ছবি দিয়ে প্লট করে দেখিয়েছি।
এখন ধারণা করি, সপ্তাহের কোন দিন কোন আইটেমটা রান্না হতে পারে। যদি সপ্তাহের শুরুটা রবিবার দিয়ে হয় তাহলে উপরের ছবিটা দেখতে পারেন। রবিবার লুচি, সোমবার খিচুড়ি, মঙ্গলবার পিজা, বুধবার আবার লুচি, বৃহস্পতিবার খিচুড়ি, শুক্রবার আবারও পিজা, শনিবার আবার লুচি। এভাবেই চলতে থাকবে যতক্ষণ নতুন কোন রুল না আসে।
এমুহুর্তে আমরা যে অবস্থায় চলে এলাম, সেটা সাধারণ নিউরাল নেটওয়ার্ক দিয়ে সমাধান করা সম্ভব নয়। এখানে নিচের ইনপুটে আবহাওয়ার তথ্য আর দিচ্ছি না, তবে প্রতিদিনের আউটপুট এসে ঢুকেছে তারপরের দিনের ইনপুট হিসেবে। সরাসরি বললে আউটপুট ঘুরে চলে আসছে ইনপুটে। এই ধারণাটাই ‘রিকারেন্ট’, বার বার আউটপুট ফিরে আসছে ইনপুটে। এই ধারণা নিয়ে তৈরি করা হয়েছে নতুন ধরনের নিউরাল নেটওয়ার্ক।
গতকালকের বিকালের নাস্তা যদি লুচি হয় সেটা আজকের রান্নার ইনপুট ঢুকলে তার আউটপুট বের হবে খিচুড়ি দিয়ে। আজকে সাথী যদি খিচুড়ি রান্না করে তাহলে সেটার আউটপুট পরেরদিনের ইনপুট ঢুকলে সেটা আউটপুট হিসেবে কালকে রান্না করবে পিজা। এই নতুন ধারণায় আমাদের নতুন নিউরাল নেটওয়ার্কটা এরকম হতে পারে ছবিতে। যাকে আমরা বলছি, ‘রিকারেন্ট নিউরাল নেটওয়ার্কস’ অর্থাৎ ‘আরএনএন’।
ছবি ১৯, এখানে ইনপুট হচ্ছে আগের দিনের ঘটনার আউটপুট। ছবি ২০, মনে আছে তো আমাদের তিনটা নাস্তার ভেক্টরের কথা? দেখে নেই ছবিতে।
চলুন তৈরি করি আমাদের নতুন, তবে অতি সাধারন একটা ‘রেকারেন্ট নিউরাল নেটওয়ার্কস’। দেখুন নতুন একটা ম্যাট্রিক্স ছবি ২১এ। আমরা একে যদি লুচির ভেক্টর দিয়ে ‘মাল্টিপ্লিকেশন’ করি তাহলে যেই ভেক্টরটা পাবো সেই ভেক্টরের করেসপন্ডিং নাস্তার আইটেম হচ্ছে খিচুড়ি। এই ম্যাট্রিক্সের সাথে খিচুড়ি ভেক্টরকে গুণ করলে চলে আসবে পিজা’র ভেক্টর।
আবার, এই ম্যাট্রিক্সের সাথে পিজার ভেক্টরকে গুণ অর্থাৎ মাল্টিপ্লিকেশন করলে তার ফলাফল আসবে সেই আগের লুচির ভেক্টর। এই নিউরাল নেটওয়ার্কের নতুন ম্যাপিং দেখলে বোঝা যাবে লুচিকে ‘ম্যাপ’ করা হয়েছে খিচুড়ির সাথে। খিচুড়িকে ‘ম্যাপ’ করা হয়েছে পিজার সাথে। সবশেষে পিজাকে ‘ম্যাপ’ করা হয়েছে লুচির সাথে। নিচের ২৫ নম্বর ছবি দেখুন।
এখন, আমরা এই ম্যাট্রিক্সকে নিউরাল নেটওয়ার্কের ডায়াগ্রামের মতো করে যেখানে ‘নোড’ এবং ‘এজ’ অর্থাৎ তীর চিহ্ন ‘শেষাংশ’ (এটা লাগবে ওয়েটের জন্য) থাকে, তাহলে সেটাকে উপরের ২৬ নম্বর ছবির মত করে তৈরি করা যায়। এটাকে আমরা নিজে থেকে তৈরি করছি না, বরং পাশের নাস্তার আইটেমগুলোর ম্যাপিং থেকে এই ডায়াগ্রামটি তৈরি করা হয়েছে। এখানে আমরা শুধুমাত্র সংখ্যা ১ এর তীর চিহ্নগুলোকে টেনেছি।
এখানে আমরা লুচির ভেক্টরকে নিউরাল নেটওয়ার্কের প্রথম লেয়ারে নোডগুলোতে বসিয়ে দেই তাহলে তার ‘ম্যাট্রিক্স মাল্টিপ্লিকেশন’ এর উত্তর আসবে [০, ১, ০]। এই উত্তরটা যেই ভেক্টরের সাথে ‘এসোসিয়েটেড’ সেটা হচ্ছে খিচুড়ি।
এর অর্থ হচ্ছে, আমরা এই নিউরাল নেটওয়ার্কের ইনপুটে যেই নাস্তার আইটেম ভেক্টর বসাবো, সেটার ফলাফল আসবে তার পরের দিনের নাস্তার আইটেমের ভেক্টর। এখানে যেটা বোঝা যাচ্ছে আমরা যেটাকেই ইনপুট দিচ্ছি না কেন, সেটাকে তার পরের দিনের নাস্তার আইটেম হিসেবে আউটপুট হয়ে আবার সেটা ইনপুটে যাচ্ছে। প্রতিটা আউটপুট ভেক্টর আবার নতুন করে ‘ফিড’ করছে ইনপুট নোডে। এজন্যই এর নাম ‘রিকারেন্ট’ অর্থাৎ একই জিনিস ফিরে আসছে বারবার। উপরের ছবিটা দেখেই বুঝতে পারছেন পুরো ধারণাটা।
ইনপুট থেকে আউটপুট, আবহাওয়ার নতুন ইনপুট
এই মহামারীর মধ্যেই আমাদের ছাদ এবং বারান্দা মিলিয়ে তৈরি হল নতুন বাগান। স্বাতী, যিনি একাধারে প্রথিতযশা ব্যাংকার, হোম-অফিস এবং আসল অফিস মিলিয়ে সেই বাগানের পরিচর্যায় সময় বের করতে পারছিলো না কিছুদিন ধরে।আর তাই বের করতে হলো নতুন নিয়ম। সে এখনো আগের সিকোয়েন্সে রান্না করছে তবে, আবহাওয়ার ব্যাপারে নতুন কিছু ‘টুইকিং’ নিয়ে এসেছে।
যেদিন রৌদ্রস্নাত দিন, ঐদিন হোম-অফিসের পাশাপাশি - স্বাতী তার বাগান পরিচর্যায় সময় দেবে বেশি। ফলে, ঝামেলা কমাতে আগের দিনের একই মেনু নিয়ে আসবে পরের দিন। আর বৃষ্টির দিন, যেহেতু ছাদে বাগান পরিচর্যায় সমস্যা, তখন স্বাতী সিকোয়েন্সের পরের দিনের মেনু আমাদেরকে খাওয়াবে। এটাকে যদি ছবিতে প্লট করি, তাহলে এরকম হতে পারে।
স্বাতী যদি রবিবারে বিকেলের নাস্তা হিসেবে লুচি তৈরি করে, এবং সোমবার সকালে যদি রোদ থাকে, তাহলে সে চলে যাবে বাগান পরিচর্যায়। সময় বাঁচাতে নতুন নাস্তা তৈরি না করে আগের দিনের নাস্তার কিছু অংশ এবং আরো কিছু অংশ দিয়ে তৈরি করে দেবে সেই একই লুচি। মঙ্গলবার সকালে যদি ঘনঘটা বৃষ্টি শুরু হয়, তখন ও আর ছাদে বাগানে যেতে পারবে না। এর অর্থ হচ্ছে, মঙ্গলবারে সিকোয়েন্স অনুযায়ী সে ‘খিচুড়ি’ রান্না করবে। বুধবার সকালেও যদি সেই বৃষ্টি চলতে থাকে - তাহলে সে সিকোয়েন্সে তারপরের নাস্তা অর্থাৎ পিজা বানিয়ে দেবে। এভাবে সে আবহাওয়ার ইনপুটের উপর ভিত্তি করে আগের দিনে মেনু অথবা নতুন নাস্তা তৈরি করবে।
এই ধারণা থেকে আমাদের রিকারেন্ট নিউরাল নেটওয়ার্কের ছবিটা এরকম হতে পারে। আগের ছবির সাথে নিচে নতুন একটা ইনপুট যোগ হয়েছে যা আসছে আবহাওয়ার উপর ভিত্তি করে। দুটো ইনপুট এখন থেকে।
উপরের ছবিতে বুঝতে পারছেন - আউটপুটের নাস্তার আইটেম ফিরে আসছে ইনপুট হিসেবে। এখানে যদি গতকালকের নাস্তা হয় লুচি এবং আজকে নিচের ইনপুট হিসাবে বৃষ্টি যোগ হয়, তাহলে নাস্তার ইনপুট লুচি এবং আবহাওয়ার ইনপুট বৃষ্টি যোগ হয়ে আউটপুট আসবে খিচুড়ি। যেহেতু আবহাওয়ার ইনপুট বৃষ্টি, স্বাতী যেতে পারছে না বাইরে, সে কারণে সিকোয়েন্স অনুযায়ী সে রান্না করছে পরের নাস্তার আইটেম।
নিউরাল নেটওয়ার্কে নন-লিনিয়ার ফাংশন
এখন ফিরে আসি, আমাদের নাস্তার আইটেম এবং আবহাওয়ার ভেক্টরগুলোতে। মনে আছে তো? আবারও দেখি, নাস্তার আইটেম এবং আবহাওয়ার ম্যাট্রিক্স। আমরা এই দুটো ম্যাট্রিক্সকে যোগ করে শেষে জোড়া লাগিয়ে দিচ্ছি নিউরাল নেটওয়ার্কে নন-লিনিয়ার ফাংশন হিসেবে। আমার ‘হাতেকলমে পাইথন ডিপ লার্নিং’ বইয়ে এই নন-লিনিয়ার ফাংশন নিয়ে বেশ বড় ধারণা দেওয়া আছে। এখানে দেখানোর সময় ব্যাপারটা বুঝে যাবেন।
চলুন, শুরু করা যাক নাস্তার আইটেম এর ম্যাট্রিক্স দিয়ে। এটা ৩ x ৬ এর ম্যাট্রিক্স। তবে, এটাকে কেটে ছোট করে ফেলা হয়েছে ২ টা ৩ x ৩ দিয়ে। ৪১ নম্বর ছবির মতো আমরা নাস্তার আইটেমের ম্যাট্রিক্স এর সাথে লুচির ভেক্টরকে গুন করি, তাহলে ফলাফল হিসেবে দুটি ভেক্টরের একটা জোড়া অর্থাৎ সংযোগ পাব। এর মধ্যে উপরের ভেক্টরটা [১, ০, ০] লুচির, কারণ ম্যাট্রিক্সের উপরের তিনটা সারি হচ্ছে ‘আইডেন্টিটি ম্যাট্রিক্স’ এবং ম্যাট্রিক্স এর শেষের তিন সারি হচ্ছে পরের দিনের নাস্তা [০, ১, ০] যেটাকে খিচুড়ি বোঝা যাচ্ছে।
এটারই আরেকটা উদাহরণ দেখি এখানে। আমাদের এই নাস্তার আইটেম এর ম্যাট্রিক্স এর সাথে খিচুড়ির [০, ১, ০] ভেক্টরকে গুন করি তাহলে যেই সংযোগ ভেক্টর পাবো, যার উপরের অংশ একই দিনের নাস্তা থাকবে অর্থাৎ খিচুড়ি [০, ১, ০] এবং নিচের ভেক্টর হিসেবে আসবে এর পরের দিনের নাস্তার আইটেম যেটা পিজা [০, ০, ১]। এভাবে, পিজার নাস্তার আইটেম দিয়ে গুণ করলে নিচের ছবির মত ফলাফল আসতে পারে।
তাহলে, আমাদের নাস্তার আইটেম এর মেট্রিক্স দিয়ে কি করছি এখানে? এই ম্যাট্রিক্সটা আজকের নাস্তার আইটেমটাকে ইনপুট হিসেবে নিয়ে তার ফলাফল হিসেবে আজকের নাস্তার আইটেম এবং পরবর্তী দিনের নাস্তার আইটেম দেখাচ্ছে সংযোগ ভেক্টরে।
এখন ফিরে আসি আবহাওয়ার ম্যাট্রিক্সে। এই আবহাওয়ার ম্যাট্রিক্সটা নাস্তার আইটেম এর মতই একটা সংযোগ ম্যাট্রিক্স যার মধ্যে প্রথম ম্যাট্রিক্সের শুরুর কলামে সবগুলো ১ এবং দ্বিতীয় ম্যাট্রিক্সের শেষের কলামের সবগুলো ১।
এখন নিচের ৪৭ নম্বর ছবিটা দেখুন, এই আবহাওয়ার ম্যাট্রিক্সের সাথে বৃষ্টির দিনের ভেক্টরের [০, ১] গুণফল। এর ফলাফল হিসেবে পাচ্ছি আমরা দুটো ভেক্টর, যার উপরদিকে সবগুলো ০ এবং নিচের ভেক্টরের সবগুলো ১। এই উপরের ভেক্টরটা [০, ০, ০] আমাদের বলছে - এটা একই দিন অর্থাৎ ধরুন, রোদে ভরা দিন। সবগুলো ১ এর ভেক্টর আমাদেরকে বলছে এটা পরের দিন।
আবার, ০ দিয়ে ভরা নিচের ভেক্টর বলছে এটা পরের দিন অর্থাৎ এটা একটা বৃষ্টির দিন। এটা আগে থেকে ‘প্রিডিফাইন্ড’ ম্যাট্রিক্স থাকাতে এরকম হচ্ছে। ম্যাট্রিক্স পাল্টালে ফলাফল পাল্টাবে। এই আবহাওয়ার মেট্রিক সাথে আমরা বৃষ্টির দিনের ভেক্টরকে গুণ করলে আউটপুটের পাচ্ছি দুটো সংযোগ ভেক্টর, যার উপরেরটা সব ০ অর্থাৎ একই দিন রোদ্রের, আর নিচের সব ১ এর ভেক্টর বলছে পরের দিন [বৃষ্টি]র দিন হতে পারে। তবে, এখানে রোদ বৃষ্টির কথা নয়, আসল আউটপুট হচ্ছে - দুটো ‘স্টেট’ - অর্থাৎ একই দিনের নাস্তা এবং পরের দিনের নাস্তা, এই দুটো ‘স্টেট’ই হবে এখানে। এর অর্থ হচ্ছে আমাদেরকে আবহাওয়া ভেক্টর বলছে, এই দুটো ভেক্টরের ইনপুট নিয়ে স্বাতী কি আজকের নাস্তা তৈরি করবে নাকি সামনের দিনের নাস্তাটা বানাবে? ঝামেলা মনে হচ্ছে? তবে সেটা মিটে যাবে সামনের ফলাফলটা দেখলে।
মজার ব্যাপার হচ্ছে, আমরা যখন নাস্তার ম্যাট্রিক্স এবং আবহাওয়ার ম্যাট্রিক্সকে যোগ করব - তখন চমৎকার একটা ঘটনা ঘটবে। উপরের ডানের ৪৮ নম্বর ছবিটা দেখুন। এই যোগফলই আমাদেরকে জানিয়ে দেবে স্বাতীর করণীয় কি, বিশেষ করে আজকের এবং কালকে নাস্তা কি হবে? এতে স্বাতী বুঝতে পারবে - আজকের নাস্তা তৈরি করবে নাকি কালকের নাস্তা নিয়ে আসবে? ম্যাট্রিক্স দুটির যোগফল এখানে একটা ভালো ধারণা নিয়ে আসবে।
এটার উদাহরণ, গতকালকে স্বাতী বিকালের নাস্তা হিসেবে লুচি দিয়েছিল এবং আজকের সকাল থেকেই বৃষ্টি হচ্ছে। এখানে ছবিতে সেই ফলাফলটা এসছে নাস্তার মেট্রিক্স থেকে, যখন লুচির ভেক্টরের সাথে নাস্তা ম্যাট্রিক্স গুন করেছিলাম। ফলাফল, আজকের জন্য কোনটা নাস্তা এবং সামনে কোন নাস্তাটা রান্না হবে।
এর সাথে যোগ করতে চাচ্ছি আবহাওয়ার ম্যাট্রিক্স, যার মধ্যে একটা বৃষ্টির দিনের ভেক্টরের সাথে আবহাওয়ার ম্যাট্রিক্স গুণের ফলাফল। এদুটো ভেক্টরকে যোগ করলে (ছবি: ৫১) আমরা যে ফলাফলটা পাচ্ছি, সেখানে নিচের ভেক্টর অংশে সর্বোচ্চ সংখ্যা ২ এসেছে। এখানে দুইয়ের ফলাফল হচ্ছে পরের দিনের নাস্তা অর্থাৎ খিচুড়ি। কারণ, খিচুড়ির ভেক্টর হচ্ছে [০, ১, ০]। এখানে সর্বোচ্চ সংখ্যা ২ কে বের করে নিয়ে গেলে একটা সংযোগের ম্যাপ তৈরি হবে। এই ২ সংখ্যাকে বের করার জন্য আমাদেরকে উপরের ৫০ নম্বর ছবিটা দেখতে হবে। এটা একটা ‘নন-লিনিয়ার’ অপারেশন।
এখানে প্রথম অংশে বলা হচ্ছে, আজকে কোন নাস্তাটা বানানো হবে এবং সামনে কোনটা রান্না হতে পারে, এরপরের অংশে আমাদেরকে একটা ধারণা দিচ্ছে - দুটো অবস্থার মধ্য থেকে কোনটাকে আমরা বেছে নেব? আমরা কি সেদিনকেই বেছে নেবো নাকি সামনের দিনটাকে বেছে নেব? এই দুটো সিদ্ধান্তের যোগসূত্র থেকে আমরা বের করতে পারব - সামনের দিনে স্বাতী কি নাস্তা বানাবে?
‘নন-লিনিয়ার’ ফাংশন - ‘সিগময়েড’: সামনে পাঠাবে ১
এখানে সংযোগ ম্যাপে আমরা একটা ‘নন-লিনিয়ার’ ফাংশন ব্যবহার করব যা আলাপ করা হয়েছে আমার ‘হাতেকলমে পাইথন ডিপ লার্নিং’ বইটাতে। তবে ছোট করে যদি বলি, এই ‘নন-লিনিয়ার’ ফাংশনে ভেক্টরের সর্বোচ্চ মানটাকে নিয়ে ১ সংখ্যায় পাল্টে দিবে এবং ভেক্টরের বাকি সব ডাটাকে সংখ্যা ০ করে দেবে। ‘নন-লিনিয়ার’ ফাংশন হিসেবে আমরা ‘ওয়ান হট এনকোডিং’ এর কথা বলতে পারি, যেখানে ওই অংশটা ১ ব্যবহার করে বাকি সব এন্ট্রিগুলোকে ০ করে দেবে। ‘সিগময়েড’ এ সর্বোচ্চ অর্থাৎ ১ এর বেশি ইনফরমেশনকে সামনে এগোতে দিবে।
এই ‘নন-লিনিয়ার’ আউটপুটের উপরের এবং নিচের ভেক্টরকে বের করে এনে সরাসরি যোগ করে দেয়। ছবি ৫৪ দেখুন। এই ভেক্টরের যোগফলের যে আউটপুট ভেক্টর যা [০, ১, ০] যার করেসপন্ডিং নাস্তার আইটেম হচ্ছে খিচুড়ি। এর অর্থ হচ্ছে ,আমরা যদি ইনপুট হিসেবে নাস্তার আইটেম লুচি এবং বৃষ্টির দিন এই নেটওয়ার্ক দিয়ে ঢুকিয়ে দেই, তাহলে আউটপুট হিসেবে পাবো ‘খিচুড়ি’। আমাদের এই সংযোগ ম্যাপকে ম্যাট্রিক্স হিসেবে দেখতে চাইলে নিচের ছবিটা দেখতে পারেন।
এখন আসি সংযোগ ম্যাপে। সংযোগ ম্যাপের ম্যাট্রিক্স দেখছেন এখানে। এর সাথে আমরা এই দুটো ভেক্টরের সংযোগকে গুণ করলে আমরা এ দুটোর যোগফল পাব। আমরা এটাকে নিউরাল নেটওয়ার্কের সনাতন নোড এবং ‘এজ’ অর্থাৎ ওয়েট হিসেবে দেখতে চাইলে নিচের ছবিটা দেখতে পারি।
এখানে নাস্তার আইটেমের একটা এলিমেন্ট দেখছি আমরা উপরে। তার নিচে আবহাওয়ার এলিমেন্ট, এই দুটোই ইনপুট এলিমেন্ট। এরপরে দুটো এলিমেন্টকে যোগ করার একটা সেকশন, এরপর নিউরাল নেটওয়ার্কের সনাতন ‘নন-লিনিয়ার’ সেকশন, এবং শেষে ‘মার্জ’ অর্থাৎ সংযোগ ম্যাপ।
মার্জ ম্যাপ, ফলাফল
এখানে উদাহরণ হিসেবে নাস্তা আইটেম লুচির ভেক্টর এবং আবহাওয়া সেকশনে বৃষ্টি দিনের ভেক্টর দিয়ে শুরু করলে, এই ভেক্টরগুলো উপরের ডানের ছবির মত করে শুরুর নোডে এসে জমা হবে।
এখানকার নোডের ওয়েটের অংশে (তীরচিহ্নের) আমরা শুধুমাত্র সেই ‘অ্যারোগুলো’কে এঁকেছি যার মধ্যে সংখ্যা ১ লেবেল করা আছে। সংখ্যা ০ লেবেলগুলোকে এখানে আঁকা হয়নি। এই নোডের মানগুলোর সাথে ‘এজের’ ওয়েটগুলোর ম্যাট্রিক্স মাল্টিপ্লিকেশন করলে সেটা সামনে এভাবে দাঁড়ায়।
এখানে ম্যাট্রিক্স মাল্টিপ্লিকেশন মানে এই নোডের ভ্যালুর সাথে ‘এজে’র ওয়েটগুলোকে গুন করে শেষে যোগ করতে হবে।এখানে আমাদের ম্যাট্রিক্স মাল্টিপ্লিকেশন এর ফলাফল দেখতে পাচ্ছি দ্বিতীয় লেয়ারের নোডগুলোতে। এখানে নাস্তা এবং আবহাওয়া ম্যাট্রিক্সগুলোকে যোগ করে দিচ্ছি। এখানে সর্বোচ্চ ভ্যালু হিসেবে ২ কে ধরে সামনে ‘নন-লিনিয়ার’ ফাংশন ব্যবহার করলে সেই ২ এর জায়গায় ১ হয়ে বাকি এন্ট্রিগুলো ০ হয়ে যাবে। এবং শেষের ম্যাট্রিক্সে উপরের ভেক্টর এবং নিচের ভেক্টরকে যোগ করে আমরা সর্বশেষ নোডে ফলাফল পাচ্ছি একটা ভেক্টর যার এসোসিয়েটেড নাস্তা হচ্ছে খিচুড়ি।
আউটপুট থেকে ইনপুটে, 'রিকার' অর্থাৎ ‘রিকারেন্ট নিউরাল নেটওয়ার্ক’
এটা যদিও একটা নিউরাল নেটওয়ার্ক তবে এখানে নাস্তার ইনপুট হিসেবে যেই নোডগুলো ব্যবহার হচ্ছে, সেটার আউটপুট হিসেবে শেষের লেয়ারের যেই নোডগুলো দেখছি - সেখানে এই আউটপুটের ফলাফল ইনপুট হিসেবে চলে যাচ্ছে নাস্তার ইনপুট লেয়ারে। তাহলে এই নিউরাল নেটওয়ার্কের কার্যপরিধি উপরের ছবির মত দেখা যেতে পারে।
আর, এই জন্যই এই নিউরাল নেটওয়ার্ককে বলা হচ্ছে ‘রিকারেন্ট নিউরাল নেটওয়ার্ক’ অর্থাৎ আউটপুট এর ৩ সংখ্যার ভেক্টর ফিরে আসছে ইনপুটে একই সংখ্যার ভেক্টর হিসেবে। এই জন্যই এই ‘রিকারেন্ট নিউরাল নেটওয়ার্কস’ ব্যবহার হয় সব ধরনের কাজে - যেখানে ‘সিকোয়েন্সিয়াল’ ডাটা ব্যবহার থাকে। যেখানে আমাদের পরের ডাটা পয়েন্ট তার আগের অথবা তার আরো আগের ডাটার উপর নির্ভর করে, তখন এ ধরনের নেটওয়ার্ক ব্যবহার হয়।
আমাদের এই রিকারেন্ট নিউরাল নেটওয়ার্কসের পরিবারের সদস্য হচ্ছে ‘এলএসটিএম’ অর্থাৎ লং শর্ট টার্ম মেমোরি নেটওয়ার্কস। ‘এলএসটিএম’ নেটওয়ার্কে ‘আরএনএন’ এর মত একটার জায়গায় দুটো মেমোরি থাকে। একটা ছোট সময়ের জন্য মেমোরি, আরেকটা বড় সময়ের জন্য মেমোরি, যখন যেটা দরকার। ছোট এবং বড় সময়ের জন্য হবার কারণে দুটো মেমোরির আপডেট হয় ভিন্ন ভিন্ন সময়ে। এখানে ‘আরএনএন’ এর যেহেতু একটা মেমোরি এবং সেকারণে ছোটখাটো ইভেন্ট মনে রাখতে পারে। এখানে এই ‘আরএনএন’ বেশ কয়েকদিন আগে পর্যন্ত মানে কবে কবে বৃষ্টি এবং রুদ্রের দিন ছিল, সেগুলো মনে রাখতে পারে। এই ‘এলএসটিএম’ বাই অর্থাৎ দুই দিকের ‘ডাইরেকশনাল’ হতে পারে। সাধারণত, রিকারেন্ট নিউরাল নেটওয়ার্ক একটা শব্দের আগে শব্দকে মনে রাখলেও এরপরে শব্দকে মনে রাখার জন্য দক্ষতার জন্য দুই পাশ থেকে ‘বাই ডাইরেকশনাল’ ‘এলএসটিএম’ চালাতে পারে।
© রকিবুল হাসান