گرادیان نزولی یک روش تکراری برای کمکردن تابع هدف است. در هر گام، مشتق یا گرادیان تابع در پارامتر فعلی را حساب میکنیم و با یک نرخ مشخص در جهت منفی آن حرکت میکنیم. نام «نزولی» به این معنی نیست که با هر نرخ و روی هر تابع، هر گام حتماً زیان را کم میکند.
پارامتر را با ورودی اشتباه نگیریم
در تمرین، تابع هدف J(w)=(w−۳)² است. w پارامتری است که تغییر میدهیم؛ داده مشتری یا خروجی احتمال نیست. کمینه دقیق تابع در w=۳ قرار دارد و مقدار تابع آنجا صفر است. این مسئله ساده برای دیدن مسیر حرکت انتخاب شده است؛ نتیجه آن را نمیتوان بدون بررسی به شبکه بزرگ یا تابع غیرمحدب تعمیم داد.
مشتق J برابر ۲(w−۳) است. قاعده بهروزرسانی را w_new = w_old − α×۲(w_old−۳) مینویسیم. α نرخ یادگیری این تمرین است. در هر گام، مشتق باید از مقدار فعلی w حساب شود؛ استفاده مکرر از مشتق آغازین، همین الگوریتم نیست.
سه گام را با نرخ ۰٫۱ حساب کنیم
از w=۰ شروع میکنیم. مشتق منفی ۶ است، پس گام اول w را به ۰٫۶ میبرد. در مقدار تازه، مشتق منفی ۴٫۸ است و گام دوم به ۱٫۰۸ میرسد. سپس مشتق منفی ۳٫۸۴، پارامتر را به ۱٫۴۶۴ میبرد.
| گام | پارامتر w | زیان J(w) |
|---|---|---|
| 0 | 0 | 9 |
| 1 | ۰٫۶ | ۵٫۷۶ |
| 2 | ۱٫۰۸ | ۳٫۶۸۶۴ |
| 3 | ۱٫۴۶۴ | ۲٫۳۵۹۲۹۶ |
پس از سه گام هنوز به ۳ نرسیدهایم؛ کاهش زیان با تمامشدن بهینهسازی یکسان نیست. برای همین تابع میتوان نوشت فاصله تازه از کمینه برابر (۱−۲α) برابر فاصله قبلی است. با α=۰٫۱، فاصله در هر گام در ۰٫۸ ضرب میشود.
کد و یک حالت شکست آشکار
def loss(w):
return (w-3.0)**2
def run(rate, steps=3):
w = 0.0
rows = [(0, w, loss(w))]
for step in range(1, steps+1):
gradient = 2*(w-3.0)
w = w-rate*gradient
rows.append((step, w, loss(w)))
return rows
normal = run(0.1)
for step, w, value in normal:
print(step, round(w, 6), round(value, 6))
print('rate=1', [w for _, w, _ in run(1.0)])
print('rate=1.1', [round(w, 6) for _, w, _ in run(1.1)])
assert abs(normal[-1][1]-1.464) < 1e-12
assert abs(normal[-1][2]-2.359296) < 1e-12
assert all(normal[j+1][2] < normal[j][2] for j in range(3))
assert [w for _, w, _ in run(1.0)] == [0.0, 6.0, 0.0, 6.0]
assert run(1.1)[-1][2] > run(1.1)[0][2]با نرخ ۱، دنباله پارامترها ۰، ۶، ۰، ۶ میشود؛ زیان در هر گام ۹ میماند. با نرخ ۱٫۱، فاصله از کمینه در ضریب منفی ۱٫۲ ضرب میشود و اندازه آن رشد میکند. این مثال نشان میدهد چرا فقط منفیبودن جهت گرادیان، اندازه گام دلخواه را مجاز نمیکند. بازه همگرایی ۰<α<۱ در این مثال مربوط به همین تابع درجهدو است، نه نسخه عمومی برای همه مدلها.
در آموزش مدل کدام عدد را پایش کنیم؟
در این کد تابع هدف دقیق و بدون نویز است. در آموزش با دستههای داده، گرادیان هر دسته و تغییر زیان میتوانند متفاوت باشند. ابتدا مشخص کنید زیان روی کدام داده و در کدام لحظه ثبت شده است. افت یک عدد آموزش، بهتنهایی به معنی عملکرد بهتر روی ورودی تازه نیست؛ راهنمای بیشبرازش همین تفاوت را پی میگیرد.
در گزارش، نرخ، مقدار آغازین، تعداد گام و معیار توقف را کنار هم بنویسید. توقف بهدلیل سقف گام را با رسیدن به کمینه یکی ننامید. اگر پارامترها چندتا هستند، گرادیان برداری از مشتقها خواهد بود و همه مؤلفهها باید با قرارداد بهروزرسانی مشخص تغییر کنند.
تمرین و مسیر ادامه
مقدار آغازین را از صفر به ۵ تغییر دهید و ببینید علامت مشتق چگونه جهت حرکت را برمیگرداند. سپس نرخ ۰٫۵ را امتحان کنید؛ برای این تابع خاص در یک گام به ۳ میرسید. این سرعت، ویژگی انتخاب تابع و نرخ ماست و ادعای سرعت آموزش مدل واقعی نیست.
برای فهم محل وزنها در مدل، محاسبه یک شبکه عصبی کوچک را ببینید. برای مسئله پاسخگویی مشتری، خروجی مطلوب و معیار آزمون را در بررسی نیاز با اپرا مشخص کنید؛ دانستن نام بهینهساز جای سنجش رفتار یک راهکار را نمیگیرد.
فایل تمرین و منابع
دریافت کد کامل این تمرین؛ این فایل فقط از کتابخانه استاندارد پایتون استفاده میکند. ورودیهای آن ساختگی و برای بازتولید محاسبهاند؛ اجرای آموزشی آن نتیجه یک محصول یا مشتری را نشان نمیدهد.
تاریخ بررسی منابع: ۳ نوامبر ۲۰۲۶. منابع، مرجع روشاند؛ دادهها، اعداد و کد مثال برای همین راهنما طراحی شدهاند.
ادامه مسیر یادگیری
پسانتشار و قاعده زنجیرهای — جهت بهروزرسانی به گرادیان نیاز دارد؛ مثال پسانتشار نشان میدهد مشتق وزنهای یک شبکه چگونه به دست میآید.