الدرس 2 من 8

إزاي الشبكة بتتعلم

هنبني شبكة بـ NumPy بس ونشوفها بتتعلم قدامنا.

الدورة اللي بتتكرر

  • Forward pass: الداتا تعدي على الطبقات وتطلع توقع.
  • Loss: نقيس التوقع بعيد عن الإجابة الصح قد إيه.
  • Backward pass: نحسب الـ gradient لكل وزن بالـ chain rule، من آخر طبقة لأولها.
  • Update: نحرك كل وزن خطوة صغيرة عكس الـ gradient.

ده الـ gradient descent اللي عملناه في المرحلة ٣ على وزن واحد، بس هنا على كل أوزان الشبكة مع بعض. واسم الخطوة التالتة Backpropagation لأن الغلط بيرجع لورا طبقة طبقة.

مسألة XOR: خط واحد مش كفاية

XOR بيطلع 1 لو واحد بس من المدخلين 1. ارسم النقط الأربعة على ورقة وهتلاقي إن مستحيل تفصل الـ 1 عن الـ 0 بخط مستقيم واحد. يعني Logistic Regression هيفشل، ومحتاجين طبقة مخفية. تعالى نبنيها بإيدينا:

xor_numpy.py
import numpy as np

X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
y = np.array([[0], [1], [1], [0]])            # XOR

rng = np.random.default_rng(1)
W1, b1 = rng.normal(size=(2, 4)), np.zeros(4)  # hidden layer: 4 neurons
W2, b2 = rng.normal(size=(4, 1)), np.zeros(1)  # output layer
sigmoid = lambda z: 1 / (1 + np.exp(-z))
lr = 0.5

for epoch in range(5001):
    # ---- forward ----
    h = np.tanh(X @ W1 + b1)
    p = sigmoid(h @ W2 + b2)
    loss = np.mean((p - y) ** 2)

    # ---- backward (chain rule, layer by layer) ----
    d_out = 2 * (p - y) / len(X) * p * (1 - p)
    d_W2, d_b2 = h.T @ d_out, d_out.sum(axis=0)
    d_h = d_out @ W2.T * (1 - h ** 2)            # derivative of tanh
    d_W1, d_b1 = X.T @ d_h, d_h.sum(axis=0)

    # ---- update ----
    W2 -= lr * d_W2; b2 -= lr * d_b2
    W1 -= lr * d_W1; b1 -= lr * d_b1

    if epoch % 1000 == 0:
        print(f"epoch {epoch:4}: loss = {loss:.4f}")

print("predictions:", p.round(2).ravel())

الشبكة بدأت بأوزان عشوائية، والـ loss نزل لحد ما التوقعات بقت قريبة جداً من [0, 1, 1, 0]. محدش قالها القاعدة، اتعلمتها من ٤ أمثلة.

epoch لفة كاملة على كل الداتا.
forward pass حساب التوقع من المدخلات.
backward pass حساب الـ gradients من الـ loss.
learning rate حجم الخطوة، نفس اللي في المرحلة ٣.
💡 مش هتكتب ده تانيالجزء اللي عليه backward ده أصعب حتة، وفي PyTorch بيتعمل في سطر واحد أوتوماتيك. بس لازم تكون شفته مرة عشان تفهم إيه اللي بيحصل من ورا الستارة، ولما حاجة تبوظ تعرف تدور فين.
الدرس اللي فات