PyTorch / أسس الموتر والتدرج والوحدة / الدرس 2
التفاضل التلقائي وأوضاع التدرج
تتبع العمليات التي تدخل الرسم العكسي وافصل تراكم التدرجات عن تحديث المعاملات.
في هذه الصفحة
أهداف الدرس
- تحديد الموترات الورقية وأهداف الانتشار العكسي المفردة.
- شرح تراكم .grad عبر رسوم حساب جديدة.
- تمييز requires_grad وno_grad وinference_mode ووضع تقييم الوحدة.
يتبع التفاضل العمليات المنفذة المدعومة
يسجل PyTorch العمليات في رسم عكسي عندما تتطلب المدخلات المناسبة تدرجات ضمن وضع التدرج. يمكن لموتر ورقي أنشئ بـ requires_grad=True استقبال مشتقات متراكمة في حقل .grad؛ وتخدم الموترات الوسيطة عادة قاعدة السلسلة بدلاً من الاحتفاظ تلقائياً بمخزن تدرج معروض. لا تصبح الفهارس الصحيحة والقرارات الحادة معاملات عادية قابلة للتفاضل لمجرد ظهورها في البرنامج. حدد الهدف المفرد ومسار المعامل قبل تشخيص تدرجات مفقودة. يحسب التفاضل التلقائي مشتقات الحساب المنفذ؛ ولا يقدم برهاناً على صحة هدفه أو وسومه أو تصميم تقييمه.
للانتشار العكسي والتراكم عمرا حياة مختلفان
ينشئ البرنامج التوضيحي ورقة عددية، ويقيم نصف خسارة تربيعية، ويستدعي backward. عند w=2 يساوي الباقي خمسة ومشتقة 3*w المحلية ثلاثة، فيكون التدرج خمسة عشر. يبنى بعد ذلك رسم أمامي جديد ويشتق مجدداً، فتضاف خمسة عشر أخرى إلى مخزن الورقة نفسه. يختلف ذلك عن استدعاء backward مرتين على الرسم المحرر نفسه. لا يغير تفريغ مخزن التدرج قيمة المعامل؛ فتحديث المحسن عملية أخرى. تميز الدروس اللاحقة None من تدرج صفري صريح عندما يفسر المحسن المعاملات التي لم تشارك.
import torch
w = torch.tensor(2.0, dtype=torch.float64, device="cpu", requires_grad=True)
loss = 0.5*(3*w-1)**2
loss.backward()
print("first gradient", w.grad.item())
(0.5*(3*w-1)**2).backward()
print("accumulated gradient", w.grad.item())
w.grad = None
with torch.no_grad():
output = 3*w
print("no-grad output requires gradient", output.requires_grad)
first gradient 15.0
accumulated gradient 30.0
no-grad output requires gradient False
يستخدم كل استدعاء backward هدفاً عددياً جديد البناء، فتتراكم تدرجات الورقة دون إعادة استخدام رسم محرر. لم ينفذ مرور PyTorch العكسي أو وضع تدرجه أثناء المراجعة.
تتحكم أوضاع التدرج في تسجيل الرسم
تعطل torch.no_grad تسجيل حسابات سياقها مع السماح باستخدام كثير من القيم الناتجة لاحقاً في وضع التدرج العادي. لعقد torch.inference_mode قيود إضافية أقوى على الموترات المنشأة داخله؛ فلا تفترض أنه بديل مباشر لكل كتلة no-grad. تتحكم requires_grad في المعاملات المشاركة في حساب التدرج؛ وليست علماً للتدريب مقابل التقييم. تغير module.eval سلوك الوحدة كالإسقاط أو استخدام الإحصاءات الجارية ولا تعطل autograd بذاتها. اختر وضع التدرج وحالة الوحدة بصورة مستقلة وفق الحساب الفعلي.
افحص مشتقة صغيرة ملساء بصورة مستقلة
يحسب المرافق القياسي المشتقة التحليلية والفرق العددي المركزي للدالة التربيعية نفسها. يفحص شرط السماحية ذلك الحساب العددي عند نقطة ملساء. ولا يتحقق من محرك PyTorch أو يثبت صحة شبكة تتفرع أو تستخدم أقنعة أو عمليات غير قابلة للتفاضل. تحتاج الفحوص العددية دقة وحجم اضطراب ومدخلات حتمية مناسبة؛ وقد تفقد فروق صغيرة جداً الدقة بسبب الطرح. إذا غاب تدرج إطار، فافحص أولاً هل قطع detach أو تحويل إلى عدد عادي أو سياق no-grad أو مسار غير مدعوم الاعتماد المطلوب قبل تعديل المحسن.
def loss(w):
return 0.5*(3*w-1)**2
w, h = 2.0, 1e-5
analytic = 3*(3*w-1)
central = (loss(w+h)-loss(w-h))/(2*h)
print(f"analytic={analytic:.6f}")
print(f"central={central:.6f}")
print("within tolerance", abs(analytic-central) < 1e-8)
analytic=15.000000
central=15.000000
within tolerance True
يفحص المرافق المنفذ مشتقة عددية ملساء واحدة بصورة مستقلة؛ ولا يشغل رسوم autograd أو مخازن تدرجات أو مديري سياق PyTorch.
اجعل ترتيب الاشتقاق والتعديل ظاهراً
أكمل المشتقات اللازمة من الحالة الأمامية قبل تعديل المعاملات أو القيم المحفوظة. يختلف تسجيل loss.item بعد بناء الهدف عن استبدال تعبير موتر مطلوب بعدد Python قبل backward. يوقف الفصل المتعمد مسار التدرج ولا يعوض نسخ تخزين مستقل. تحقق من المعاملات المسماة التي ينبغي أن تتلقى تدرجات وتلك المجمدة عمداً. يبقى برنامج الإطار توضيحياً بمخرجات مشتقة لغياب torch؛ ويدعم المرافق المنفذ الاستدلال الحسابي فقط، دون ادعاء عن ذاكرة الرسم أو تنفيذ الإطار أو تدريب نموذج أو أداء جهاز.
الأخطاء الشائعة وإصلاحها
ضاعفت خطوة ثانية تدرجها دون توقع
- لماذا يحدث؟
- تراكمت مخازن الورقة بسبب غياب حد التصفير المقصود.
- كيف تصلحه؟
- امسح التدرجات عند حد التراكم المعلن قبل التحديث المستقل التالي.
- كيف تتجنب تكراره؟
- اختبر مشتقات الرسوم الجديدة وتصفير المخزن بصورة منفصلة.
افتُرض أن استدعاء eval يعطل التدرجات
- لماذا يحدث؟
- اختلط سلوك الوحدة بتسجيل autograd.
- كيف تصلحه؟
- اختر حالة eval وسياق تدرج مناسباً بصورة مستقلة.
- كيف تتجنب تكراره؟
- افحص حالة تدريب الوحدة ووجود التدرجات المطلوبة معاً.
أصبحت الخسارة عدداً بلا مسار عكسي
- لماذا يحدث؟
- أزال detach أو تحويل إلى عدد عادي الاعتماد.
- كيف تصلحه؟
- أبق تعبير الموتر قابلاً للتفاضل حتى اكتمال الاشتقاق.
- كيف تتجنب تكراره؟
- اختبر مسار معامل معلوم إلى الهدف قبل إضافة التسجيل أو الأغلفة.
اختبر فهمك
1. لماذا ينتج backward الثاني في المثال ثلاثين بدلاً من خمسة عشر؟
اعرض الحل المشروح
يحسب الهدف الثاني من رسم جديد عند قيمة المعامل نفسها، فتكون مشتقته خمسة عشر إضافية. يضيف PyTorch الإسهام إلى الخمسة عشر الموجودة في حقل .grad للورقة. لم تغير خطوة محسن قيمة w. يؤدي تصفير المخزن قبل الاشتقاق الجديد إلى الاحتفاظ بإسهام واحد بدلاً من ذلك.
2. وحدة في وضع eval ومعاملاتها العائمة تتطلب تدرجات. هل يبني مرور أمامي عادي رسماً للتدرج؟
اعرض الحل المشروح
نعم، في وضع التدرج العادي ومع عمليات مدعومة، لا تعطل eval تسجيل الرسم. تغير فقط الوحدات التي تعرف حساباً خاصاً بالوضع. استخدم سياق no-grad أو inference مقصوداً عند الملاءمة، مع مراعاة حاجة الموترات الناتجة إلى المشاركة لاحقاً في autograd.
أهم ما تعلمته
- يسجل autograd حساباً محدداً مدعوماً.
- قد تتراكم مشتقات رسم جديد في مخازن ورقية قائمة.
- وضع الوحدة ووضع التدرج قراران مستقلان.