মেশিন লার্নিং-এ নিউমেরিক্যাল মেথডস — অপ্টিমাইজেশনের সংযোগ
এই পাঠে যা শিখবেন
- কেন মেশিন লার্নিং মডেল প্রশিক্ষণ মূলত একটি অপ্টিমাইজেশন সমস্যা
- M9/L43-এর গ্র্যাডিয়েন্ট ডিসেন্ট কীভাবে "লস ফাংশন মিনিমাইজ করা"-র সাথে সরাসরি যুক্ত
- একটি সত্যিকারের, চলমান কোড ডেমো — একটি টয় মিন-স্কয়ার্ড-এরর লস মিনিমাইজ করে একটি প্যারামিটার ফিট করা
- কেন এই পরিচিতি সম্পূর্ণ ML/DL কোর্স প্রতিস্থাপন করে না, বরং তাদের বোঝার একটি নিউমেরিক্যাল ভিত্তি দেয়
১ · মডেল প্রশিক্ষণ = অপ্টিমাইজেশন
একটি মেশিন লার্নিং মডেল (একটি লিনিয়ার রিগ্রেশন, একটি নিউরাল নেটওয়ার্ক — যেকোনো কিছু) কিছু অভ্যন্তরীণ প্যারামিটার (ওজন) দিয়ে তৈরি। "প্রশিক্ষণ" মানে এই প্যারামিটারগুলোর মান বেছে নেওয়া যাতে মডেলের প্রেডিকশন বাস্তব ডেটার সাথে যতটা সম্ভব মিলে যায়। এই "কতটা মিলছে না" পরিমাপ করার ফাংশনকে বলা হয় লস ফাংশনLoss Function — মডেলের প্রেডিকশন ও প্রকৃত মানের মধ্যে পার্থক্য পরিমাপকারী একটি ফাংশন; যত ছোট, মডেল তত ভালো ফিট করছে। — এবং প্রশিক্ষণ মানে এই লস ফাংশনকে প্যারামিটারগুলোর একটি ফাংশন হিসেবে দেখে, তার মিনিমাম খুঁজে বের করা। এটি ঠিক M9-এ শেখা অপ্টিমাইজেশন সমস্যা — শুধু এখানে "ফাংশন" টি একটি লস ফাংশন এবং "ভেরিয়েবল"-গুলো মডেলের ওজন।
M4/L20-এ শেখা লিস্ট-স্কয়ার্স ফিটিং আসলে একটি অপ্টিমাইজেশন সমস্যা যার একটি সরাসরি (closed-form) সমাধান আছে — কিন্তু একই সমস্যা গ্র্যাডিয়েন্ট ডিসেন্ট দিয়েও ইটারেটিভভাবে সমাধান করা যায়।
লক্ষ লক্ষ ওজন থাকা নিউরাল নেটওয়ার্কে কোনো closed-form সমাধান নেই — গ্র্যাডিয়েন্ট ডিসেন্ট (ও এর ভ্যারিয়েন্ট, যেমন Adam) ই একমাত্র ব্যবহারিক পথ।
নিউরাল নেটওয়ার্কে গ্র্যাডিয়েন্ট গণনার দক্ষ পদ্ধতি ("ব্যাকপ্রোপ") মূলত চেইন-রুল প্রয়োগ করে প্রতিটি ওজনের জন্য লসের গ্র্যাডিয়েন্ট বের করে — Deep Learning কোর্সে বিস্তারিত।
Machine Learning কোর্স মডেল-নির্দিষ্ট ধারণা (রিগ্রেশন, ক্লাসিফিকেশন, ফিচার ইঞ্জিনিয়ারিং) শেখায়, এবং Deep Learning কোর্স নিউরাল নেটওয়ার্ক আর্কিটেকচার ও ব্যাকপ্রোপাগেশন বিস্তারিতভাবে কভার করে — এই পাঠ সেই দুটো কোর্সের ট্রেনিং লুপের ভিতরে ঠিক কোন নিউমেরিক্যাল অ্যালগরিদম চলছে (গ্র্যাডিয়েন্ট ডিসেন্ট, M9/L43-এ শেখা) তা সংক্ষেপে সংযুক্ত করে, পুরো বিষয়টি পুনরায় শেখায় না।
২ · একটি সত্যিকারের ডেমো — টয় লস ফাংশন মিনিমাইজ করা
ধরা যাক আমাদের কাছে কিছু ডেটা পয়েন্ট (x, y) আছে যেখানে প্রকৃত সম্পর্কটি প্রায়
y ≈ w·x (একটি একক প্যারামিটার w, উৎপত্তি-বিন্দু দিয়ে যাওয়া একটি সরলরেখা)।
লক্ষ্য: মিন-স্কয়ার্ড-এরর (MSE) লস মিনিমাইজ করে সবচেয়ে ভালো w খুঁজে বের করা:
$$ L(w) = \frac{1}{n}\sum_{i=1}^{n} (w\,x_i - y_i)^2, \qquad \frac{dL}{dw} = \frac{2}{n}\sum_{i=1}^{n} (w\,x_i - y_i)\,x_i $$
এই গ্র্যাডিয়েন্ট dL/dw ঠিক M9/L43-এর গ্র্যাডিয়েন্ট ডিসেন্ট আপডেট রুলে ব্যবহৃত হবে:
w ← w − লার্নিং-রেট × গ্র্যাডিয়েন্ট। নিচের কোড সেলে একটি ছোট সিন্থেটিক ডেটাসেট
(প্রকৃত w_true = 3.0 দিয়ে সামান্য এলোমেলো নয়েজ যোগ করে তৈরি) থেকে শুরু করে w = 0
থেকে গ্র্যাডিয়েন্ট ডিসেন্ট চালিয়ে সত্যিকারের প্রতি-ইটারেশন লস কমে যাওয়া দেখানো হয়েছে।
import random
# টয় ডেটাসেট: y প্রায় = 3*x (একটি প্রকৃত প্যারামিটার, w_true = 3.0)
random.seed(7)
xs = [0.5, 1.0, 1.5, 2.0, 2.5, 3.0]
w_true = 3.0
ys = [w_true * x + random.uniform(-0.3, 0.3) for x in xs]
print("ডেটা পয়েন্ট (x, y):")
for x, y in zip(xs, ys):
print(f" ({x:.2f}, {y:.4f})")
def mse_loss(w):
n = len(xs)
return sum((w * xs[i] - ys[i]) ** 2 for i in range(n)) / n
def grad(w):
n = len(xs)
return sum(2 * (w * xs[i] - ys[i]) * xs[i] for i in range(n)) / n
w = 0.0 # প্রাথমিক অনুমান
lr = 0.05 # লার্নিং রেট
n_iters = 25
print()
print(f"{'ইটারেশন':>8} | {'w':>10} | {'লস':>10} | {'গ্র্যাডিয়েন্ট':>12}")
for i in range(n_iters + 1):
L = mse_loss(w)
g = grad(w)
if i % 5 == 0 or i == n_iters:
print(f"{i:8d} | {w:10.6f} | {L:10.6f} | {g:12.6f}")
if i < n_iters:
w = w - lr * g
print()
print(f"{n_iters} ইটারেশন পর চূড়ান্ত w: {w:.6f} (ডেটা তৈরিতে ব্যবহৃত প্রকৃত ঢাল: {w_true})")
print(f"চূড়ান্ত লস: {mse_loss(w):.6f}")
w = 0-এ লস ≈ 33.32,
৫ ইটারেশন পরই তা নেমে আসে ≈ 0.30-এ, এবং ২৫ ইটারেশন পর w ≈ 2.9636-এ স্থিতিশীল
হয় (প্রকৃত w_true = 3.0-এর খুব কাছাকাছি), চূড়ান্ত লস ≈ 0.0177। গ্র্যাডিয়েন্টের
মানও ধারাবাহিকভাবে শূন্যের কাছে যাচ্ছে (−22.47 → −2.07 → −0.19 → ... → −0.00015) — এটাই
গ্র্যাডিয়েন্ট ডিসেন্টের সংজ্ঞাগত আচরণ: গ্র্যাডিয়েন্ট শূন্যের কাছাকাছি মানে লস ফাংশনের একটি স্থানীয়
মিনিমামের কাছাকাছি পৌঁছানো।
একটি বাস্তব ML মডেলে (যেমন হাজার হাজার ওজনের একটি নিউরাল নেটওয়ার্ক) এই একই লুপ চলে — শুধু
w-এর বদলে একটি বিশাল ভেক্টর, আর grad(w)-এর বদলে ব্যাকপ্রোপাগেশন দিয়ে গণনা করা
একটি গ্র্যাডিয়েন্ট ভেক্টর। M9/L43-এ যেমন দেখানো হয়েছিল, লার্নিং রেট খুব বড় হলে এই একই লুপ ডাইভার্জ
করতে পারে — এই ঝুঁকিটি প্র্যাকটিক্যাল ML প্রশিক্ষণেও ঠিক একইভাবে থাকে, তাই লার্নিং-রেট বাছাই একটি
গুরুত্বপূর্ণ ব্যবহারিক সিদ্ধান্ত।
একটি ML লাইব্রেরির model.fit() বা loss.backward(); optimizer.step()-এর মতো
একলাইনের কল আসলে এই কোর্সের M9-এ শেখা অ্যালগরিদমেরই (গ্র্যাডিয়েন্ট ডিসেন্ট, বা এর উন্নত ভ্যারিয়েন্ট)
একটি বৃহৎ-স্কেল, সুচারুভাবে ইঞ্জিনিয়ারড বাস্তবায়ন। নিউমেরিক্যাল মেথডসের ভিত্তি বুঝলে
Machine Learning ও
Deep Learning কোর্সের "ব্ল্যাক-বক্স" ট্রেনিং প্রক্রিয়া আর
রহস্যময় থাকে না — এটি ঠিক এই কোর্স জুড়ে শেখা ইটারেটিভ, কনভারজেন্স-চালিত অ্যালগরিদমেরই একটি প্রয়োগ।
ভাবনার প্রশ্ন
প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।
প্র ০১
কোড সেলে চূড়ান্ত w ≈ 2.9636 হয়েছে, ঠিক 3.0 নয় কেন?
দুটো কারণ। প্রথমত, ডেটা তৈরির সময় প্রতিটি y-তে সামান্য এলোমেলো নয়েজ (±0.3)
যোগ করা হয়েছিল — তাই "সেরা ফিট" মানে ঠিক w_true নয়, বরং সেই নয়েজি ডেটাতেই সবচেয়ে কম
MSE দেওয়া w। দ্বিতীয়ত, গ্র্যাডিয়েন্ট ডিসেন্ট একটি ইটারেটিভ মেথড — মাত্র ২৫ ইটারেশন পর
গ্র্যাডিয়েন্ট এখনো ঠিক শূন্য নয় (≈ −0.00015), তাই এটি এখনো মিনিমামের খুব কাছে কিন্তু
ঠিক পৌঁছায়নি — আরও ইটারেশন চালালে আরও কাছে যেত।
প্র ০২
এই উদাহরণে মাত্র একটি প্যারামিটার (w) ছিল। একটি বাস্তব নিউরাল নেটওয়ার্কে লক্ষ লক্ষ
প্যারামিটার থাকে — এতে গ্র্যাডিয়েন্ট ডিসেন্ট প্রয়োগ করতে মূলত কী বদলাতে হবে বলে আপনার মনে হয়?
মূলনীতি একই থাকে — শুধু w একটি একক সংখ্যার বদলে একটি বিশাল ভেক্টর (বা একাধিক ভেক্টর/
ম্যাট্রিক্সের সংগ্রহ) হয়ে যায়, আর গ্র্যাডিয়েন্টও একই আকৃতির একটি ভেক্টর — প্রতিটি প্যারামিটারের জন্য
পৃথক আংশিক ডেরিভেটিভ। ব্যবহারিকভাবে এই বিশাল গ্র্যাডিয়েন্ট ভেক্টর দক্ষভাবে গণনা করাই মূল চ্যালেঞ্জ
(ব্যাকপ্রোপাগেশন অ্যালগরিদম এই সমস্যা সমাধান করে) — আপডেট রুল w ← w − lr·গ্র্যাডিয়েন্ট
ধারণাগতভাবে অভিন্ন থাকে।
প্র ০৩ M4/L20-এ লিস্ট-স্কয়ার্স ফিটিং একটি সরাসরি (closed-form) সূত্র দিয়ে সমাধান করা হয়েছিল — কোনো ইটারেশন ছাড়াই। তাহলে এই একই ধরনের সমস্যার জন্য গ্র্যাডিয়েন্ট ডিসেন্টের মতো একটি ধীর, ইটারেটিভ মেথড কেন ব্যবহার করা হয়?
ছোট, সরল লিনিয়ার রিগ্রেশন সমস্যার জন্য closed-form সমাধানই (নরমাল ইকুয়েশন) দ্রুততর ও বেশি সঠিক — এখানে গ্র্যাডিয়েন্ট ডিসেন্ট শুধু শিক্ষামূলক উদাহরণ হিসেবে ব্যবহার করা হয়েছে যাতে M9-এর সাথে সংযোগ স্পষ্ট হয়। কিন্তু একটি নিউরাল নেটওয়ার্কের মতো জটিল, নন-লিনিয়ার মডেলের জন্য এমন কোনো closed-form সূত্র নেই (M9-এর সূচনায় যেমন বলা হয়েছিল) — সেখানে গ্র্যাডিয়েন্ট ডিসেন্টের মতো ইটারেটিভ মেথডই একমাত্র ব্যবহারিক উপায়।
অনুশীলন
-
চিন্তা করুন: কোড সেলে লার্নিং রেট
lr = 0.05-কেlr = 0.5-এ বাড়ালে (M9/L43-এ শেখা প্যাটার্ন অনুযায়ী) কী ঘটবে বলে আপনার ধারণা?M9/L43-এ দেখানো হয়েছিল অতিরিক্ত বড় লার্নিং রেট গ্র্যাডিয়েন্ট ডিসেন্টকে মিনিমামের চারপাশে দোদুল্যমান (oscillate) করে তুলতে পারে বা এমনকি ডাইভার্জ করাতে পারে, কনভার্জ করার বদলে। এই টয় সমস্যার জন্য
lr = 0.5হয়তো এখনো কনভার্জ করবে (কারণ ডেটা ছোট ও ভালোভাবে স্কেলড), কিন্তু দোলন (oscillation) দেখা যেতে পারে — সরাসরি একঘেয়ে (monotonic) কমার বদলে। -
পরীক্ষা করুন: কোড সেলে
lr = 0.05-কেlr = 0.5-এ পরিবর্তন করে Run চেপে আপনার অনুমান যাচাই করুন — লস কি এখনো মসৃণভাবে কমছে, নাকি লাফাচ্ছে?lr = 0.5-এ প্রথম কয়েক ইটারেশনেw-এর মান লক্ষ্যমাত্রা3.0-এর চারপাশে বড় বড় লাফ দেয় (উদাহরণস্বরূপ শুরুতে অতিরিক্ত বড় গ্র্যাডিয়েন্ট-ধাপ), কিন্তু এই নির্দিষ্ট ছোট, ভালোভাবে-কন্ডিশনড টয় সমস্যায় সাধারণত তারপরও দ্রুত স্থিতিশীল হয়ে যায় — লার্নিং রেট আরও বড় করলে (যেমনlr = 2.0বা তার বেশি) প্রকৃত ডাইভার্জেন্স দেখা যাওয়ার সম্ভাবনা বাড়ে, ঠিক M9/L43-এর ডেমোর মতো।
আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ
- গ্র্যাডিয়েন্ট ডিসেন্ট আবার দেখুন M9 · L43 লার্নিং-রেট নির্বাচনের প্রভাব ও কনভার্জিং/ডাইভার্জিং উদাহরণ বিস্তারিতভাবে দেখানো হয়েছে।
- Machine Learning কোর্স সহোদর কোর্স রিগ্রেশন, ক্লাসিফিকেশন ও ফিচার ইঞ্জিনিয়ারিং সহ মডেল-নির্দিষ্ট ধারণা — এখানে শেখা অপ্টিমাইজেশন ভিত্তির উপরে তৈরি।
- Deep Learning কোর্স সহোদর কোর্স নিউরাল নেটওয়ার্ক আর্কিটেকচার ও ব্যাকপ্রোপাগেশন — গ্র্যাডিয়েন্ট ডিসেন্ট যেখানে বৃহৎ স্কেলে প্রয়োগ হয়।