گرادیان کاهشی
برای کمینه کردن یک تابع، قدم به قدم در خلاف جهت گرادیان حرکت میکند. اینجا خطی را به چند نقطه برازش میدهد (کمترین مربعات). اندازهی گام (نرخ یادگیری) تعیین میکند همگرا شود یا واگرا.
گرادیان یک تابع جهتی است که تابع در آن سریعتر از همه زیاد میشود. برای کمینه کردن، در خلاف آن قدم برمیداریم:
ادامهی توضیح ↓- زمان:
O(n) per step - حافظه:
O(1) extra - CLRS، بخش ۳۳.۳
چهار نقطه نزدیک y = 2x + 1؛ با نرخ ۰٫۰۵ و ۲۵ گام، w و b به ۲ و ۱ نزدیک میشوند و خطا مدام کم میشود.
def gradient_descent(P, rate, steps):# Fit a line y = w·x + b to the points P by least squares. rate is the learning rate in thousandths.eta = rate / 1000n = len(P)w = 0.0b = 0.0rows = [[0, w, b, round(loss(P, w, b), 4)]] # for the picture: step, w, b, lossfor t in range(1, steps + 1):# The gradient of the mean squared error with respect to w and b.gw = 0.0gb = 0.0for x, y in P:err = w * x + b - ygw = gw + 2 * err * x / ngb = gb + 2 * err / nw = round(w - eta * gw, 4)b = round(b - eta * gb, 4)current = round(loss(P, w, b), 4)rows.append([t, w, b, current])if current > rows[0][3]:return Nonereturn [w, b]def loss(P, w, b):total = 0.0for x, y in P:total = total + (w * x + b - y) ** 2return total / len(P)
شروع اجرا
جدول هنوز خالی است.
متغیرهای محلی
نارنجی = در همین گام عوض شد
P list
Call stack
- gradient_descent()خط 1
توضیح
ایده
گرادیان یک تابع جهتی است که تابع در آن سریعتر از همه زیاد میشود. برای کمینه کردن، در خلاف آن قدم برمیداریم:
θ ← θ − η · ∇L(θ)
η نرخ یادگیری (اندازهی گام) است.
برازش خط
برای نقطههای (x_i, y_i) خط y = w·x + b را میخواهیم که میانگین مربع خطا کمینه شود:
L(w, b) = (1/n) Σ (w·x_i + b − y_i)²
∂L/∂w = (2/n) Σ (w·x_i + b − y_i) · x_i
∂L/∂b = (2/n) Σ (w·x_i + b − y_i)
این تابع محدب است، پس گرادیان کاهشی با نرخ مناسب به کمینهی سراسری میرسد.
نرخ یادگیری
- خیلی کوچک: همگرایی آهسته.
- خیلی بزرگ: هر گام از کمینه رد میشود و خطا بزرگتر میشود (واگرایی).
ورودی
هر سطر P یک نقطه است؛ rate نرخ یادگیری به هزارم (۵۰ یعنی ۰٫۰۵) و steps تعداد گامها.