Chapter 10 of 28
Why ReLU won, and what its alternatives fix
যেকোনো নিউরাল নেটওয়ার্ক থেকে অ্যাক্টিভেশন ফাংশনগুলো সরিয়ে দিন, নেটওয়ার্কটি যত গভীরই হোক না কেন, একটি আশ্চর্যজনক বিষয় লক্ষ্য করবেন: পুরো নেটওয়ার্কটি ভেঙে একটি একক লিনিয়ার বা রৈখিক রূপান্তরে (linear transformation) পরিণত হবে। মাঝখানে কোনো নন-লিনিয়ারিটি বা অ্যাক্টিভেশন ফাংশন ছাড়া একটার ওপর আরেকটা সাজানো ১০০টি কনভোলিউশন লেয়ার গাণিতিকভাবে একটিমাত্র কনভোলিউশন লেয়ারের সমতুল্য। এর গভীরতা, এর সমস্ত রিপ্রেজেন্টেশনাল ক্ষমতা এক মুহূর্তে কর্পূরের মতো উড়ে যাবে।
অ্যাক্টিভেশন ফাংশনগুলোই মূলত এই ভেঙে যাওয়া বা অবক্ষয় রোধ করে। এগুলো হলো ছোট, সস্তা এবং খুব সাধারণ গাণিতিক ফাংশন যা প্রতি লেয়ারের পর উপাদান-ভিত্তিক বা element-wise প্রয়োগ করা হয় — আর কোন ফাংশনটি ব্যবহার করছেন সেই সিদ্ধান্তটি নেটওয়ার্ক কত দ্রুত ট্রেইন হবে, গ্রেডিয়েন্ট পেছনের দিকে প্রবাহের সময় বেঁচে ফিরবে কিনা, এবং কিছু নিউরন নীরবে চিরতরে শেখা বন্ধ করে দেবে কিনা তার ওপর এক বিশাল প্রভাব ফেলে।
ভাবুন তো, একটি রিভিউ কমিটি কোনো দরখাস্ত যাচাই করছে, যেখানে প্রতিটি রিভিউয়ারের চূড়ান্ত সিদ্ধান্ত হলো তার আগের রিভিউয়ারের সিদ্ধান্তের একটি গড় বা ওয়েটেড এভারেজ মাত্র। এই চেইনে আপনি যত রিভিউয়ারই যোগ করুন না কেন, পুরো কমিটি শেষ পর্যন্ত একটি কার্যকরী ওয়েটেড এভারেজে নেমে আসবে — অর্থাৎ লিনিয়ার বা রৈখিক আচরণ করা রিভিউয়ারের সংখ্যা বাড়িয়ে আসলে আপনার কোনো লাভ নেই। এবার প্রতি রিভিউয়ারকে একটি করে নিয়ম দিন, যেমন "যদি আমার ক্যালকুলেট করা স্কোর নেগেটিভ হয়, তবে আমি সিদ্ধান্ত না দিয়ে চুপ থাকব বা vote দেওয়া থেকে বিরত থাকব" — হঠাৎ করেই প্রতি রিভিউয়ারের সিদ্ধান্ত আগের রিভিউয়ারের সরল সিদ্ধান্তের চেয়ে আরও জটিল ও ভিন্ন কিছু তৈরি করবে। এই "নেগেটিভ হলে বিরত থাকা" নিয়মটিই হলো মূলত ReLU (Rectified Linear Unit), যা আধুনিক CNN-এর প্রায় প্রতিটি কনভোলিউশনের পর ব্যবহৃত অ্যাক্টিভেশন ফাংশন।
সহজ কথা: ReLU অত্যন্ত সাধারণ — পজিটিভ মানগুলোকে কোনো পরিবর্তন ছাড়া পার হতে দেয়, আর নেগেটিভ সবকিছুকে কেটে শূন্য করে দেয়। এই সরলতাই হলো এর মূল শক্তি: এর গ্রেডিয়েন্ট বা ডেরিভেটিভ হয় নিখুঁত ১, নয়তো নিখুঁত ০, মাঝখানে কোনো ছোট গুণক বা ফ্যাক্টর থাকে না। ফলে পজিটিভ অ্যাক্টিভেশনের মধ্য দিয়ে গ্রেডিয়েন্ট যখন পেছনের অনেকগুলো লেয়ার পেরিয়ে প্রবাহিত হয়, তখন তা চেপে বা সংকুচিত হয়ে যায় না।
সুবিধাসমূহ: কম্পিউটেশনালি খুবই সস্তা (শুধু শূন্যের সাথে একটি তুলনা করতে হয়); এর জন্য vanishing gradient সমস্যা এড়ায়; স্পার্সিটি (sparsity) বাড়ায়, কারণ যেকোনো ইনপুটের জন্য উল্লেখযোগ্য বা বড় অংশের নিউরনের আউটপুট হুবহু শূন্য হয়।
অসুবিধাসমূহ: "dying ReLU" সমস্যা — কোনো নিউরনের আউটপুট যদি ট্রেনিংয়ের সব উদাহরণের জন্যই হয়, তবে তার গ্রেডিয়েন্ট চিরতরে শূন্য হয়ে যায় এবং সেটি স্থায়ীভাবে শেখা বন্ধ করে দেয়; ReLU-র আউটপুট কখনো নেগেটিভ হয় না, তাই এটি জিরো-সেন্টার্ড (zero-centered) নয়।
ব্যবহারিক ক্ষেত্র: CNN-এর হিডেন লেয়ারগুলোর জন্য ডিফল্ট পছন্দ — প্রায় প্রতিটি কনভোলিউশনের পরই এটি ব্যবহৃত হয়।
সহজ কথা: Leaky ReLU নেগেটিভ ইনপুটের জন্য গ্রেডিয়েন্টকে হুবহু শূন্য হতে দেয় না — পুরোপুরি নীরব হয়ে যাওয়ার বদলে, একটি "মৃতপ্রায়" নিউরন সামান্য গ্রেডিয়েন্ট সংকেত (ইনপুটের গুণ) লিক বা প্রবাহিত করতে পারে যা ট্রেনিংয়ের সময় তাকে পুনরায় সচল করতে সাহায্য করে।
সুবিধাসমূহ: -এর জন্য একটি ছোট অশূন্য গ্রেডিয়েন্ট বজায় রেখে সরাসরি dying-neuron সমস্যার সমাধান করে।
অসুবিধাসমূহ: বাস্তবে এর ফলাফল সবসময় সাধারণ ReLU থেকে ভালো হয় না; হলো আরেকটি অতিরিক্ত হাইপারপ্যারামিটার যা বেছে নিতে হয়, যদি না এটি মডেল নিজে থেকে শেখে (যেমন PReLU বা Parametric ReLU-র ক্ষেত্রে)।
ব্যবহারিক ক্ষেত্র: ট্রেনিংয়ের সময় যদি প্রচুর পরিমাণে ডেড নিউরনের উপস্থিতি সনাক্ত হয়, তবে ReLU-র বিকল্প ড্রপ-ইন হিসেবে এটি ব্যবহৃত হয়।
সহজ কথা: Sigmoid যেকোনো বাস্তব সংখ্যাকে চেপে বা সংকুচিত করে সীমার মধ্যে নিয়ে আসে, যার ফলে এর আউটপুটকে সরাসরি প্রোবাবিলিটি বা সম্ভাবনা হিসেবে পড়া যায়। তবে এর ডেরিভেটিভের দিকে তাকান: এটি হলো আউটপুট গুণ ১ মাইনাস আউটপুট, যা সর্বোচ্চ হয় এ এবং এর মান ০ বা ১ এর কাছাকাছি পৌঁছালে তা সংকুচিত হয়ে শূন্যের কাছাকাছি চলে যায়। কয়েক লেয়ার সিগময়েড স্তুপ করলে এই ছোট গুণকগুলো গুণ হয়ে আগের লেয়ারগুলোতে পৌঁছাতে পৌঁছাতে গ্রেডিয়েন্ট প্রায় পুরোপুরি গায়েব বা ভ্যানিশ হয়ে যায়।
সুবিধাসমূহ: সর্বত্র মসৃণ ও ব্যবকলনযোগ্য (smooth and differentiable); বাউন্ডেড আউটপুট যা সরাসরি সম্ভাবনা নির্দেশ করে।
অসুবিধাসমূহ: vanishing gradient for large ; zero-centered নয়; ReLU-র চেয়ে কম্পিউটেশনালি কিছুটা ব্যয়বহুল (কম্প্যারিসনের বদলে exponential হিসাব করতে হয়)।
ব্যবহারিক ক্ষেত্র: binary classification-এর আউটপুট লেয়ার; এছাড়া LSTM সেলের gating function হিসেবে ব্যবহৃত হয় — তবে CNN-এর হিডেন লেয়ারে এর ব্যবহার এখন আর দেখাই যায় না।
সহজ কথা: Tanh মূলত একটি রিস্ট্রাকচারড বা রিস্কেল্ড সিগময়েড, যা আউটপুটকে -এর বদলে সীমার মধ্যে সংকুচিত করে। জিরো-সেন্টার্ড হওয়ার কারণে — অর্থাৎ এর আউটপুট নেগেটিভ হতে পারায় — এটি সিগময়েডের চেয়ে অপ্টিমাইজেশনকে কিছুটা সহজ করে তোলে। তবে এর মূল দুর্বলতা একই: খুব বড় ইনপুটের জন্য এর ডেরিভেটিভ শূন্যের দিকে যায় এবং গ্রেডিয়েন্ট ভ্যানিশ হয়ে যায়।
সুবিধাসমূহ: zero-centered output, যা সিগময়েডের তুলনায় gradient-based optimization-এ বেশি সাহায্য করে; মসৃণ ও ব্যবকলনযোগ্য।
অসুবিধাসমূহ: very large -এ এখনও ভ্যানিশিং-গ্রেডিয়েন্ট সমস্যায় ভোগে।
ব্যবহারিক ক্ষেত্র: ReLU জনপ্রিয় হওয়ার আগে হিডেন লেয়ারে ব্যবহৃত হতো; এখনও RNN এবং LSTM সেলের ভেতরে খুব বেশি ব্যবহৃত হয়।
সহজ কথা: সফটম্যাক্স এক ভেক্টর লজিট বা raw স্কোরকে একটি সঠিক প্রোবাবিলিটি বা সম্ভাবনার ডিস্ট্রিবিউশনে রূপান্তর করে — যেখানে প্রতিটি মান পজিটিভ হয় এবং সবগুলোর যোগফল হুবহু ১ হয়। বড় লজিটগুলো এক্সপোনেনশিয়ালি বেশি সম্ভাবনা লাভ করে, যা ক্রস-এন্ট্রপি লসের সাথে একে চমৎকারভাবে মানিয়ে নেয়: মডেলটি অন্য লজিটের তুলনায় সঠিক ক্লাসের লজিটকে বেশি বাড়াতে পারলে সরাসরি পুরস্কৃত হয়।
সুবিধাসমূহ: raw স্কোরগুলোকে সংখ্যক ক্লাসের ওপর বৈধ সম্ভাবনায় রূপান্তর করে; ক্রস-এন্ট্রপি লসের সাথে চমৎকার বন্ধন তৈরি করে (যা আমরা আগের চ্যাপ্টারগুলোতে দেখেছি)।
অসুবিধাসমূহ: খুব বড় লজিটের প্রতি সংবেদনশীল যা exponential করার সময় overflow হতে পারে — বাস্তবে হিসাব করার আগে প্রতিটি লজিট থেকে সর্বোচ্চ লজিটটি বিয়োগ করে নিয়ে এই সমস্যার সমাধান করা হয়, যা গাণিতিক মান অপরিবর্তিত রেখে সংখ্যাগুলোকে নিয়ন্ত্রণে রাখে।
ব্যবহারিক ক্ষেত্র: multi-class classification-এর আউটপুট লেয়ারে।
| ফাংশন (Function) | আউটপুট সীমা (Range) | সুবিধাসমূহ (Advantages) | অসুবিধাসমূহ (Disadvantages) | ব্যবহারিক ক্ষেত্র (Typical Use) |
|---|---|---|---|---|
| ReLU | [0, ∞) | খুব দ্রুত, x>0 এর জন্য গ্রেডিয়েন্ট ভ্যানিশ হয় না | Dying ReLU সমস্যা | হিডেন লেয়ার (ডিফল্ট পছন্দ) |
| Leaky ReLU | (-∞, ∞) | Dying ReLU সমস্যার সমাধান করে | অতিরিক্ত হাইপারপ্যারামিটার (α) | হিডেন লেয়ার (বিকল্প পছন্দ) |
| Sigmoid | (0, 1) | প্রোবাবিলিটি আউটপুট দেয় | ভ্যানিশিং গ্রেডিয়েন্ট সমস্যা | binary output layer |
| Tanh | (-1, 1) | zero-centered output | ভ্যানিশিং গ্রেডিয়েন্ট সমস্যা | RNN/LSTM, প্রাচীন CNN হিডেন লেয়ার |
| Softmax | (0, 1), সমষ্টি ১ | মাল্টি-ক্লাস সম্ভাবনা দেয় | Overflow-এর ঝুঁকি (max বিয়োগ করে সমাধানযোগ্য) | multi-class output layer |

