ML Learning Hub
الأسسمبتدئ

حساب التفاضل والتكامل والتحسين

من المشتقات إلى الانحدار التدريجي — المحرك الذي يدرّب كل شبكة عصبية

المشتقات والمشتقات الجزئية وقاعدة السلسلة (الانتشار العكسي) والانحدار التدرجي — ثم Adam والزخم وجدولة معدل التعلم. القصة الكاملة لكيفية تعلم الشبكات العصبية.

45 min
8 مخططات
8 المفاهيم المغطاة

المتطلبات الأساسية

Linear Algebra

المفاهيم المغطاة

DerivativesChain RuleGradientGradient DescentAdamMomentumLearning RateConvexity

الصيغ الرئيسية

التدرج

متجه المشتقات الجزئية — يشير إلى اتجاه أشد صعود

قاعدة السلسلة

العمود الفقري للانتشار الخلفي — تركيب المشتقات عبر الطبقات

الانحدار التدرجي

التحرك بشكل متكرر عكس التدرج لتقليل الخسارة L

تحديث آدم

انحدار تدرجي مع معدلات تعلم تكيفية لكل معامل (العزمات الأولى والثانية المصحَّحة)

محاكاة تفاعلية

Loading visualization…
🎯

التحسين هو ما يجعل النماذج تتعلم

motivation

تدريب نموذج التعلم الآلي هو مشكلة تحسين: إيجاد المعاملات θ التي تقلل دالة الخسارة L(θ). الانحدار التدرجي هو الخوارزمية الأساسية التي تحل هذا لمشاكل بملايين المعاملات حيث لا توجد حلول بصيغة مغلقة. قاعدة السلسلة تجعل حساب التدرجات عبر تركيبات عميقة من الدوال ممكناً — هذا هو الانتشار الخلفي.

نموذج GPT يحتوي على ~175 مليار معامل. الانحدار التدرجي يُحدّث جميعها في آنٍ واحد في تمرير خلفي واحد بفضل قاعدة السلسلة.

💡

التدرج كاتجاه في فضاء المعاملات

intuition

تخيل دالة الخسارة كمنظر تلالي وموقعك هو معاملاتك. التدرج ∇L(θ) سهم يشير إلى الأعلى. التحرك في الاتجاه المعاكس (−η∇L) ينزل — نحو خسارة أقل. معدل التعلم η يتحكم في حجم الخطوة: كبير جداً فترتد (التشتت)، صغير جداً فيستغرق التدريب أبداً. يحل Adam هذا بالحفاظ على معدل تعلم منفصل لكل معامل بناءً على تاريخ تدرجاته.

الحدس لقاعدة السلسلة: إذا كان تغيير درجة الحرارة يؤثر على الضغط، والضغط يؤثر على الحجم، فكيف تؤثر درجة الحرارة على الحجم؟ اضرب الحساسيات الفردية.

⚙️

محسِّن آدم — خطوة بخطوة

algorithm
1

التهيئة: θ، m₀=0 (العزم الأول)، v₀=0 (العزم الثاني)، t=0، β₁=0.9، β₂=0.999، ε=1e-8

2

حساب التدرج: g_t = ∇_θ L(θ_{t-1})

3

تحديث العزم الأول المتحيز (الزخم): m_t = β₁·m_{t-1} + (1-β₁)·g_t

4

تحديث العزم الثاني المتحيز (المقياس التكيفي): v_t = β₂·v_{t-1} + (1-β₂)·g_t²

5

تصحيح التحيز: m̂_t = m_t/(1-β₁ᵗ)، v̂_t = v_t/(1-β₂ᵗ)

6

تحديث المعاملات: θ_t = θ_{t-1} - η·m̂_t / (√v̂_t + ε)

7

الحدس: m̂_t متوسط متحرك للتدرجات (زخم). √v̂_t يُطبّع حسب الحجم — المتغيرات ذات التدرجات الكبيرة تحصل على معدلات تعلم أصغر.

</>

الانحدار التدرجي من الصفر

code
python80 lines
import numpy as np
import matplotlib.pyplot as plt

class="tok-comment"># ── Numerical derivatives (educational) ──────────────────────────────────────
def numerical_grad(f, x, h=class="tok-num">1e-5):
    class="tok-str">"""Central difference approximation: (f(x+h) - f(x-h)) / 2h"""
    grad = np.zeros_like(x, dtype=float)
    for i in range(len(x)):
        x_plus  = x.copy(); x_plus[i]  += h
        x_minus = x.copy(); x_minus[i] -= h
        grad[i] = (f(x_plus) - f(x_minus)) / (class="tok-num">2 * h)
    return grad

class="tok-comment"># ── class="tok-num">1. Gradient Descent on simple quadratic ───────────────────────────────────
def loss(theta):
    return (theta[class="tok-num">0] - class="tok-num">3)**class="tok-num">2 + (theta[class="tok-num">1] + class="tok-num">1)**class="tok-num">2  class="tok-comment"># minimum at (class="tok-num">3,-class="tok-num">1)

def grad_loss(theta):
    return np.array([class="tok-num">2*(theta[class="tok-num">0]-class="tok-num">3), class="tok-num">2*(theta[class="tok-num">1]+class="tok-num">1)])

theta = np.array([class="tok-num">0., class="tok-num">0.])
lr = class="tok-num">0.1
history = [theta.copy()]

