پسانتشار یا Backpropagation، مشتق زیان نسبت به پارامترهای شبکه را با عبور معکوس از گراف محاسبه به دست میآورد. سپس یک بهینهساز میتواند از این گرادیانها برای تغییر وزنها استفاده کند. محاسبه گرادیان و بهروزرسانی وزن دو مرحله متفاوتاند؛ در این مثال هر دو را با دست و با پایتون جدا میبینیم.
اول عبور رو به جلو
شبکه تمرین یک ورودی، یک نورون ReLU و یک خروجی خطی دارد: z=w×x+b، سپس h=max(۰,z) و در پایان y_hat=v×h+c. ورودی x=۲، هدف y=۱ و پارامترها w=۰٫۵، b=۰٫۱، v=۲ و c=−۰٫۲ هستند. این مقدارها آموزشیاند و از داده واقعی آموخته نشدهاند.
بنابراین z=۱٫۱، h=۱٫۱ و y_hat=۲ است. زیان را برای این یک نمونه به شکل L=۰٫۵(y_hat−y)² تعریف میکنیم، پس L=۰٫۵. عامل ۰٫۵، مشتق این مثال را ساده میکند؛ حذفش مقدار گرادیان را تغییر میدهد. برای آشنایی با اجزای عبور جلو، راهنمای شبکه عصبی کوچک را جدا بخوانید.
قاعده زنجیرهای را عقب دنبال کنیم
مشتق زیان نسبت به خروجی برابر y_hat−y یعنی ۱ است. خروجی نسبت به v مشتق h دارد، پس dL/dv=۱×۱٫۱=۱٫۱. مشتق نسبت به c برابر ۱ است. سهم برگشتی از خروجی به h برابر ۱×v=۲ میشود. چون z مثبت است، مشتق ReLU در همین نقطه ۱ است و dL/dz=۲ خواهد بود.
| پارامتر | مسیر مشتق | گرادیان این نمونه |
|---|---|---|
| w | dL/dz × x | 4 |
| b | dL/dz | 2 |
| v | dL/dy_hat × h | ۱٫۱ |
| c | dL/dy_hat | 1 |
این ضربها معنای پسانتشار در مثالاند. برای z منفی، مسیر همین ReLU مشتق صفر میگیرد؛ در z=۰ تابع گوشه دارد و قرارداد مشتق پیادهسازی لازم است. مثال ما عمداً دور از آن گوشه است تا کنترل مشتق عددی قابل تفسیر باشد.
همه پارامترها را از نسخه قبلی بهروز کنیم
با نرخ ۰٫۰۱، مقدارهای تازه w=۰٫۴۶، b=۰٫۰۸، v=۱٫۹۸۹ و c=−۰٫۲۱ میشوند. برای هرکدام از گرادیان نسخه قدیم استفاده میکنیم؛ تغییر w و محاسبه گرادیان v از شبکه نیمهتغییرکرده همان گام مشترک نیست. عبور جلو تازه z=۱، خروجی ۱٫۷۷۹ و زیان ۰٫۳۰۳۴۲۰۵ میدهد.
کد و کنترل با تفاضل محدود
x, target = 2.0, 1.0
params = {'w': 0.5, 'b': 0.1, 'v': 2.0, 'c': -0.2}
def forward(p):
z = p['w']*x+p['b']
h = max(0.0, z)
output = p['v']*h+p['c']
return z, h, output
def loss(p):
_, _, output = forward(p)
return 0.5*(output-target)**2
z, h, output = forward(params)
gout = output-target
gz = gout*params['v']*(1.0 if z > 0 else 0.0)
grad = {'w': gz*x, 'b': gz, 'v': gout*h, 'c': gout}
eps = 1e-6
errors = {}
for name in params:
plus, minus = params.copy(), params.copy()
plus[name] += eps
minus[name] -= eps
numeric = (loss(plus)-loss(minus))/(2*eps)
errors[name] = abs(numeric-grad[name])
updated = {k: value-0.01*grad[k] for k, value in params.items()}
print('forward', z, h, output, loss(params))
print('gradients', grad)
print('finite difference max error', max(errors.values()))
print('updated', updated, 'new loss', loss(updated))
assert abs(grad['w']-4) < 1e-12 and abs(grad['v']-1.1) < 1e-12
assert max(errors.values()) < 1e-7
assert abs(loss(updated)-0.3034205) < 1e-12کنترل عددی هر پارامتر را یک بار اندکی بالا و یک بار پایین میبرد و شیب تقریبی میسازد. این کنترل برای همین نقطه و تابع است؛ اختلاف کوچک، درستی همه مسیرهای یک برنامه یا تمام نقطهها را ثابت نمیکند. نزدیک گوشه ReLU یا با eps نامناسب، خواندن نتیجه به دقت بیشتری نیاز دارد.
در ابزارهای یادگیری چه چیزی را جدا ببینیم؟
در کتابخانههایی مانند PyTorch، مشتقها میتوانند خودکار محاسبه شوند. داشتن مشتق هنوز به معنی انجام گام بهینهساز نیست؛ در حلقه معمول، پاککردن یا انباشت عمدی گرادیان، عبور جلو، زیان، backward و گام بهینهساز قرارداد جدا دارند. تفاوت آموزش و اجرای مدل کمک میکند استفاده از وزن آماده را با تغییر وزنها اشتباه نگیرید.
برای تمرین، خروجی هدف را از ۱ به ۲ تغییر دهید؛ در پارامترهای آغازین همین نمونه زیان و گرادیانها صفر میشوند. این اتفاق یعنی پاسخ این نمونه برابر شده، نه اینکه شبکه برای دادههای تازه درست است. برای ارزیابی یک راهکار مشتری، نمونه مستقل و خروجی موردانتظار را در بررسی با تیم اپرا مشخص کنید؛ این شبکه توصیف معماری محصول نیست.
فایل تمرین و منابع
دریافت کد کامل این تمرین؛ این فایل فقط از کتابخانه استاندارد پایتون استفاده میکند. ورودیهای آن ساختگی و برای بازتولید محاسبهاند؛ اجرای آموزشی آن نتیجه یک محصول یا مشتری را نشان نمیدهد.
- Google ML Crash Course: Backpropagation
- PyTorch Tutorials: Neural Networks, Backprop and weight update
تاریخ بررسی منابع: ۳ نوامبر ۲۰۲۶. منابع، مرجع روشاند؛ دادهها، اعداد و کد مثال برای همین راهنما طراحی شدهاند.
ادامه مسیر یادگیری
تفاوت Epoch، Batch و Step — پس از محاسبه گرادیان، تعداد اجرای دسته و تعداد بهروزرسانی را در حلقه آموزش جدا بشمارید.