Chapter 8 of 18
How a network turns raw input into a real prediction
প্রতিটা নিউরাল নেটওয়ার্ক, যতই বড় হোক না কেন, প্রেডিকশন করার সময় ঠিক একই মৌলিক কাজটাই করে: এটা একগুচ্ছ ইনপুট সংখ্যা নেয়, সেগুলোকে হিসাবের একটা চেইনের মধ্য দিয়ে পাঠায়, আর একগুচ্ছ আউটপুট সংখ্যা তৈরি করে। ইনপুট থেকে শুরু করে পুরো আউটপুট পর্যন্ত পৌঁছানোর এই পুরো প্রক্রিয়াকেই বলা হয় forward propagation (কখনো কখনো শুধু "forward pass")।
নেটওয়ার্কটাকে একটা ব্ল্যাক বক্স না ভেবে একটা পাইপলাইন হিসেবে কল্পনা করুন। raw ডেটা এক প্রান্ত দিয়ে ঢোকে — ধরুন, একটা বাসার স্কয়ার ফুটেজ, বেডরুম সংখ্যা, আর বয়স — আর অন্য প্রান্ত দিয়ে একটা প্রেডিকশন বের হয়, যেমন একটা আনুমানিক দাম। মাঝখানের সবকিছুই একটা ফিক্সড সিরিজ হিসাব-নিকাশ: গুণ করো, যোগ করো, রূপান্তর করো, পুনরাবৃত্তি করো, লেয়ারের পর লেয়ার, যতক্ষণ না চূড়ান্ত সংখ্যাগুলো আউটপুটে গিয়ে পৌঁছায়।
Forward propagation হলো একটা নেটওয়ার্কের আউটপুট হিসাব করার প্রক্রিয়া, একটা ইনপুটকে প্রতিটা লেয়ারের মধ্য দিয়ে পাঠিয়ে, ক্রমানুসারে, প্রথম লেয়ার থেকে শেষ লেয়ার পর্যন্ত।
এখানে "forward" শব্দটা গুরুত্বপূর্ণ কারণ একটা দ্বিতীয়, খুবই ভিন্ন প্রক্রিয়াও আছে — backpropagation — যা উল্টো দিকে চলে, একটা প্রেডিকশন কতটা ভুল হয়েছিল তার উপর ভিত্তি করে weight অ্যাডজাস্ট করে। Forward propagation কিছুই অ্যাডজাস্ট করে না; এটা নিখুঁতভাবে নেটওয়ার্কের বর্তমান weight আর bias ব্যবহার করে একটা ইনপুটকে একটা আউটপুটে পরিণত করার কাজ। একটা ট্রেন করা মডেল যেকোনো প্রেডিকশন করে — একটা ইমেইল ক্লাসিফাই করা, একটা মুখ চেনা, একটা প্রোডাক্ট সাজেস্ট করা — সেটাই একটা forward pass।
Forward propagation-কে একটা অ্যাসেম্বলি লাইনের মতো ভাবুন। raw মালামাল (ইনপুট) এক প্রান্তে ঢোকে। প্রতিটা স্টেশন (প্রতিটা লেয়ার) আগের স্টেশন থেকে যা আসে তার উপর নিজের ফিক্সড কাজটা করে। কিছুই সামনে লাফ দেয় না, কিছুই পেছনে যায় না — সবকিছু কঠোরভাবে সামনের দিকে প্রবাহিত হয় যতক্ষণ না একটা সমাপ্ত প্রোডাক্ট (প্রেডিকশন) দূরের প্রান্ত থেকে বেরিয়ে আসে।
Forward propagation-কে সঠিকভাবে দেখতে হলে, শুধু একটা লেয়ারে কী ঘটে সেটার উপর জুম করলে সাহায্য হয়, তারপর বুঝতে পারবেন ঠিক এই একই রেসিপি এর পরের প্রতিটা লেয়ারে পুনরাবৃত্তি হয়।
একটা লেয়ারের প্রতিটা নিউরন এর কাছে যা আসে তার একটা ওয়েটেড সাম হিসাব করে, প্লাস একটা bias:
এখানে, হলো আগের লেয়ার থেকে আসা মান (অথবা raw ইনপুট, যদি এটা প্রথম লেয়ার হয়), হলো সেই নিউরনের weight — আসা প্রতিটা কানেকশনের একটা করে — আর হলো সেই নিউরনের bias। ফলাফল, , একটা মাত্র সংখ্যা: এই নিউরনের কাঁচা, অ্যাক্টিভেশনের-আগের আউটপুট।
একটা লেয়ার একটা মাত্র নিউরন না — সাধারণত এটা একসাথে থাকা অনেকগুলো নিউরন, প্রতিটাই ঠিক এই একই হিসাব চালায়, কিন্তু নিজস্ব আলাদা weight-এর সেট আর নিজস্ব bias দিয়ে। একটা লেয়ারের প্রতিটা নিউরন আগের লেয়ার থেকে আসা একই ইনপুট দেখে, কিন্তু প্রতিটা এই ইনপুটগুলোকে ভিন্নভাবে ওয়েট করে, তাই লেয়ারের প্রতিটা নিউরন নিজের আলাদা মান তৈরি করে।
লেয়ার ১-এর প্রতিটা নিউরন তার আউটপুট হিসাব করে ফেললে, সেই আউটপুটগুলো লেয়ার ২-এর ইনপুট হয়ে যায়। লেয়ার ২ ঠিক একই ধরনের হিসাব চালায় — ওয়েটেড সাম প্লাস bias — কিন্তু নিজস্ব weight আর bias দিয়ে, লেয়ার ১ যে মান তৈরি করেছে তার উপর। এটা নেটওয়ার্কের প্রতিটা লেয়ারে পুনরাবৃত্তি হয়: লেয়ার ২-এর আউটপুট লেয়ার ৩-কে খাওয়ায়, লেয়ার ৩-এর আউটপুট লেয়ার ৪-কে খাওয়ায়, এভাবে চলতে থাকে, যতক্ষণ না শেষ লেয়ার নেটওয়ার্কের আউটপুট তৈরি করে।
কোনো লেয়ারই তার আউটপুট হিসাব করতে পারে না যতক্ষণ না তার আগের লেয়ার শেষ করেছে। লেয়ার ৩ আক্ষরিক অর্থেই চলতে পারে না যতক্ষণ না লেয়ার ২-এর সংখ্যাগুলো তৈরি হয়, কারণ লেয়ার ২-এর আউটপুট লেয়ার ৩-এর ইনপুট। এই কঠোর, এক-দিকের নির্ভরতাই forward propagation-কে লেয়ার হিসাবের একটা সিকোয়েন্স বানায়, এমন কিছু না যা একসাথে ঘটতে পারে।
যেকোনো লেয়ারে, জিজ্ঞেস করুন: "আমি কোন সংখ্যা পাচ্ছি, আর কোথা থেকে?" উত্তর সবসময়ই "ঠিক আগের লেয়ারের আউটপুট" (অথবা raw ইনপুট, লেয়ার ১-এর জন্য)। আরও পেছনের কোনো লেয়ার থেকে কখনো কিছু দরকার হয় না — প্রতিটা লেয়ারের শুধু সেটাই দরকার যা ঠিক তার আগের লেয়ারটা মাত্র হস্তান্তর করেছে।
যদি forward propagation ওয়েটেড সামে গিয়ে থেমে যেত, একটা গুরুত্বপূর্ণ জিনিস অনুপস্থিত থাকত। একটা ওয়েটেড সাম, , একটা নিখুঁত লিনিয়ার হিসাব — যতগুলো নিখুঁত লিনিয়ার লেয়ার একসাথে স্তূপ করুন না কেন, পুরো নেটওয়ার্কটা গাণিতিকভাবে ভেঙে একটা মাত্র লিনিয়ার লেয়ারের সমতুল্য কিছুতে পরিণত হয়। যতই depth থাক না কেন কোনো আসল ক্ষমতাই যোগ হয় না (এটাই ঠিক সেই সীমাবদ্ধতা যা Linear vs Non-Linear Separability চ্যাপ্টারে দেখানো হয়েছিল)।
সমাধান হলো হিসাব করার সাথে সাথেই এর উপর একটা অ্যাক্টিভেশন ফাংশন প্রয়োগ করা, ফলাফলটা পরের লেয়ারে পাঠানোর আগে:
এখানে হলো অ্যাক্টিভেশন ফাংশন — একটা ফিক্সড, non-linear সূত্র, ওই লেয়ারের প্রতিটা নিউরনে একই সূত্র প্রয়োগ হয় — আর হলো সেই নিউরনের অ্যাক্টিভেশন, সেই সংখ্যা যা আসলেই পরের লেয়ারে পাঠানো হয়। raw কখনো নিউরন থেকে বের হয় না; শুধু , অ্যাক্টিভেটেড মানটাই বের হয়।
কয়েকটা অ্যাক্টিভেশন ফাংশন সবসময়ই দেখা যায়:
Sigmoid
যেকোনো ইনপুটকে ০ আর ১-এর মধ্যে একটা মানে চেপে ফেলে। প্রায়ই binary classification-এর জন্য একটা আউটপুট লেয়ারে ব্যবহার হয়, যেখানে আউটপুটকে একটা প্রোবাবিলিটির মতো দেখাতে হয়।
ReLU (Rectified Linear Unit)
ইনপুট পজিটিভ হলে সরাসরি সেটাই আউটপুট করে, নাহলে ০ আউটপুট করে। হিডেন লেয়ারে অত্যন্ত সাধারণ কারণ এটা হিসাব করা সহজ আর deep নেটওয়ার্কে ভালো কাজ করে।
Tanh
যেকোনো ইনপুটকে -১ আর ১-এর মধ্যে একটা মানে চেপে ফেলে। sigmoid-এর মতোই, কিন্তু ০.৫-এর বদলে ০-কে কেন্দ্র করে।
Softmax
একটা পুরো লেয়ারের raw আউটপুটকে এমন কিছু প্রোবাবিলিটিতে রূপান্তরিত করে যেগুলো যোগ করলে ১ হয়, সাধারণত multi-class classification-এর জন্য আউটপুট লেয়ারে ব্যবহার হয়।
অ্যাক্টিভেশন ফাংশনকে একটা ঐচ্ছিক অ্যাড-অন ভাবাটা সহজ মনে হতে পারে। কিন্তু এগুলো তা না — লেয়ারগুলোর মাঝে একটা non-linear অ্যাক্টিভেশন ফাংশন ছাড়া, একটা ১০০-লেয়ারের নেটওয়ার্কও শুধু একটা সরল decision boundary আঁকতে পারবে, ঠিক একটা সিঙ্গেল perceptron-এর মতো। অ্যাক্টিভেশন ফাংশনই depth-কে নেটওয়ার্কের জন্য আসলে কিছু কিনে দেওয়ার সুযোগ দেয়।
Activation প্রতিটা হিডেন লেয়ারে ঘটে, নিউরনে নিউরনে: হিসাব করো, প্রয়োগ করো, পাও, আর সামনে পাঠাও। এই অ্যাক্টিভেটেড মানটাই, raw না, যা পরের লেয়ার আসলেই তার একটা ইনপুট হিসেবে পায়।
Forward propagation শেষ হয় আউটপুট লেয়ারে — নেটওয়ার্কের শেষ লেয়ার, যার অ্যাক্টিভেশনই নেটওয়ার্কের প্রেডিকশন। এর পরে কিছুই ঘটে না; আউটপুট লেয়ারের নিউরনগুলো থেকে যা সংখ্যা বের হয় সেটাই এই নির্দিষ্ট ইনপুটের জন্য চূড়ান্ত উত্তর।
আউটপুট লেয়ারে অ্যাক্টিভেশন ফাংশনের বাছাই সরাসরি নির্ভর করে নেটওয়ার্কটা কী ধরনের প্রেডিকশন করছে তার উপর:
| কাজ | সাধারণ আউটপুট অ্যাক্টিভেশন | আউটপুটের অর্থ কী |
|---|---|---|
| Binary Classification | Sigmoid | ০ আর ১-এর মধ্যে একটা মাত্র সংখ্যা — পজিটিভ ক্লাসের আনুমানিক প্রোবাবিলিটি |
| Multi-class Classification | Softmax | প্রতিটা ক্লাসের জন্য একটা করে সংখ্যা, সবগুলো ০ আর ১-এর মধ্যে, যোগফল ১ — ক্লাসগুলোর উপর একটা প্রোবাবিলিটি ডিস্ট্রিবিউশন |
| Regression | কিছু না (লিনিয়ার/আইডেন্টিটি) | একটা কাঁচা, অসীমাবদ্ধ সংখ্যা — যেমন একটা প্রেডিক্ট করা দাম বা তাপমাত্রা |
আগের বাসার-দামের উদাহরণটা ধরুন: প্রতিটা হিডেন লেয়ার ক্রমানুসারে তার মান হিসাব আর অ্যাক্টিভেট করে ফেলার পর, চূড়ান্ত লেয়ার — যার রেঞ্জ সীমাবদ্ধ করে এমন কোনো অ্যাক্টিভেশন ফাংশন নেই — একটা raw সংখ্যা তৈরি করে, ধরুন । এটাই নেটওয়ার্কের প্রেডিকশন: একটা টাকার পরিমাণ, প্রোবাবিলিটি না, কারণ regression-এর আউটপুট একটা ফিক্সড রেঞ্জে চাপার দরকার নেই।
তার বদলে একটা স্প্যাম classifier ধরুন: আউটপুট লেয়ার, sigmoid ব্যবহার করে, হয়তো তৈরি করে। এটা কোনো দাম না — এটা একটা প্রোবাবিলিটি, মানে নেটওয়ার্ক ৯৩% নিশ্চিত এই ইমেইলটা স্প্যাম। "স্প্যাম প্রেডিক্ট করা" হিসেবে ধরা হবে কিনা সাধারণত একটা থ্রেশহোল্ডের উপর নির্ভর করে, সাধারণত : এর উপরে হলে, স্প্যাম প্রেডিক্ট করো; নিচে হলে, না-স্প্যাম প্রেডিক্ট করো।
একটা prediction নিছক আউটপুট লেয়ারের অ্যাক্টিভেশন মান, বাকি সব লেয়ারের মতোই একই forward-propagation প্রক্রিয়ায় হিসাব করা, কিন্তু নেটওয়ার্কটা যে কাজের জন্য বানানো হয়েছে তা অনুযায়ী ব্যাখ্যা করা।
একটা নির্দিষ্ট ইনপুটে নেটওয়ার্কের প্রেডিকশন সত্যিই বুঝতে হলে, একবারে একটা সংখ্যা ট্রেস করুন: লেয়ার ১-এর প্রতিটা নিউরনের জন্য হিসাব করুন, প্রতিটা পেতে অ্যাক্টিভেশন প্রয়োগ করুন, সেগুলো লেয়ার ২-তে খাওয়ান, আউটপুট লেয়ার পর্যন্ত পুনরাবৃত্তি করুন। প্রতিটা প্রেডিকশন, নেটওয়ার্ক যতই বড় হোক না কেন, ভিন্ন ভিন্ন সংখ্যা দিয়ে পুনরাবৃত্তি হওয়া এই একই চেইন ছাড়া আর কিছুই না।
নিচের ইন্টারেক্টিভ ডেমোটা আপনাকে সেই অ্যাক্টিভেশন ফাংশনগুলো এক্সপ্লোর করতে দেয় যা forward propagation-এর সময় প্রতিটা লেয়ারে প্রয়োগ হয় — sigmoid, tanh, ReLU, বা Leaky ReLU বেছে নিন আর দেখুন প্রতিটা কীভাবে তার raw ইনপুটকে ভিন্নভাবে রূপান্তরিত করে।
সিগময়েড, ট্যানএইচ, ReLU, অথবা Leaky ReLU বেছে নিন এবং ফাংশনটিকে তার ডেরিভেটিভের সাথে প্লট করা অবস্থায় দেখুন — খেয়াল করুন এদের প্রত্যেকে কোথায় গিয়ে স্যাচুরেট করে।
ফাংশনগুলোর মধ্যে সুইচ করার সময় কয়েকটা জিনিস খেয়াল করার মতো:
এই সিঙ্গেল রূপান্তরটাকে একটা আসল নেটওয়ার্কের প্রতিটা লেয়ারের প্রতিটা নিউরনে গুণ করুন, একটা লেয়ারের অ্যাক্টিভেশনকে পরের লেয়ারের ওয়েটেড সামে চেইন করুন, আর আপনার কাছে forward propagation-এর পুরো ছবিটা আছে: ইনপুট সংখ্যা, ওয়েটেড সাম আর অ্যাক্টিভেশনের মধ্য দিয়ে লেয়ারে লেয়ারে আকার বদলে, আউটপুট লেয়ারে একটা সমাপ্ত প্রেডিকশন হিসেবে পৌঁছাচ্ছে।