Chapter 11 of 28
Teaching a vision model what "wrong" looks like
একটি CNN-এর ফরওয়ার্ড পাস (forward pass) শেষ হয় একটি সংখ্যা, অথবা কয়েকটি সংখ্যার মাধ্যমে — যেমন একটি প্রোবাবিলিটি বা সম্ভাবনা, এক সেট ক্লাস স্কোর, অথবা একটি প্রেডিক্ট করা কোঅর্ডিনেট বা স্থানাঙ্ক। নিজে নিজে বা সাধারণভাবে এই আউটপুটটি ট্রেনিং প্রক্রিয়ার জন্য কিছুই অর্থ বহন করে না। নেটওয়ার্কটি কোনো কিছু শেখার আগে, মডেলের "ভুল" সিদ্ধান্তটিকে একটি একক স্কেলার (scalar) মানে রূপান্তর করতে হয় যা কমানোর জন্য অপ্টিমাইজার কাজ করতে পারে। মডেলের প্রেডিকশন এবং তার আসল সত্যের (ground truth) মধ্যকার ব্যবধানকে গাণিতিক পরিমাপে রূপান্তর করে "মডেলটি ঠিক কতটা ভুল সিদ্ধান্ত দিয়েছে" তা বের করাই হলো লস ফাংশনের (loss function) কাজ।
কোনো কাজের বা টাস্কের জন্য ভুল লস ফাংশন বেছে নিলে হয়তো ট্রেনিং সরাসরি বন্ধ হয়ে যাবে না — কিন্তু এটি ট্রেনিংয়ের গতিকে অনেক ধীর করে দেয়, অথবা ঠিক যখন শক্তিশালী গ্রেডিয়েন্ট সিগন্যালের প্রয়োজন ছিল তখন গ্রেডিয়েন্টকে দুর্বল করে ফেলে। এই চ্যাপ্টারটি মূলত সেই গুটিকয়েক লস ফাংশন নিয়ে আলোচনা করে যা আপনার সম্মুখীন হওয়া প্রায় প্রতিটি CNN প্রজেক্ট কভার করবে, এবং জানাবে কোন লস ফাংশনের ঠিক আগে কোন অ্যাক্টিভেশন ফাংশন জোড়া দেওয়া উচিত।
পরীক্ষার খাতায় দুটি সম্পূর্ণ ভিন্ন ধরণের প্রশ্ন মূল্যায়ন করার কথা ভাবুন। একটি সত্য/মিথ্যা (true/false) প্রশ্নের খাতা দেখার নিয়ম খুব স্পষ্ট: উত্তরটি হয় সঠিক, নয়তো সম্পূর্ণ ভুল, এবং ভুল উত্তরের জন্য পেনাল্টি বা শাস্তি ঠিক ততটাই হওয়া উচিত উত্তরদাতা ওই ভুল উত্তরের ব্যাপারে যতটা দৃঢ় বা আত্মবিশ্বাসী ছিল। আবার "আগামীকালের তাপমাত্রা কত ডিগ্রি হবে তা নিখুঁতভাবে অনুমান করা" প্রশ্নের খাতা মূল্যায়নের জন্য সম্পূর্ণ ভিন্ন নিয়ম প্রয়োজন — সেখানে ২ ডিগ্রি ভুলের জন্য কম শাস্তি এবং ২০ ডিগ্রি ভুলের জন্য দশ গুণের চেয়েও অনেক বেশি শাস্তি হওয়া উচিত। তাপমাত্রা পরিমাপের প্রশ্নে যদি আপনি সত্য/মিথ্যার মূল্যায়নের নিয়ম খাটান, অথবা এর উল্টোটা করেন, তবে পুরো খাতা দেখার বিষয়টি হাস্যকর রূপ নেবে। লস ফাংশন বেছে নেওয়ার সিদ্ধান্তটিও ঠিক এটিই: ক্লাসিফিকেশন (classification) এবং রিগ্রেশন (regression) টাস্কের ভুলগুলোকে সম্পূর্ণ ভিন্ন গাণিতিক এককে পরিমাপ করা হয়।
যেখানে: হলো আসল বাইনারি লেবেল, এবং হলো পজিটিভ ক্লাসের প্রেডিক্টেড প্রোবাবিলিটি, যা সাধারণত একটি Sigmoid-এর আউটপুট।
সহজ কথা: যেকোনো একটি উদাহরণের জন্য এই দুটি পদের মধ্যে কেবল একটি পদই সবসময় "সক্রিয়" থাকে — যদি হয়, তবে পদটি শূন্য হয়ে যায় এবং লস দাঁড়ায় স্রেফ , যা এর মান ০ এর দিকে যাওয়ার সাথে সাথে অসীমের দিকে ধাবিত হয়। অন্য কথায়, আত্মবিশ্বাসের সাথে ভুল সিদ্ধান্ত দিলে কঠোর শাস্তি দেওয়া হয়, অন্যদিকে আত্মবিশ্বাসের সাথে সঠিক উত্তর দিলে লসের পরিমাণ প্রায় শূন্য হয়।
কখন ব্যবহার করবেন: binary classification (হুবহু ২টি ক্লাস থাকবে), যার আউটপুট লেয়ারে Sigmoid অ্যাক্টিভেশন থাকে।
সুবিধাসমূহ: সহজ; Sigmoid-এর সাথে জোড়া দিলে অত্যন্ত চমৎকার ও সুশৃঙ্খল গ্রেডিয়েন্ট তৈরি করে; এটি একটি স্ট্যান্ডার্ড ও নির্ভরযোগ্য ডিফল্ট পছন্দ।
অসুবিধাসমূহ: ২টির বেশি ক্লাসের জন্য সরাসরি ব্যবহার করা যায় না (সেক্ষেত্রে Categorical Cross-Entropy ব্যবহার করতে হবে); ক্লাসের ইমব্যালেন্স বা অসমতার প্রতি সংবেদনশীল, যা দূর করার জন্য কখনোকখনো ক্লাস ওয়েট (class weights) ব্যবহার করতে হয়।
যেখানে: হলো সংখ্যক ক্লাসের ওপর ওয়ান-হট এনকোড করা আসল লেবেল ভেক্টর (সঠিক ক্লাসের পজিশনে ১, বাকি সব জায়গায় ০), এবং হলো Softmax আউটপুট থেকে পাওয়া প্রেডিক্টেড প্রোবাবিলিটি ডিস্ট্রিবিউশন।
সহজ কথা: যেহেতু আসল লেবেল ওয়ান-হট ভেক্টর, তাই সঠিক ক্লাসের ইনডেক্স ছাড়া যোগফলের অন্য প্রতিটি পদ শূন্য হয়ে যায় — যার ফলে লসটি সংকুচিত হয়ে সঠিক ক্লাস -এর জন্য সরাসরি এ পরিণত হয়। নেটওয়ার্ককে শাস্তি দেওয়া হয় শুধুমাত্র সঠিক ক্লাসের জন্য সে কত কম প্রোবাবিলিটি বরাদ্দ করেছিল তার ওপর ভিত্তি করে, ভুল ক্লাসগুলোর মধ্যে সে কীভাবে প্রোবাবিলিটি বন্টন করেছে তা এখানে বিবেচনা করা হয় না।
কখন ব্যবহার করবেন: ওয়ান-হট এনকোড করা লেবেল বিশিষ্ট মাল্টি-ক্লাস ও একক-লেবেল (single-label) ক্লাসিফিকেশন টাস্কে, যার আউটপুট লেয়ারে Softmax অ্যাক্টিভেশন থাকে।
সুবিধাসমূহ: সঠিক ক্লাসে কম আত্মবিশ্বাসের জন্য সরাসরি পেনাল্টি দেয়; Softmax-এর সাথে চমৎকার ও মসৃণ গ্রেডিয়েন্ট তৈরি করে।
অসুবিধাসমূহ: ওয়ান-হট এনকোড করা লেবেল প্রয়োজন হয়, যা অনেক বেশি ক্লাস থাকলে অতিরিক্ত মেমরি খরচ করে।
সহজ কথা: এটি গাণিতিকভাবে Categorical Cross-Entropy-র হুবহু সমতুল্য — এটিও ওয়ান-হট সামেশন পেরিয়ে টিকে থাকা একই হিসাব করে — তবে এখানে লেবেলটিকে ওয়ান-হট ভেক্টরের বদলে সরাসরি একটি পূর্ণসংখ্যা বা ইন্টিজার ইনডেক্স হিসেবে দেওয়া হয়, ফলে ওয়ান-হট রিপ্রেজেন্টেশন তৈরি করার মেমরি খরচের প্রয়োজন হয় না।
কখন ব্যবহার করবেন: Categorical Cross-Entropy-র মতো হুবহু একই ক্ষেত্রে, তবে যেখানে লেবেলগুলো ওয়ান-হট ভেক্টরের বদলে সাধারণ পূর্ণসংখ্যা (যেমন ৩ নম্বর ক্লাস) হিসেবে দেওয়া থাকে।
সুবিধাসমূহ: মেমরি বাচায়, নিজে হাতে ওয়ান-হট এনকোডিং করার ঝামেলা এড়ায়, এবং CCE-র সমান ফলাফল দেয়।
অসুবিধাসমূহ: CCE-র বাইরে অতিরিক্ত কোনো অসুবিধা নেই — এটি মূলত একটি সুবিধাজনক ইমপ্লিমেন্টেশন মাত্র, কোনো ভিন্ন লস ফাংশন নয়।
সহজ কথা: ভুলের বর্গের বা স্কয়ার করার অর্থ হলো ছোট ভুলের জন্য পেনাল্টি খুবই সামান্য হয়, কিন্তু বড় ভুলের জন্য পেনাল্টি গুণিতক হারে অনেক বেশি বেড়ে যায় — যেমন ২ ইউনিটের ভুলের জন্য লস ৪ হলেও, ১০ ইউনিটের ভুলের জন্য লস হবে ১০০। এই কারণে MSE কন্টিনিউয়াস বা বাস্তব সংখ্যা প্রেডিক্ট করার জন্য চমৎকার উপযোগী, যেখানে "কতটুকু ভুল হয়েছে" তা পরিমাপ করা সম্ভব।
কখন ব্যবহার করবেন: regression (regression) টাস্কে — যেমন বাউন্ডিং বক্সের কোঅর্ডিনেট প্রেডিক্ট করা, কি-পয়েন্ট সনাক্ত করা বা যেকোনো বাস্তব সংখ্যা অনুমান করা। ক্লাসিফিকেশনে এটি সাধারণত ব্যবহৃত হয় না।
সুবিধাসমূহ: সহজ, সর্বত্র ব্যবকলনযোগ্য (differentiable), এবং বর্গের কারণে বড় ভুলকে কঠোরভাবে নিয়ন্ত্রণ করে।
অসুবিধাসমূহ: আউটলায়ার বা অতিরিক্ত ভুল মানের প্রতি অত্যন্ত সংবেদনশীল; ক্লাসিফিকেশনের ক্ষেত্রে এটি খুব একটা কার্যকর নয় কারণ Cross-Entropy এ ধরনের ক্ষেত্রে অনেক দ্রুত ও বিশ্বস্তভাবে কনভার্জ করে।
| Loss Function | কাজের ধরণ (Task Type) | লেবেল ফরম্যাট (Label Format) |
|---|---|---|
| Binary Cross-Entropy | ২-ক্লাস ক্লাসিফিকেশন (Binary classification) | একক প্রোবাবিলিটি (০/১) |
| Categorical Cross-Entropy | মাল্টি-ক্লাস, একক-লেবেল | ওয়ান-হট ভেক্টর |
| Sparse Categorical Cross-Entropy | মাল্টি-ক্লাস, একক-লেবেল | পূর্ণসংখ্যা বা ইন্টিজার ইনডেক্স |
| Mean Squared Error | রিগ্রেশন (Regression) | কন্টিনিউয়াস বাস্তব সংখ্যা |
ধরুন, একটি বাইনারি ক্লাসিফায়ার যার আউটপুট লেয়ারে Sigmoid আছে, সেটি এমন একটি নমুনার জন্য প্রেডিক্ট করল যার আসল লেবেল — অর্থাৎ এটি খুবই আত্মবিশ্বাসের সাথে একটি ভুল প্রেডিকশন দিয়েছে।
Binary Cross-Entropy ব্যবহার করলে: , যা একটি বড় লস মান, এবং সবচেয়ে বড় কথা হলো Sigmoid-এর প্রাক-অ্যাক্টিভেশন ইনপুটের সাপেক্ষে BCE-র গ্রেডিয়েন্ট দাঁড়াবে — যা একটি অত্যন্ত শক্তিশালী সিগন্যাল যা প্রেডিকশনকে দ্রুত সঠিক দিকে ঠেলে নিয়ে যায়।
এর বিপরীতে যদি MSE ব্যবহার করা হতো: , যা প্রথম নজরে একটি সাধারণ লস ভ্যালু — কিন্তু এর সাপেক্ষে MSE-র গ্রেডিয়েন্ট হলো , যা পরবর্তীতে Sigmoid-এর নিজস্ব ডেরিভেটিভ দিয়ে গুণ হতে বাধ্য। এই গুণের কারণে গ্রেডিয়েন্টটি সংকুচিত হয়ে প্রায় এ নেমে আসবে — যা BCE-র গ্রেডিয়েন্টের তুলনায় প্রায় দুই গুণিতক বা ১০০ গুণ দুর্বল! ঠিক এই সময়েই যখন মডেলকে সবচেয়ে বড় ধাক্কা দিয়ে সংশোধন করার প্রয়োজন ছিল, তখন গ্রেডিয়েন্ট সিগন্যাল প্রায় নিষ্ক্রিয় হয়ে পড়ে। এটিই হলো মূলত "ক্লাসিফিকেশনে Sigmoid/Softmax এর সাথে কখনো MSE ব্যবহার না করার" পেছনের বাস্তব কারণ।
import numpy as np
def binary_cross_entropy(y_true, y_pred, eps=1e-12):
y_pred = np.clip(y_pred, eps, 1 - eps) # log(0) এড়ানোর জন্য ক্লিপ করা হয়েছে
return -(y_true * np.log(y_pred) + (1 - y_true) * np.log(1 - y_pred))
def categorical_cross_entropy(y_true_onehot, y_pred, eps=1e-12):
y_pred = np.clip(y_pred, eps, 1 - eps)
return -np.sum(y_true_onehot * np.log(y_pred))
def sparse_categorical_cross_entropy(y_true_index, y_pred, eps=1e-12):
return -np.log(np.clip(y_pred[y_true_index], eps, 1 - eps))
def mse(y_true, y_pred):
return np.mean((y_true - y_pred) ** 2)
# গ্রেডিয়েন্টের শক্তির তুলনা: আত্মবিশ্বাসের সাথে ভুল উত্তরের জন্য BCE বনাম MSE
y_true, y_pred = 1.0, 0.01
bce_loss = binary_cross_entropy(y_true, y_pred)
mse_loss = mse(np.array([y_true]), np.array([y_pred]))
# Sigmoid প্রাক-অ্যাক্টিভেশনের সাপেক্ষে লসের গ্রেডিয়েন্ট (চেইন রুল প্রয়োগ করে):
bce_grad_wrt_logit = y_pred - y_true # সরল চমৎকার রূপ
mse_grad_wrt_logit = 2 * (y_pred - y_true) * y_pred * (1 - y_pred)
print(f"BCE লস={bce_loss:.3f}, লজিটের সাপেক্ষে গ্রেডিয়েন্ট={bce_grad_wrt_logit:.4f}")
print(f"MSE লস={mse_loss:.3f}, লজিটের সাপেক্ষে গ্রেডিয়েন্ট={mse_grad_wrt_logit:.4f}")কোডটির কয়েকটি বিশেষ দিক লক্ষ্য করুন:
log(0) তৈরি করবে, যা ঋণাত্মক অসীম — ট্রেনিং লুপের জন্য এটি একটি বড় গাণিতিক ত্রুটি।sparse_categorical_cross_entropy কখনো ওয়ান-হট ভেক্টর তৈরি করে না — এটি স্রেফ সঠিক ক্লাসের ইনডেক্স সরাসরি ব্যবহার করে প্রেডিক্টেড ডিস্ট্রিবিউশন থেকে মানটি টেনে নেয়, যা মেমরি বাচানোর জন্য চমৎকার সাহায্য করে।"Sigmoid → BCE, Softmax → (Sparse) Categorical Cross-Entropy, Linear output → MSE।" আউটপুট অ্যাক্টিভেশনের সাথে সঠিক লস ফাংশনের জোড়া মেলানো পরীক্ষায় এবং প্রজেক্টের কাজে অন্যতম সাধারণ ভুল এড়ানোর মূল মন্ত্র।