for step in range(class="tok-num">50):
    g = grad_loss(theta)
    theta -= lr * g
    history.append(theta.copy())
    if np.linalg.norm(g) < class="tok-num">1e-6:
        print(fclass="tok-str">"Converged at step {step}")
        break

print(fclass="tok-str">"Final θ: {theta.round(class="tok-num">4)}")  class="tok-comment"># ≈ [class="tok-num">3, -class="tok-num">1]

class="tok-comment"># ── class="tok-num">2. Adam optimizer ────────────────────────────────────────────────────────
def adam(grad_fn, theta_init, lr=class="tok-num">0.01, n_steps=class="tok-num">100, b1=class="tok-num">0.9, b2=class="tok-num">0.999, eps=class="tok-num">1e-8):
    theta = theta_init.copy().astype(float)
    m, v = np.zeros_like(theta), np.zeros_like(theta)
    history = [theta.copy()]
    for t in range(class="tok-num">1, n_steps+class="tok-num">1):
        g = grad_fn(theta)
        m = b1*m + (class="tok-num">1-b1)*g
        v = b2*v + (class="tok-num">1-b2)*g**class="tok-num">2
        m_hat = m / (class="tok-num">1 - b1**t)
        v_hat = v / (class="tok-num">1 - b2**t)
        theta -= lr * m_hat / (np.sqrt(v_hat) + eps)
        history.append(theta.copy())
    return theta, history

theta_adam, hist_adam = adam(grad_loss, np.array([class="tok-num">0., class="tok-num">0.]), lr=class="tok-num">0.1)
print(fclass="tok-str">"Adam θ: {theta_adam.round(class="tok-num">4)}")

class="tok-comment"># ── class="tok-num">3. Chain rule in action (manual backprop) ─────────────────────────────────
class="tok-comment"># f(x) = (2x + class="tok-num">1)^class="tok-num">2. df/dx = class="tok-num">2 * (2x+class="tok-num">1) * class="tok-num">2 = class="tok-num">4*(2x+class="tok-num">1)
x = class="tok-num">3.0
class="tok-comment"># Forward pass
u = class="tok-num">2*x + class="tok-num">1    class="tok-comment"># u = class="tok-num">7
f = u**class="tok-num">2       class="tok-comment"># f = class="tok-num">49

class="tok-comment"># Backward pass (chain rule)
df_du = class="tok-num">2*u    class="tok-comment"># = class="tok-num">14
du_dx = class="tok-num">2      class="tok-comment"># constant
df_dx = df_du * du_dx   class="tok-comment"># = class="tok-num">28
print(fclass="tok-str">"df/dx at x=class="tok-num">3: {df_dx}")  class="tok-comment"># analytical: class="tok-num">4*(class="tok-num">2*class="tok-num">3+class="tok-num">1) = class="tok-num">28 ✓

class="tok-comment"># ── class="tok-num">4. Learning rate sensitivity ─────────────────────────────────────────────
fig, axes = plt.subplots(class="tok-num">1, class="tok-num">3, figsize=(class="tok-num">12,class="tok-num">3))
for ax, lr_val in zip(axes, [class="tok-num">0.01, class="tok-num">0.1, class="tok-num">0.9]):
    theta = np.array([class="tok-num">0.])
    losses = []
    for _ in range(class="tok-num">100):
        g = class="tok-num">2*(theta[class="tok-num">0] - class="tok-num">5)
        theta[class="tok-num">0] -= lr_val * g
        losses.append((theta[class="tok-num">0]-class="tok-num">5)**class="tok-num">2)
    ax.semilogy(losses)
    ax.set_title(fclass="tok-str">"lr = {lr_val}")
    ax.set_xlabel(class="tok-str">"Steps")
    ax.set_ylabel(class="tok-str">"Loss")
plt.tight_layout()
plt.show()  class="tok-comment"># lr=class="tok-num">0.01: slow, lr=class="tok-num">0.1: perfect, lr=class="tok-num">0.9: oscillates
⚠️

الحد الأدنى المحلي مقابل نقاط السرج — ما يبطئ التدريب فعلاً

pitfall

في أسطح الخسارة عالية الأبعاد، الحدود الدنيا المحلية الحقيقية نادرة — معظم النقاط 'العالقة' هي نقاط سرج. الانحدار التدرجي مع الضوضاء (SGD) يهرب من نقاط السرج بشكل طبيعي. المشاكل العملية الأكبر هي: (1) انفجار التدرجات في الشبكات العميقة — استخدم قص التدرج. (2) اختفاء التدرجات في الشبكات التكررية — استخدم LSTM/GRU. (3) سوء التكييف — استخدم تطبيع الدُفعات أو تهيئة الأوزان.

للمشاكل المحدبة (الانحدار الخطي، اللوجستي، SVM)، الانحدار التدرجي مضمون للعثور على الحد الأدنى العالمي. للشبكات العصبية، يجد حوضاً 'جيداً بما يكفي'.

?اختبار المعرفة

يتم حفظ التقدم في متصفحك — لا حاجة لحساب.

تحتاج مهندس ذكاء اصطناعي أو عالم بيانات؟

أبني نماذج تعلم آلي مخصصة، ووكلاء ذكاء اصطناعي، ورؤية حاسوب، وأتمتة — من الفكرة إلى الإنتاج.