ধরুন, একটি কনভোলিউশন ফিল্টারের প্রাক-অ্যাক্টিভেশন বা pre-activation আউটপুট ৫০টি ট্রেনিং ইমেজের একটি ব্যাচের জন্য সবসময় নেগেটিভ আসে — অর্থাৎ প্রতি ইমেজের জন্যই । এটি যখন সাধারণ ReLU-র মধ্য দিয়ে প্রবাহিত হয়, তখন ৫০টি ছবির জন্যই আউটপুট হয় ০, এবং লোকাল ডেরিভেটিভ এর মানও ৫০টি ছবির জন্যই ০ হয়। ব্যাকপ্রোপাগেশনের সময়, এই ফিল্টারের ওজনের কাছে পৌঁছানো গ্রেডিয়েন্টকে প্রতিটি উদাহরণের জন্য ওই শূন্য ডেরিভেটিভ দিয়ে গুণ করা হয় — তাই ইনকামিং এরর সিগন্যাল যত বড়ই হোক না কেন, এই ফিল্টারের ওজনের আপডেট বা সংশোধন হয় হুবহু ০। এটি এখন ট্রেনিংয়ের যত epoch-ই আসুক না কেন, স্থায়ীভাবে লক বা আটকে গেছে।
এবার এই একই ফিল্টারে Leaky ReLU (যেখানে ) ব্যবহার করে দেখুন, -এর জন্য ডেরিভেটিভের মান ০ না হয়ে হবে — খুব ছোট, কিন্তু অশূন্য। ফিল্টারটি এখনও একটি (হালকা) গ্রেডিয়েন্ট সিগন্যাল পাবে এবং বাকি নেটওয়ার্ক বা ডেটার পরিবর্তনের সাথে সাথে পুনরায় পজিটিভ জোনে ফেরত আসার সুযোগ পাবে।
import numpy as np
def relu(x):
return np.maximum(0, x)
def relu_grad(x):
return (x > 0).astype(float)
def leaky_relu(x, alpha=0.01):
return np.where(x > 0, x, alpha * x)
def leaky_relu_grad(x, alpha=0.01):
return np.where(x > 0, 1.0, alpha)
def sigmoid(x):
return 1.0 / (1.0 + np.exp(-x))
def softmax(z):
shifted = z - np.max(z) # গাণিতিক স্থিতিশীলতার জন্য: প্রথমে সর্বোচ্চ লজিট বিয়োগ করা হয়েছে
exp_z = np.exp(shifted)
return exp_z / np.sum(exp_z)
# মিনি-ব্যাচ জুড়ে "dying ReLU" ফিল্টার সনাক্ত করা
pre_activations = np.array([-2.1, -0.5, -3.0, -1.2, -0.8]) # এই ফিল্টারের জন্য সর্বদা নেগেটিভ
dead_fraction = np.mean(relu_grad(pre_activations) == 0)
print(f"এই ফিল্টারের জন্য শূন্য ReLU গ্রেডিয়েন্ট পাওয়া উদাহরণের হার: {dead_fraction:.0%}")কোডটির কয়েকটি বিশেষ দিক লক্ষ্য করুন:
softmax সবসময় প্রথমে সর্বোচ্চ লজিট বিয়োগ করে নেয়। এটি কোনো স্টাইলিশ বা ঐচ্ছিক বিষয় নয় — এটি ছাড়া বড় লজিটগুলো np.exp-কে overflow করে NaN রেজাল্ট তৈরি করবে, যদিও গাণিতিকভাবে আউটপুট একই থাকার কথা।relu_grad একটি বুলিয়ান-ভিত্তিক অ্যারে রিটার্ন করে, যা মূলত ব্যাকপ্রোপাগেশনের সময় ইনকামিং গ্রেডিয়েন্টের সাথে গুণ করার জন্য একদম পারফেক্ট গুণক — এটি ওপরের সমীকরণের পিসওয়াইজ ডেরিভেটিভের সরাসরি প্রতিফলন।"হিডেনে থাকবে ReLU, দরজায় থাকবে Sigmoid/Softmax।" নেটওয়ার্কের কনভোলিউশনাল হিডেন লেয়ারের সব জায়গায় ReLU বা এর উন্নত রূপ ব্যবহৃত হয়; আর Sigmoid বা Softmax সংরক্ষিত থাকে একদম শেষের লেয়ারে, আউটপুটকে সুন্দর প্রোবাবিলিটিতে রূপ দেওয়ার জন্য।
একটি খুব কমন ভুল ধারণা হলো Softmax-কে যেকোনো সাধারণ হিডেন লেয়ারে ব্যবহারযোগ্য নন-লিনিয়ারিটি ভাবা। বাস্তবে এটি শুধুমাত্র আউটপুট লেয়ারে ব্যবহৃত হয় যেখানে সব আউটপুটের যোগফল হুবহু ১ হওয়া প্রয়োজন — হিডেন লেয়ারের মাঝপথে এমন সীমাবদ্ধতা জুড়ে দেওয়ার কোনো গাণিতিক যৌক্তিকতা নেই।
অনেক সময় লস কার্ভ বা plateau দেখে আমরা ধরে নিই লার্নিং রেট বা মডেল আর্কিটেকচার ভুল, অথচ চেক করি না যে ReLU নিউরনের একটি বড় অংশ ইতিমধ্যে স্থায়ীভাবে নিষ্ক্রিয় বা মৃত হয়ে গেছে কিনা। প্রতি লেয়ারে শূন্য অ্যাক্টিভেশনের অনুপাত পর্যবেক্ষণ করা খুব সহজ ও কার্যকর একটি ডায়াগনস্টিক।
আপনার তৈরি করা প্রায় প্রতিটি CNN একই অ্যাক্টিভেশন প্যাটার্ন অনুসরণ করবে: প্রতিটি কনভোলিউশন এবং ডেন্স হিডেন লেয়ারের পর ReLU (বা Leaky ReLU, অথবা এর আধুনিক কোনো রূপ যেমন GELU বা Swish), এবং একদম শেষ লেয়ারের জন্য সংরক্ষিত থাকবে Sigmoid বা Softmax। মডেল যখন ট্রেইন হতে চায় না — লস কমছে না, অ্যাকুরেসি আটকে আছে — তখন হাইপারপ্যারামিটার বা অপ্টিমাইজার বদলানোর আগে অ্যাক্টিভেশন ফাংশন চেক করা এবং ডেড নিউরনের উপস্থিতি খোঁজা সবচেয়ে কার্যকর প্রথম পদক্ষেপগুলোর একটি।