ক্লাসিফিকেশন সমস্যার জন্য MSE ব্যবহার করা একটি চিরায়ত ভুল: এর গ্রেডিয়েন্ট ঠিক তখনই দুর্বল হয়ে পড়ে যখন প্রেডিকশনগুলো আত্মবিশ্বাসের সাথে ভুল হয়, যার ফলে Cross-Entropy-র তুলনায় শেখার গতি নাটকীয়ভাবে কমে যায় — কারণ Cross-Entropy ঠিক সেই পরিস্থিতিতেই শক্তিশালী ও সুসামঞ্জস্যপূর্ণ গ্রেডিয়েন্ট তৈরি করে।
Categorical Cross-Entropy ওয়ান-হট ভেক্টর আশা করে; Sparse Categorical Cross-Entropy ইন্টিজার ইনডেক্স আশা করে। যেকোনো একটিতে ভুল লেবেল ফরম্যাট দিলে তা একটি সাধারণ ইমপ্লিমেন্টেশন বাগ তৈরি করে, যা স্পষ্ট কোনো এরর না দেখিয়ে নিঃশব্দে ভুল লস মান দিয়ে যায়।
যেকোনো CNN training run সাজানোর সময় সঠিক loss function বেছে নেওয়াটাই প্রথম দিকের একটা সিদ্ধান্ত, আর এটা প্রায় পুরোপুরি নির্ভর করে task-এর ওপর — binary classification-এ BCE, multi-class classification-এ (Sparse) Categorical Cross-Entropy, আর যেকোনো continuous-valued prediction task-এ (যেমন object detection-এর bounding box regression, pose estimation, depth prediction) MSE বা তার বেশি robust কোনো ভাই (Huber loss-এর মতো) ব্যবহার করা হয়। এই জুটিটা সঠিকভাবে মেলানো, আর সঠিক output activation-এর সাথে সেটা মিলিয়ে নেওয়া — এটাই প্রায়ই একটা মডেল স্বাভাবিকভাবে train হওয়া আর architecture-এর সাথে কোনো সম্পর্কই নেই এমন কারণে plateau করে থাকার মধ্যেকার পার্থক্য গড়ে দেয়।