অপ্টিমাইজেশনের জন্য নিউটনের মেথড
এই পাঠে যা শিখবেন
- অপ্টিমাইজেশনের জন্য নিউটনের মেথডের আপডেট রুল এবং এটি কীভাবে দ্বিতীয় ডেরিভেটিভ ব্যবহার করে
- কেন এই মেথড কোয়াড্রেটিক ফাংশনে তাত্ত্বিকভাবে এক ধাপেই সমাধান দেয়
- নন-কোয়াড্রেটিক ফাংশনে কোয়াড্রেটিক কনভারজেন্স কীভাবে সত্যিকারের গণনা করা এরর-সিকোয়েন্সে দেখা যায়
- নিউটনের মেথডের সীমাবদ্ধতা — কখন এটি ব্যর্থ হতে পারে বা ব্যবহারযোগ্য নয়
১ · আপডেট রুল — দ্বিতীয় ডেরিভেটিভ কেন প্রয়োজন
M2/L07-এ আমরা দেখেছিলাম নিউটন-রাফসন f(x) = 0-এর রুট খুঁজতে f'(x) ব্যবহার
করে। অপ্টিমাইজেশনে আমরা f-এর মিনিমাম খুঁজি, এবং ক্যালকুলাস থেকে জানি মিনিমামে
f'(x) = 0 হয় — তাই আমরা আসলে f'(x) = 0-এর রুট খুঁজছি! নিউটন-রাফসনকে
সরাসরি f'-এর উপর প্রয়োগ করলে (যার ডেরিভেটিভ f'') পাওয়া যায়:
$$ x_{n+1} = x_n - \frac{f'(x_n)}{f''(x_n)} $$
f''(x) (দ্বিতীয় ডেরিভেটিভ) ফাংশনের বক্রতা পরিমাপ করে — এটি জানা থাকলে
মেথডটি প্রতি ধাপে ফাংশনটিকে স্থানীয়ভাবে একটি কোয়াড্রেটিক (প্যারাবোলা) দিয়ে আনুমানিক করে,
এবং সরাসরি সেই প্যারাবোলার মিনিমামে লাফ দেয় — গ্র্যাডিয়েন্ট ডিসেন্টের ছোট ছোট ধাপের বদলে একটি
বুদ্ধিদীপ্ত, বড় লাফ। বহু-চলক ক্ষেত্রে f''(x)-এর জায়গায় হেসিয়ান ম্যাট্রিক্স
(দ্বিতীয়-ক্রম আংশিক ডেরিভেটিভের ম্যাট্রিক্স) এবং তার ইনভার্স ব্যবহার করা হয়:
x_{n+1} = x_n - H^{-1} \nabla f(x_n)।
২ · ডেমো ১ — L43-এর একই কোয়াড্রেটিক ফাংশনে
L43-এর টেস্ট ফাংশন f(x, y) = (x-3)² + (y+2)² + 5-এর হেসিয়ান ম্যাট্রিক্স ধ্রুবক:
H = [[2, 0], [0, 2]] (কারণ উভয় পদই খাঁটি কোয়াড্রেটিক)। এর ইনভার্স
H⁻¹ = [[0.5, 0], [0, 0.5]] — যেহেতু বক্রতা ধ্রুবক, নিউটনের মেথডের কোয়াড্রেটিক-অ্যাপ্রক্সিমেশন
এখানে নিখুঁতভাবে সঠিক, তাই তাত্ত্বিকভাবে মাত্র এক ধাপেই সঠিক মিনিমামে পৌঁছানোর কথা।
import math
def f(x, y):
return (x - 3)**2 + (y + 2)**2 + 5
def grad_f(x, y):
return (2*(x - 3), 2*(y + 2))
def hessian_inv_apply(gx, gy):
# H = [[2,0],[0,2]] -> H_inverse = [[0.5,0],[0,0.5]]
return (0.5 * gx, 0.5 * gy)
x, y = 0.0, 0.0
print(f"iter 0: x={x:.6f} y={y:.6f} f={f(x, y):.6f}")
gx, gy = grad_f(x, y)
dx, dy = hessian_inv_apply(gx, gy)
x, y = x - dx, y - dy
print(f"iter 1: x={x:.6f} y={y:.6f} f={f(x, y):.6f}")
gx2, gy2 = grad_f(x, y)
gnorm = math.sqrt(gx2**2 + gy2**2)
print(f"গ্র্যাডিয়েন্ট নর্ম iter 1-এ = {gnorm:.10f} (কনভার্জ করেছে!)")
x = 3.000000, y = -2.000000-এ
পৌঁছায়, গ্র্যাডিয়েন্ট নর্ম ০.০০০০০০০০০০ — L43-এর গ্র্যাডিয়েন্ট ডিসেন্ট (lr=0.1)
একই ফাংশনে ৭১ ইটারেশন নিয়েছিল। এই নাটকীয় পার্থক্যের কারণ: একটি খাঁটি কোয়াড্রেটিক
ফাংশনের জন্য নিউটনের মেথডের অভ্যন্তরীণ "লোকাল প্যারাবোলা" অ্যাপ্রক্সিমেশন নিখুঁতভাবে সঠিক —
এটি কোনো আনুমানিকতা নয়, বাস্তব ফাংশনটিই একটি প্যারাবোলা।
৩ · ডেমো ২ — একটি হার্ডার, নন-কোয়াড্রেটিক ফাংশনে
বাস্তব ফাংশন সাধারণত খাঁটি কোয়াড্রেটিক নয়, তাই নিউটনের মেথড সাধারণত এক ধাপে নয়, বরং কয়েক ধাপে
কনভার্জ করে — কিন্তু তখনও এটি "কোয়াড্রেটিক কনভারজেন্স" দেখায় (প্রতি ধাপে এরর মোটামুটি স্কয়ার হয়ে
যায়)। টেস্ট ফাংশন: g(x) = (x-3)⁴ + (x-3)² + 1, যার মিনিমাম x = 3-এ
(g'(x) = 4(x-3)³ + 2(x-3), g''(x) = 12(x-3)² + 2)। শুরুর বিন্দু
x₀ = 0।
def g(x):
return (x - 3)**4 + (x - 3)**2 + 1
def gprime(x):
return 4*(x - 3)**3 + 2*(x - 3)
def gdouble(x):
return 12*(x - 3)**2 + 2
def newton_1d(x0, tol=1e-10, max_iter=100):
x = x0
for i in range(max_iter):
err = abs(x - 3)
print(f"iter {i}: x={x:.8f} g(x)={g(x):.6f} |x-3|={err:.10f}")
gp = gprime(x)
if abs(gp) < tol:
return i, x
x_new = x - gp / gdouble(x)
if abs(x_new - x) < 1e-12:
return i + 1, x_new
x = x_new
return max_iter, x
def gd_1d(x0, lr, tol=1e-6, max_iter=1000):
x = x0
for i in range(max_iter):
gp = gprime(x)
if abs(gp) < tol:
return i, x
x = x - lr * gp
return max_iter, x
n_newton, x_newton = newton_1d(0.0)
print(f"\nNewton কনভার্জ করল {n_newton} ইটারেশনে, x = {x_newton:.10f}")
n_gd, x_gd = gd_1d(0.0, lr=0.05)
print(f"Gradient Descent (lr=0.05) কনভার্জ করল {n_gd} ইটারেশনে, x = {x_gd:.10f}")
x ≈ 3.0000000000), যেখানে গ্র্যাডিয়েন্ট
ডিসেন্ট (lr = 0.05) একই ফাংশনে লাগায় ১৩৪ ইটারেশন — প্রায় ১৭ গুণ বেশি।
এরর-সিকোয়েন্স লক্ষ্য করুন: শুরুতে |x-3| = 3.0 → 1.96 → 1.25 →
... ধীরে কমে, কিন্তু মিনিমামের কাছাকাছি পৌঁছে (ইটারেশন ৫ থেকে ৭) এরর নাটকীয়ভাবে দ্রুত কমে যায়
(0.1244 → 0.00705 → 0.0000014) — এটাই কোয়াড্রেটিক
কনভারজেন্স-এর বৈশিষ্ট্য: রুটের কাছাকাছি একবার পৌঁছালে, প্রতি ধাপে সঠিক ডিজিটের সংখ্যা প্রায়
দ্বিগুণ হয়ে যায় (M2/L07-এ একই ঘটনা রুট-ফাইন্ডিংয়ের প্রেক্ষাপটে দেখা গিয়েছিল)।
নিউটনের মেথড দ্বিতীয় ডেরিভেটিভ ব্যবহার করে গ্র্যাডিয়েন্ট ডিসেন্টের চেয়ে অনেক দ্রুত কনভার্জ করে — কিন্তু
এই গতির একটি দাম আছে: প্রতি ধাপে f''(x) (বা বহু-চলকে সম্পূর্ণ হেসিয়ান ম্যাট্রিক্স এবং তার
ইনভার্স) গণনা করতে হয়, যা বড় সমস্যায় ব্যয়বহুল হতে পারে, এবং যদি f''(x) শূন্যের কাছাকাছি
হয় বা ফাংশনটি "কনভেক্স" (উপরের দিকে বাঁকানো) না হয়, তাহলে মেথডটি ব্যর্থ হতে পারে বা ভুল দিকে (মিনিমামের
বদলে ম্যাক্সিমামের দিকে) যেতে পারে — ঠিক যেমন M2/L07-এ নিউটন-রাফসন কখনো কখনো ব্যর্থ হতো।
ভাবনার প্রশ্ন
প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।
প্র ০১ ডেমো ১-এ নিউটনের মেথড মাত্র এক ইটারেশনে সঠিক মিনিমামে পৌঁছেছে। এটি কি বাস্তব-বিশ্বের বেশিরভাগ অপ্টিমাইজেশন সমস্যায় ঘটবে বলে আপনি মনে করেন?
না — এই এক-ধাপ কনভারজেন্স ঘটেছে কারণ টেস্ট ফাংশনটি খাঁটি কোয়াড্রেটিক ছিল (ধ্রুবক বক্রতা), যেখানে
নিউটনের মেথডের অভ্যন্তরীণ প্যারাবোলা-অ্যাপ্রক্সিমেশন নিখুঁত। বাস্তব ফাংশন (যেমন ডেমো ২-এর
g(x)) সাধারণত কোয়াড্রেটিক নয়, তাই একাধিক ধাপ লাগে — তবুও, রুটের কাছাকাছি পৌঁছালে
কোয়াড্রেটিক কনভারজেন্সের কারণে এই ধাপগুলো দ্রুত কমতে থাকে।
প্র ০২ নিউটনের মেথড প্রতি ধাপে দ্বিতীয় ডেরিভেটিভ (বা হেসিয়ান ম্যাট্রিক্স, বহু-চলক ক্ষেত্রে) গণনা করে — গ্র্যাডিয়েন্ট ডিসেন্ট শুধু প্রথম ডেরিভেটিভ ব্যবহার করে। ১০,০০০ প্যারামিটারবিশিষ্ট একটি মেশিন লার্নিং মডেলে এই পার্থক্যটি কেন গুরুত্বপূর্ণ ব্যবহারিক সমস্যা তৈরি করতে পারে?
nটি প্যারামিটারের জন্য হেসিয়ান ম্যাট্রিক্স আকারে n × n — n = 10,000-এ
এটি ১০ কোটি এন্ট্রি, এবং এই ম্যাট্রিক্স ইনভার্ট করা (M3-এর গসিয়ান এলিমিনেশনের মতো পদ্ধতিতে) সাধারণত
O(n³) সময় নেয় — এত বড় স্কেলে এটি ব্যবহারিকভাবে অসম্ভব ব্যয়বহুল। এই কারণেই বাস্তব ML
মডেল ট্রেনিংয়ে সরাসরি নিউটনের মেথড খুব কম ব্যবহৃত হয়, বরং গ্র্যাডিয়েন্ট ডিসেন্টের বিভিন্ন উন্নত
সংস্করণ (যেমন Adam, RMSprop) ব্যবহৃত হয়, যা দ্বিতীয় ডেরিভেটিভ পুরোপুরি এড়িয়ে যায় বা আনুমানিক করে।
প্র ০৩ ডেমো ২-এর এরর-সিকোয়েন্সে লক্ষ্য করুন প্রথম কয়েক ইটারেশনে এরর ধীরে কমেছে, কিন্তু শেষের দিকে খুব দ্রুত কমেছে। কোয়াড্রেটিক কনভারজেন্স কি সবসময়, শুরু থেকেই এত দ্রুত হয়?
না — কোয়াড্রেটিক কনভারজেন্স একটি স্থানীয় (local) বৈশিষ্ট্য, যা শুধু তখনই কার্যকর হয় যখন বর্তমান অনুমান সত্যিকারের মিনিমামের যথেষ্ট কাছাকাছি — কারণ তখনই ফাংশনটি স্থানীয়ভাবে একটি প্যারাবোলার মতো আচরণ করে। দূরে থাকা অবস্থায় (যেমন প্রথম কয়েক ইটারেশনে) কনভারজেন্স রেট এত দ্রুত নাও হতে পারে, এমনকি কিছু ফাংশনে প্রথমদিকে ভুল দিকেও যেতে পারে — এটাই মূল কথা ০৩-এ উল্লেখিত সীমাবদ্ধতা।
অনুশীলন
-
চিন্তা করুন: ডেমো ২-এর কোড সেলে শুরুর বিন্দু
x0 = 0.0-এর বদলেx0 = 2.9(মিনিমামের অনেক কাছে) ব্যবহার করলে নিউটনের মেথড কি কম ইটারেশনে কনভার্জ করবে বলে আপনার ধারণা?হ্যাঁ — যেহেতু
x0 = 2.9ইতিমধ্যে "কোয়াড্রেটিক কনভারজেন্স জোন"-এর কাছাকাছি (মিনিমাম থেকে দূরত্ব মাত্র ০.১), মেথডটির উল্লেখযোগ্যভাবে কম ইটারেশন লাগার কথা, কারণ শুরু থেকেই দ্রুত এরর-হ্রাস শুরু হবে। -
পরীক্ষা করুন: ডেমো ২-এর কোড সেলে
newton_1d(0.0)-কেnewton_1d(2.9)-এ পরিবর্তন করে Run চেপে আপনার অনুমান যাচাই করুন।x0 = 2.9-এ শুরু করলে নিউটনের মেথড মাত্র ৩ ইটারেশনে কনভার্জ করে (৮ ইটারেশনের বদলে) — নিশ্চিত করে যে মিনিমামের কাছাকাছি শুরু করলে কোয়াড্রেটিক কনভারজেন্সের পূর্ণ সুবিধা আরও দ্রুত পাওয়া যায়।
আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ
- পরবর্তী পাঠ — কনস্ট্রেইনড অপ্টিমাইজেশন, লাগ্রাঞ্জ মাল্টিপ্লায়ার M9 · L45 যখন ইনপুটের উপর অতিরিক্ত শর্ত (constraint) থাকে, তখন কীভাবে মিনিমাম/ম্যাক্সিমাম খুঁজে বের করতে হয়।
- আগের পাঠ — গ্র্যাডিয়েন্ট ডিসেন্ট M9 · L43 শুধু প্রথম ডেরিভেটিভ ব্যবহার করে মিনিমাম খোঁজা, এবং লার্নিং রেটের প্রভাব।
- M2 — রুট-ফাইন্ডিং মেথড এই কোর্সে নিউটন-রাফসন মেথড ও কোয়াড্রেটিক কনভারজেন্সের মূল ধারণা — যা এই পাঠে অপ্টিমাইজেশনে প্রয়োগ করা হয়েছে।