Chapter 26 of 28
The bugs and misconceptions that trip up almost everyone
পরীক্ষায়, চাকরির ইন্টারভিউতে বা বাস্তব জীবনের প্রজেক্টে একটি সাধারণ উত্তর বনাম চমৎকার উত্তরের মধ্যকার মূল ব্যবধানটি গড়ে ওঠে কিছু নিয়মিত ভুলের ধারণা এড়ানোর ক্ষমতার ওপর। এর কোনোটিই খুব বিরল ভুল নয়; এগুলো এমন কিছু ভুল যা শিখতে গিয়ে প্রায় প্রত্যেকেই অন্তত একবার না একবার করে বসেন। যেকোনো পরীক্ষা বা ইন্টারভিউতে বসার আগে এই তালিকাটি একবার রিভিশন দিয়ে নিন, এবং আপনার কোড রান করার আগে মিলিয়ে দেখুন কোনো ভুল আপনার অজান্তেই রয়ে গেছে কিনা।
Kernel size (৩×৩, ৫×৫ ইত্যাদি) একটি ফিল্টারের স্থানিক বা spatial আকার প্রকাশ করে — অর্থাৎ এটি একবারে ছবির কতটা লোকাল প্রতিবেশ দেখতে পারে। আর ওজনের ফিল্টার সংখ্যা (number of filters) সম্পূর্ণ পৃথক একটি হাইপারপ্যারামিটার যা নির্দেশ করে লেয়ারটি কতগুলো ভিন্ন ভিন্ন ফিল্টার শিখবে, যা আউটপুটের চ্যানেল সংখ্যাও নির্ধারণ করে। Conv2d(64, kernel_size=3) এর মতো লেয়ার সংজ্ঞা পড়ার সময় নতুনরা প্রায়শই এ দুটি গুলিয়ে ফেলেন, কিন্তু এরা সম্পূর্ণ ভিন্ন প্রশ্নের উত্তর দেয়: কার্নেল সাইজ নিয়ন্ত্রণ করে একটি ফিল্টার কী দেখতে পাবে; আর ফিল্টার সংখ্যা নিয়ন্ত্রণ করে লেয়ারটি কতগুলো সম্পূর্ণ আলাদা ফিচার ম্যাপ সনাক্ত করতে পারবে।
Pooling layer (Max অথবা Average) একটি নির্দিষ্ট, শেখা-নয় এমন অপারেশন প্রয়োগ করে — এখানে ট্রেইন করার মতো কিছুই নেই। কখনো কখনো শিক্ষার্থীরা পরীক্ষায় নেটওয়ার্কের মোট প্যারামিটার গণনা করার সময় "পুলিং প্যারামিটার" গোনার চেষ্টা করেন, কিন্তু সঠিক অবদান সবসময় শূন্য। আপনার প্যারামিটার-গণনার হিসাবে যদি কোনো পুলিং লেয়ারের জন্য অশূন্য কোনো মান থাকে, তবে সেটিই ভুল।
Mean Squared Error মূলত রিগ্রেশনের জন্য তৈরি, যেখানে আউটপুট কন্টিনিউয়াস বা ধারাবাহিক পরিমাণ। এটিকে ক্লাসিফিকেশনে প্রয়োগ করলে — যেখানে টার্গেট একটি ক্লাস লেবেল বা ওয়ান-হট ভেক্টর — তা Cross-Entropy-র তুলনায় অনেক দুর্বল গ্রেডিয়েন্ট তৈরি করে, বিশেষ করে যখন প্রেডিকশন আত্মবিশ্বাসের সাথে ভুল হয়, এবং এতে ট্রেনিং ধীরগতির ও কম স্থিতিশীল হয়ে যায়। ক্লাসিফিকেশনের জন্য Cross-Entropy-ই ডিফল্ট লস হওয়া উচিত; MSE শুধুমাত্র তখনই ব্যবহার করুন যখন আপনি সত্যিকারের কোনো কন্টিনিউয়াস মান প্রেডিক্ট করছেন।
Softmax মূলত পারস্পরিক exclusive মাল্টি-ক্লাস সমস্যার জন্য (Sparse) Categorical Cross-Entropy-র সাথে জোড়া বাঁধার জন্য তৈরি; আর Sigmoid বাইনারি বা মাল্টি-লেবেল সমস্যার জন্য Binary Cross-Entropy-র সাথে জোড়া বাঁধে। এদের গুলিয়ে ফেলা — যেমন Categorical Cross-Entropy-র সাথে একটি Sigmoid আউটপুট লেয়ার ব্যবহার করা — এই জোড়াটির কাছ থেকে প্রত্যাশিত পরিষ্কার গ্রেডিয়েন্ট সম্পর্ক ভেঙে দেয় এবং ভুল, অস্থির আচরণের ট্রেনিং তৈরি করে। আপনার লস যদি প্রত্যাশামতো কমছে না মনে হয়, তবে সবার আগে এই জোড়াটিই যাচাই করুন।
নরমালাইজেশন স্ট্যাটিস্টিক্স — যেমন পিক্সেল মান স্কেল করতে ব্যবহৃত গড় ও স্ট্যান্ডার্ড ডেভিয়েশন — সম্পূর্ণ ডেটাসেট থেকে, টেস্ট সেটসহ, হিসাব করলে টেস্ট ডেটার তথ্য ট্রেনিংয়ে লিক হয়ে যায়। এটি আপনার রিপোর্ট করা অ্যাকুরেসিকে এমনভাবে বাড়িয়ে দেয় যা সত্যিকারের অদেখা ডেটাতে টিকবে না। প্রিপ্রসেসিং স্ট্যাটিস্টিক্স সবসময় শুধুমাত্র ট্রেনিং সেট থেকে হিসাব করা উচিত, তারপর অপরিবর্তিতভাবে ভ্যালিডেশন ও টেস্ট সেটে প্রয়োগ করা উচিত।
নেটওয়ার্ককে একটি নির্দিষ্ট, সাজানো ক্রমে ডেটা দেওয়া — যেমন আগে ক্লাস ১-এর সব ছবি, তারপর ক্লাস ২-এর সব ছবি, এভাবে — মানে প্রতিটি মিনি-ব্যাচ সামগ্রিক ডেটা ডিস্ট্রিবিউশনের একদমই প্রতিনিধিত্বমূলক থাকে না। এটি প্রতি ধাপে গ্রেডিয়েন্ট এস্টিমেটকে পক্ষপাতদুষ্ট করে এবং ট্রেনিংকে মারাত্মকভাবে অস্থিতিশীল করে তুলতে পারে। প্রতি epoch-এর আগে শাফল করা (অথবা শাফলিং ডেটা লোডার ব্যবহার করা) একটি ছোট, সহজে ভুলে যাওয়া ধাপ যা দেখতে যতটা তুচ্ছ মনে হয় তার চেয়ে অনেক বেশি গুরুত্বপূর্ণ।
অতিরিক্ত বেশি লার্নিং রেট লসকে প্রচণ্ডভাবে দোলাতে থাকে বা একেবারে ডাইভার্জ করিয়ে দেয়, প্রতি ধাপে ভালো সমাধান ছাড়িয়ে যায়। খুব কম লার্নিং রেট ট্রেনিংকে যন্ত্রণাদায়কভাবে ধীর করে দেয়, অথবা এটি থামার অনেক আগেই লস সারফেসের কোনো অগভীর অঞ্চলে আটকে যেতে পারে। কোনো সার্বজনীনভাবে সঠিক মান নেই — সবসময় ট্রেনিং লস কার্ভ পর্যবেক্ষণ করে সমন্বয় করুন, অথবা একবার আন্দাজ করে এগিয়ে যাওয়ার বদলে একটি লার্নিং রেট ফাইন্ডার বা শিডিউলার ব্যবহার করুন।
ট্রেনিংয়ের সময় Dropout ও Batch Normalization ইনফারেন্সের তুলনায় ভিন্নভাবে আচরণ করে — Dropout-এর এলোমেলোভাবে নিউরন নিষ্ক্রিয় করা বন্ধ করে দেওয়া উচিত, এবং Batch Normalization-এর ব্যাচ স্ট্যাটিস্টিক্সের বদলে তার সংরক্ষিত running স্ট্যাটিস্টিক্স ব্যবহারে পরিবর্তন হওয়া উচিত। ফ্রেমওয়ার্কগুলো আপনাকে স্পষ্টভাবে এটি সিগন্যাল করতে বলে (যেমন PyTorch-এ model.eval())। এটি ভুলে গেলে আপনার ভ্যালিডেশন বা টেস্ট ফলাফল আসলে যে মডেলটি আপনি ডেপ্লয় করতে চান তার বদলে একটি অর্ধ-ট্রেইন করা, এলোমেলোভাবে বিচ্যুত নেটওয়ার্কের প্রতিফলন ঘটায়।
ওজন শেয়ারিং CNN-কে আনুমানিক translation ইনভ্যারিয়েন্স দেয় — একটি প্যাটার্ন যেখানেই দেখা যাক না কেন সনাক্ত হয়। এটি স্বয়ংক্রিয়ভাবে rotation বা scale ইনভ্যারিয়েন্স দেয় না; সোজা দাঁড়ানো একটি বিড়ালের কান সনাক্ত করার জন্য ট্রেইন করা একটি ফিল্টার স্বয়ংক্রিয়ভাবে ৯০ ডিগ্রি ঘোরানো বা অর্ধেক আকারে সংকুচিত করা একই কান চিনতে পারে না। rotation বা scale-এর প্রতি যেকোনো দৃঢ়তা স্পষ্টভাবে তৈরি করে দিতে হয়, সাধারণত সেই ট্রান্সফরমেশনগুলো কভার করা ডেটা অগমেন্টেশনের মাধ্যমে, অথবা এর জন্য বিশেষভাবে ডিজাইন করা আর্কিটেকচারের মাধ্যমে।
ভ্যালিডেশন সেট থাকে সিদ্ধান্তে গাইড করার জন্য — হাইপারপ্যারামিটার টিউনিং, ট্রেনিং কখন থামাবেন তা বেছে নেওয়া, আর্কিটেকচারের মধ্যে থেকে বেছে নেওয়া। বারবার ভ্যালিডেশন পারফরম্যান্সের ওপর ভিত্তি করে সিদ্ধান্ত নিলে সরাসরি এর ওপর ট্রেইন না করেও পরোক্ষভাবে ভ্যালিডেশন সেটের প্রতিই "ওভারফিট" করে ফেলতে পারেন। শুধুমাত্র এমন একটি টেস্ট সেট যা সেই সিদ্ধান্ত গ্রহণ প্রক্রিয়ার কোনো অংশেই স্পর্শ করা হয়নি, তা মডেলটি সত্যিকারের নতুন ডেটাতে কেমন পারফর্ম করবে তার একটি ন্যায্য, চূড়ান্ত অনুমান দিতে পারে।
পরীক্ষা বা ইন্টারভিউয়ের আগে, এই তালিকাটি আরেকবার ঘুরে দেখা এবং সৎভাবে নিজেকে জিজ্ঞাসা করা মূল্যবান যে আপনি নিজের কোড বা নিজের উত্তরে এই ভুলগুলোর প্রতিটি ধরতে পারতেন কিনা। এই দশটি ভুল ধারাবাহিকভাবে একটি ভালো উত্তর ও একটি চমৎকার উত্তরের মধ্যে পার্থক্য গড়ে দেয় — কারণ এগুলো বুঝতে কঠিন বলে নয়, বরং মুহূর্তের মধ্যে ভুলে যাওয়া সহজ বলে।