AI: الشبكات العصبية

آخر تحديث: 2026-08-26

قد يبدو "التعلم العميق" غامضًا ومعقدًا، لكن لبنته الأساسية -العصبون- ببساطة هو مجموع مرجح يليه تحويل خطي غير متسلسل. بدًا من المُدرِك (perceptron)، يرشدك هذا الفصل خطوة بخطوة عبر الشبكات متعددة الطبقات، ودالات التنشيط، وانتشار الأمام، وانتشار الخلف، ويُريك كيفية تنفيذ نموذج MLP من الصفر باستخدام بايثون البحت الذي يمكنه حل مشكلة XOR.

١. ما ستتعلمه



2. القصة: "الدماغ" المُختبئ خلف 10 أسطر من الكود

(1) نقطة الألم: ما هو التعلم العميق بالضبط؟

كان بوب قد سمع أن "التعلم العميق" يمكنه التعرف على الوجوه، وترجمة اللغات، وكتابة المقالات، لكنه لم يكن لديه أدنى فكرة عن ماهية الشبكة العصبية. حاول البحث عنها في ويكيبيديا، لكن الشاشة المليئة بالتفاضلات الجزئية وقاعدة السلسلة جعلته يُغلق الصفحة فورًا. "ألا يمكن لأحد أن يشرح لي بأبسط المصطلحات ما تفعله 'الخلية العصبية' بالفعل؟"

(2) كود أليس المكون من 10 أسطر

ابتسمت أليس وفتحت بايثون وكتبت خلية عصبية بسيطة (perceptron) في 10 أسطر من الكود - تأخذ رقمين كمدخل وتطبع إما 0 أو 1:

PYTHON
# A single perceptron: AND gate
def perceptron(x1, x2, w1=1, w2=1, b=-1.5):
    return 1 if w1 * x1 + w2 * x2 + b > 0 else 0

for x1, x2 in [(0,0),(0,1),(1,0),(1,1)]:
    print(f"AND({x1},{x2}) = {perceptron(x1, x2)}")
💻 المُخرج:

TEXT 📖 للعرض فقط
AND(0,0) = 0
AND(0,1) = 0
AND(1,0) = 0
AND(1,1) = 1

أدرك بوب: "أليست هذه مجرد عملية تصويت مُرجّح؟ كلا المُدخلين مضبوطان على 1، وإذا تجاوز المجموع المُرجّح العتبة، يكون المُخرج 1 - إذن الشبكة العصبية هي مجرد سلسلة من هذه الوحدات القرار البسيطة المتصلة معًا!"

(3) الفوائد: من وحدات بسيطة إلى شبكات قوية

أومأت أليس برأسها. "صحيح. الخلية العصبية البسيطة (البِرسِبترون) الواحدة لا تستطيع أداء سوى التصنيف الخطي، لكن عن طريق تكديس عشرات أو مئات الخلايا العصبية البسيطة في شبكة متعددة الطبقات، يمكننا مُطابقة دوال معقدة للغاية - وهنا يبدأ التعلم العميق."


3. التحسين—الشبكة العصبية الأبسط

(1) التعريف الرياضي للحساسية (Perceptron)

الحساسية، التي اقترحها عالم النفس روزنبلات في عام 1958، هي واحدة من أقدم نماذج الخلايا العصبية الاصطناعية. تستقبل مدخلات متعددة $x_1, x_2, \ldots, x_n$، لكل منها وزن $w_i$، بالإضافة إلى انحياز $b$، وأخيرًا تُخرج 0 أو 1 عبر دالة خطوة:

$$y = \text{step}\left(\sum_{i=1}^{n} w_i x_i + b\right)$$

على وجه الخصوص، $\text{step}(z) = 1$ إذا كان $z > 0$، و $0$ خلاف ذلك.

حدس: تخيّل أنك تقرر الخروج للركض—درجة الحرارة، جودة الهواء، إن كان لديك وقت، ومزاجك—كل عامل له "وزن"، وإذا تجاوز المجموع "عتبة الكسل" الخاصة بك، فإنك تخرج.

(2) المعنى الهندسي للحساسية

ترسم الحساسية خطًا مستقيمًا $w_1 x_1 + w_2 x_2 + b = 0$ في الفضاء ثنائي الأبعاد، حيث تُخرج 1 على جانب من الخط و 0 على الجانب الآخر. يمكنها حل مشكلات خطية التفرقة بشكل مثالي مثل AND و OR، لكنها لا تستطيع حل مشكلة XOR—لأن فئتي النقاط في مشكلة XOR لا يمكن فصلهما بخط مستقيم واحد.

▶ مثال: تنفيذ بوابة AND باستخدام الحساسية بلغة Python البحتة (الصعوبة: ⭐)

PYTHON
# Perceptron AND gate with training
def step(z):
    return 1 if z > 0 else 0

def train_perceptron(X, y, lr=0.1, epochs=10):
    n_features = len(X[0])
    weights = [0.0] * n_features
    bias = 0.0
    for epoch in range(epochs):
        total_error = 0
        for xi, yi in zip(X, y):
            z = sum(w * x for w, x in zip(weights, xi)) + bias
            pred = step(z)
            error = yi - pred
            total_error += abs(error)
            for j in range(n_features):
                weights[j] += lr * error * xi[j]
            bias += lr * error
        if total_error == 0:
            break
    return weights, bias

X = [[0,0],[0,1],[1,0],[1,1]]
y_and = [0, 0, 0, 1]
w, b = train_perceptron(X, y_and)
print(f"Weights: {w}, Bias: {b}")
for xi in X:
    print(f"AND{xi} = {step(sum(ww*xx for ww,xx in zip(w,xi)) + b)}")
💻 Output:

TEXT 📖 للعرض فقط
Weights: [0.2, 0.1], Bias: -0.2
AND[0, 0] = 0
AND[0, 1] = 0
AND[1, 0] = 0
AND[1, 1] = 1
💡 Tip: The learning rules of a perceptron are very simple—if the prediction is correct, the weights remain unchanged; if the prediction is incorrect, the weights are adjusted in the direction of the error. This is the most basic form of "learning from mistakes."



4. بنية الشبكة العصبية متعددة الطبقات (MLP)

(1) لماذا نحتاج إلى طبقات متعددة؟

الشبكة العصبية ذات الطبقة الواحدة (Perceptron) تستطيع رسم خطوط مستقيمة فقط ولا تستطيع حل مشكلة XOR. ولكن، إذا تم تغذية مخرجات شبكتين عصبيتين (Perceptron) إلى شبكة عصبية ثالثة، يصبح من الممكن الجمع بين خطيين مستقيمين لتشكيل حدود غير خطية. هذه هي الفكرة الأساسية وراء الشبكة العصبية متعددة الطبقات (MLP).

(2) البنية ثلاثية الطبقات للشبكة العصبية متعددة الطبقات (MLP)

الطبقة الوظيفة مثال
طبقة الإدخال تستقبل السمات الأصلية 2 عقدة (x₁، x₂)
الطبقة المخفية تستخرج سمات وسيطة 4 عقد (سمات تم تعلمها)
طبقة الإخراج تقدم التنبؤ النهائي 1 عقدة (0 أو 1)

كل عقدة في كل طبقة متصلة بجميع العقد في الطبقة السابقة (متصلة بالكامل)، وتتمثل قوة هذه الروابط بالـ الأوزان.

(3) عملية الانتشار الأمامي في الشبكات العصبية

100%
graph LR
    X1["x₁"] --> H1["h₁ (sigmoid)"]
    X1 --> H2["h₂ (sigmoid)"]
    X2["x₂"] --> H1
    X2 --> H2
    H1 --> Y["y (output)"]
    H2 --> Y
    style X1 fill:#e1f5fe
    style X2 fill:#e1f5fe
    style H1 fill:#fff9c4
    style H2 fill:#fff9c4
    style Y fill:#c8e6c9

حدس: طبقة الإدخال مثل العينين، والطبقات المخفية مثل مناطق المعالجة في الدماغ، وطبقة الإخراج مثل الفم الذي ينطق الإجابة. كل طبقة تقوم بعملية "مجموع مرجّح + تحويل خطي".

(4) مقارنة: الشبكة العصبية البسيطة (Perceptron) مقابل الشبكة العصبية متعددة الطبقات (MLP) مقابل الشبكات العصبية العميقة

البعد الشبكة العصبية البسيطة (Perceptron) الشبكة العصبية متعددة الطبقات (MLP) الشبكة العصبية العميقة
عدد الطبقات طبقة واحدة (بدون طبقات مخفية) 2-3 طبقات ≥ 4 طبقات (بما في ذلك طبقات مخفية متعددة)
القدرات التصنيف الخطي التصنيف/الانحدار غير الخطي استخراج السمات المعقدة تلقائيًا
التدريب قواعد الشبكة العصبية البسيطة الانتشار العكسي الانتشار العكسي + تقنيات التحسين
التطبيقات النموذجية بوابات المنطق البسيطة التصنيف/الانحدار على نطاق صغير التعرف على الصور، معالجة اللغة الطبيعية، التوليد
عدد المعلمات عشرات مئات إلى آلاف عشرات المليارات إلى المليارات
النماذج الممثلة روزنبلات بيرسيبترون شبكة MLP ذات طبقتين CNN، Transformer


5. دوال التنشيط—إضافة عدمية الخطية للشبكة

(1) لماذا نحتاج إلى دوال التنشيط؟

بدون دوال التنشيط، بغض النظر عن عدد الطبقات، تكون الشبكة في جوهرها تحولاً خطيًا—تركيبة التحولات الخطية المتعددة تبقى خطية. تُدخل دوال التنشيط عدمية الخطية، مما يتيح للشبكة مواءمة المنحنيات والحدود المعقدة.

تشبيه: التحولات الخطية مثل "التمديد والتدوير"؛ بغض النظر عن عدد مرات تمديد الأشياء أو تدويرها، يظل النتيجة خطًا مستقيمًا أو سطحًا. دوال التنشيط مثل "الطي"—اطوِ ورقة مرة واحدة، وتتغير المساحة.

(2) مقارنة بين دوال التنشيط الشائعة

الدالة الصيغة نطاق الإخراج المزايا العيوب
سيجمويد $\sigma(z)=\frac{1}{1+e^{-z}}$ (0, 1) يمكن اعتبار الخرج كاحتمال تلاشي التدرجات، مركز غير صفري
تانج $\tanh(z)=\frac{e^z-e^{-z}}{e^z+e^{-z}}$ (-1, 1) مركزه صفري التدرج يتلاشى
ريلو $\max(0, z)$ [0, +∞) حساب سريع، يخفف من مشكلة تلاشي التدرج موت العصبون (التدرج هو 0 في المنطقة السالبة)
ليك ريلو $\max(0.01z, z)$ (-∞, +∞) يعالج موت العصبون يتطلب ضبط فرط المعاملات

▶ مثال: مقارنة قيم الخرج لدوال تنشيط مختلفة (الصعوبة: ⭐)

PYTHON
# Compare activation functions
import numpy as np

def sigmoid(z):
    return 1 / (1 + np.exp(-z))

def tanh(z):
    return np.tanh(z)

def relu(z):
    return np.maximum(0, z)

def leaky_relu(z, alpha=0.01):
    return np.where(z > 0, z, alpha * z)

z_values = np.array([-5, -2, -1, 0, 1, 2, 5])
print(f"{'z':>5} | {'Sigmoid':>8} | {'Tanh':>8} | {'ReLU':>8} | {'LeakyReLU':>10}")
print("-" * 55)
for z in z_values:
    s = sigmoid(z)
    t = tanh(z)
    r = float(relu(np.array([z]))[0])
    lr = float(leaky_relu(np.array([z]))[0])
    print(f"{z:5.1f} | {s:8.4f} | {t:8.4f} | {r:8.4f} | {lr:10.4f}")
💻 الإخراج:

TEXT 📖 للعرض فقط
    z |  Sigmoid |     Tanh |     ReLU |  LeakyReLU
-------------------------------------------------------
 -5.0 |   0.0067 |  -0.9999 |   0.0000 |    -0.0500
 -2.0 |   0.1192 |  -0.9640 |   0.0000 |    -0.0200
 -1.0 |   0.2689 |  -0.7616 |   0.0000 |    -0.0100
  0.0 |   0.5000 |   0.0000 |   0.0000 |     0.0000
  1.0 |   0.7311 |   0.7616 |   1.0000 |     1.0000
  2.0 |   0.8808 |   0.9640 |   2.0000 |     2.0000
  5.0 |   0.9933 |   0.9999 |   5.0000 |     5.0000
💡 نصيحة: تقترب تدرجات دالتَي السيجمويد والتانج من 0 (تلاشي التدرج) عندما يكون |z| كبيرًا، بينما يكون تدرج الريلو دائمًا 1 في المدى الموجب؛ لذلك، غالبًا ما يكون الريلو الخيار المفضل للشبكات العصبية العميقة.



6. الانتشار الأمامي والانتشار الخلفي

(1) الانتشار الأمامي: من المدخلات إلى المخرجات

الانتشار الأمامي هو العملية التي تنتقل فيها البيانات من طبقة الإدخال عبر كل طبقة حتى تصل إلى طبقة الإخراج:

  1. حساب مدخلات الطبقة المخفية: $z^{(1)} = W^{(1)} \cdot x + b^{(1)}$
  2. تطبيق دالة التنشيط: $h = \sigma(z^{(1)})$
  3. حساب مدخلات طبقة الإخراج: $z^{(2)} = W^{(2)} \cdot h + b^{(2)}$
  4. توقع الإخراج: $\hat{y} = \sigma(z^{(2)})$

(2) دالة الخسارة: قياس الفرق بين التوقع والقيمة الحقيقية

المتوسط الحسابي لمربعات الأخطاء (MSE) يُستخدم عادةً كدالة خسارة:

الخسارة هي مربع الفرق بين القيمة الفعلية والقيمة المتوقعة.

كلما كانت الخسارة أصغر، كان التوقع أكثر دقة. الهدف من التدريب هو إيجاد الأوزان التي تُقلل الخسارة.

(3) الانتشار الخلفي: من الخطأ إلى تحديثات الأوزان

الفكرة الأساسية للانتشار الخلفي: بدءًا من الخطأ في طبقة الإخراج، حساب "مساهمة" كل وزن في الخطأ عن طريق الانتشار الخلفي عبر الشبكة طبقة بطبقة، ثم ضبط الأوزان.

تشبيه حدسي: مصنع لديه مشكلة في منتجاته—

رياضيًا، هذه هي قاعدة السلسلة: $\frac{\partial L}{\partial w} = \frac{\partial L}{\partial \hat{y}} \cdot \frac{\partial \hat{y}}{\partial z} \cdot \frac{\partial z}{\partial w}$

(4) جدول المفاهيم الأساسية في الانتشار الخلفي

المفهوم المعنى الحدس
المنحدر (المشتقة) المشتقة الجزئية للخسارة بالنسبة للأوزان في أي اتجاه وبأي مقدار يجب ضبط الأوزان
معدل التعلم حجم الخطوة لكل تكرار كبير جدًا → يتجاوز الحد الأمثل؛ صغير جدًا → التدريب بطيء جدًا
قاعدة السلسلة تمرير المنحدر طبقة بطبقة تتبع "من المسؤول" طبقة بطبقة من الإخراج إلى الإدخال
تحديث الأوزان $w \leftarrow w - \eta \cdot \frac{\partial L}{\partial w}$ اتخاذ خطوة في الاتجاه المعاكس للمنحدر
تلاشي المنحدرات المنحدرات تتناقص مع كل طبقة وتقترب من 0 الطبقات الأولى تتعلم بالكاد شيئًا
انفجار المنحدرات المنحدرات تتصاعد طبقة بطبقة تحديثات الأوزان شديدة العدوانية، مما يسبب عدم استقرار النموذج

(5) حدسية لسطوح الخسارة

تخيل أنك تقف على جبل، وهدفك هو الوصول إلى قاع الوادي (أقل خسارة). مع كل خطوة، تسير على المنحدر الأكثر حدة—هذا هو الهبوط التدريجي (المنحدر). معدل التعلم يحدد حجم خطواتك:



7. جرب بسرعة نموذج MLP باستخدام sklearn

▶ مثال: تصنيف باستخدام MLPClassifier من sklearn (الصعوبة: ⭐)

PYTHON
# MLPClassifier on XOR problem
from sklearn.neural_network import MLPClassifier
import numpy as np

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

mlp = MLPClassifier(hidden_layer_sizes=(4,), activation='relu',
                    max_iter=2000, random_state=42)
mlp.fit(X, y)

print("XOR Predictions:")
for xi in X:
    print(f"  {xi} -> {mlp.predict([xi])[0]}")
print(f"Accuracy: {mlp.score(X, y):.2f}")
💻 المخرجات:

TEXT 📖 للعرض فقط
XOR Predictions:
  [0 0] -> 0
  [0 1] -> 1
  [1 0] -> 1
  [1 1] -> 0
Accuracy: 1.00
💡 نصيحة: يتعامل MLPClassifier من sklearn تلقائياً مع جميع التفاصيل، بما في ذلك الانتشار الأمامي، والانتشار العكسي، وتهيئة الأوزان. بمجرد فهمك للمبادئ الأساسية، يُعد استخدام المكتبة هو النهج الأكثر كفاءة.

▶ مثال: تصور التغيرات في حدود القرار (الصعوبة: ⭐⭐)

PYTHON
# Visualize MLP decision boundary on XOR
import numpy as np
import matplotlib.pyplot as plt
from sklearn.neural_network import MLPClassifier

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

fig, axes = plt.subplots(1, 3, figsize=(15, 4))
hidden_configs = [(2,), (4,), (8,)]

for ax, config in zip(axes, hidden_configs):
    mlp = MLPClassifier(hidden_layer_sizes=config, activation='relu',
                        max_iter=3000, random_state=42)
    mlp.fit(X, y)

    xx, yy = np.meshgrid(np.linspace(-0.5, 1.5, 100),
                         np.linspace(-0.5, 1.5, 100))
    Z = mlp.predict(np.c_[xx.ravel(), yy.ravel()]).reshape(xx.shape)

    ax.contourf(xx, yy, Z, alpha=0.3, cmap='coolwarm')
    ax.scatter(X[:,0], X[:,1], c=y, cmap='coolwarm', edgecolors='k', s=100)
    ax.set_title(f"Hidden: {config}, Acc: {mlp.score(X,y):.2f}")
    ax.set_xlabel("x1")
    ax.set_ylabel("x2")

plt.tight_layout()
plt.savefig("mlp_decision_boundary.png", dpi=100)
plt.show()

المخرجات: (شغّل المثال لرؤية المخرجات الفعلية، أو راجع ملاحظة المخرجات المتوقعة في تعليقات الكود أعلاه.)

💡 نصيحة: كلما زاد عدد العقد في الطبقة المخفية، زادت مرونة حدود القرار - ولكنها تصبح أكثر عرضة للإفراط في التعلم. قد لا تكون عقدتين كافيتين لتعلم XOR، بينما تكون ثماني عقد أكثر من اللازم.

▶ مثال: كيف يؤثر عدد العقد في الطبقة المخفية على الأداء (الصعوبة: ⭐⭐)

PYTHON
# Effect of hidden layer size on training loss
import numpy as np
from sklearn.neural_network import MLPClassifier
import matplotlib.pyplot as plt

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

fig, ax = plt.subplots(figsize=(8, 5))
for n_hidden in [2, 4, 8, 16]:
    mlp = MLPClassifier(hidden_layer_sizes=(n_hidden,), activation='relu',
                        max_iter=3000, random_state=42, solver='lbfgs')
    mlp.fit(X, y)
    ax.plot(range(len(mlp.loss_curve_)), mlp.loss_curve_,
            label=f"Hidden={n_hidden}")

ax.set_xlabel("Iteration")
ax.set_ylabel("Loss")
ax.set_title("Training Loss vs Hidden Layer Size")
ax.legend()
ax.set_yscale('log')
plt.savefig("hidden_size_loss.png", dpi=100)
plt.show()

المخرجات: (شغّل المثال لرؤية المخرجات الفعلية، أو راجع ملاحظة المخرجات المتوقعة في تعليقات الكود أعلاه.)

💡 نصيحة: عادةً ما تتقرب النماذج ذات العقد المخفية الأكبر بشكل أسرع ولديها خسارة أقل، لكنها تحتوي على معلمات أكثر وقد تُفرط في التعلم على مجموعات البيانات الصغيرة.



8. التعلم العميق = الشبكات العصبية متعددة الطبقات

(1) المقارنة بين التعلم الآلي التقليدي والتعلم العميق

البُعد التعلم الآلي التقليدي التعلم العميق
هندسة الميزات يتطلب تصميم وتحديد الميزات يدويًا يتعلم الميزات تلقائيًا من البيانات
متطلبات حجم البيانات يكفي كمية صغيرة من البيانات عادةً يتطلب كمية كبيرة من البيانات
موارد الحوسبة وحدة المعالجة المركزية (CPU) فقط عادةً يتطلب وحدة معالجة الرسومات (GPU)
قابلية تفسير النموذج مرتفعة (أشجار القرار، النماذج الخطية) منخفضة (صندوق أسود)
الحد الأقصى للأداء يعتمد على جودة الميزات يتناسب مع حجم البيانات والنموذج
الخوارزميات التمثيلية SVM، الغابة العشوائية، XGBoost CNN، RNN، Transformer
السيناريوهات المطبقة البيانات المنظمة، العينات الصغيرة البيانات غير المنظمة مثل الصور والنصوص والصوت

(2) ماذا يعني "عميق"؟

يشير مصطلح "العمق" إلى عدد الطبقات المخفية. من المتفق عليه عمومًا أن:

كلما زاد عدد الطبقات، أصبحت الميزات التي يمكن للشبكة استخراجها أكثر تجريدًا—قد تتعلم الطبقة الأولى الحواف، والطبقة الثانية قد تتعلم القوام، والطبقة الثالثة قد تتعلم المكونات؛ ومع التقدم أعمق في الشبكة، تصبح الميزات أكثر "دلالة" بشكل متزايد.

(3) المزيد من العمق ليس بالضرورة أفضل

شبكة أعمق لا تعني بالضرورة أداء أفضل. عدد كبير جدًا من الطبقات يمكن أن يؤدي إلى:

يجب اختيار عمق النموذج بناءً على تعقيد المهمة وكمية البيانات— تمامًا كبناء ناطحة سحاب: الأطول ليس دائمًا الأفضل؛ يجب مراعاة الأساس والميزانية.


9. تمرين عملي شامل: تنفيذ مصنف MLP من الصفر

▶ مثال: تنفيذ MLP من الصفر لحل مشكلة XOR (الصعوبة: ⭐⭐⭐)

سنقوم أدناه بتنفيذ MLP كامل باستخدام بايثون البحت (بدون أي أطر عمل)، بما في ذلك الانتشار الأمامي، والانتشار العكسي، وحلقة التدريب، بهدف حل مشكلة XOR.

PYTHON
# MLP from scratch: solve XOR with pure Python + NumPy
import numpy as np

# --- Activation functions and their derivatives ---
def sigmoid(z):
    return 1 / (1 + np.exp(-np.clip(z, -500, 500)))

def sigmoid_deriv(a):
    return a * (1 - a)

# --- MLP class ---
class MLP:
    def __init__(self, layer_sizes):
        # layer_sizes e.g. [2, 4, 1] => 2-input, 4-hidden, 1-output
        self.weights = []
        self.biases = []
        for i in range(len(layer_sizes) - 1):
            w = np.random.randn(layer_sizes[i], layer_sizes[i+1]) * 0.5
            b = np.zeros((1, layer_sizes[i+1]))
            self.weights.append(w)
            self.biases.append(b)

    def forward(self, X):
        self.activations = [X]
        for i in range(len(self.weights)):
            z = self.activations[-1] @ self.weights[i] + self.biases[i]
            a = sigmoid(z)
            self.activations.append(a)
        return self.activations[-1]

    def backward(self, y, lr=0.5):
        m = y.shape[0]
        deltas = [None] * len(self.weights)

        # Output layer delta
        output = self.activations[-1]
        deltas[-1] = (output - y) * sigmoid_deriv(output)

        # Hidden layer deltas (backprop)
        for i in range(len(self.weights) - 2, -1, -1):
            deltas[i] = (deltas[i+1] @ self.weights[i+1].T) * sigmoid_deriv(self.activations[i+1])

        # Update weights and biases
        for i in range(len(self.weights)):
            self.weights[i] -= lr * (self.activations[i].T @ deltas[i]) / m
            self.biases[i] -= lr * np.mean(deltas[i], axis=0, keepdims=True)

    def train(self, X, y, epochs=5000, lr=0.5):
        self.losses = []
        for epoch in range(epochs):
            pred = self.forward(X)
            loss = np.mean((y - pred) ** 2) / 2
            self.losses.append(loss)
            self.backward(y, lr)
            if epoch % 1000 == 0:
                print(f"Epoch {epoch:4d} | Loss: {loss:.6f}")

    def predict(self, X):
        return (self.forward(X) > 0.5).astype(int)

# --- Train on XOR ---
np.random.seed(42)
X = np.array([[0,0],[0,1],[1,0],[1,1]], dtype=float)
y = np.array([[0],[1],[1],[0]], dtype=float)

mlp = MLP([2, 4, 1])
mlp.train(X, y, epochs=5000, lr=1.0)

print("\nFinal Predictions:")
preds = mlp.predict(X)
for i in range(4):
    print(f"  XOR{X[i].astype(int).tolist()} = {preds[i,0]} (target: {y[i,0].astype(int)})")
💻 المخرجات:

TEXT 📖 للعرض فقط
Epoch    0 | Loss: 0.132415
Epoch 1000 | Loss: 0.004726
Epoch 2000 | Loss: 0.002517
Epoch 3000 | Loss: 0.001751
Epoch 4000 | Loss: 0.001330

Final Predictions:
  XOR[0, 0] = 0 (target: 0)
  XOR[0, 1] = 1 (target: 1)
  XOR[1, 0] = 1 (target: 1)
  XOR[1, 1] = 0 (target: 0)
💡 نصيحة: XOR هي مشكلة غير خطية كلاسيكية—المدرك الأحادي الطبقة (single-layer perceptron) لا يستطيع حلها، ولكن شبكة MLP ببنية 2→4→1 يمكنها حلها بشكل مثالي في بضع آلاف من التكرارات فقط. هذا يوضح قوة الشبكات متعددة الطبقات المدمجة مع دوال التنشيط غير الخطية.


❓ أسئلة شائعة

س ماذا يعني مصطلح "العميق" في التعلم العميق؟
ج "العميق" يشير إلى عدد الطبقات المخفية. تحتوي شبكات MLP التقليدية على 1-2 طبقة مخفية فقط، بينما تمتلك الشبكات العميقة عادةً 4 طبقات أو أكثر - أحيانًا حتى مئات. يعني "العميق" مستويات أكثر من التجريد للميزات، حيث تستخرج كل طبقة ميزات ذات مستوى أعلى بناءً على الطبقة السابقة.
س لماذا تعتبر الدوال التنشيطية ضرورية؟
ج بدون الدوال التنشيطية، فإن تكوين عدة تحويلات خطية سيظل خطياً - بغض النظر عن عدد الطبقات المكدسة، سيكون معادلاً لتحويل خطي من طبقة واحدة. تُدخل الدوال التنشيطية اللاخطية، مما يتيح للشبكة ملاءمة المنحنيات المعقدة وحدود القرار. بدونها، لن يكون التعلم العميق ممكناً.
س ماذا لو كان الانتشار العكسي معقدًا جدًا؟
ج لا تحتاج إلى تنفيذ الانتشار العكسي يدويًا. تحتسب الأطر الحديثة (PyTorch, TensorFlow) التدرجات تلقائيًا باستخدام التمايل التلقائي (Autograd). هناك ثلاثة مفاهيم رئيسية فقط تحتاج لفهمها: ① البدء من الخطأ في طبقة الخروج والانتشار للخلف طبقة بطبقة؛ ② يتم حساب "مسؤولية" كل طبقة باستخدام قاعدة السلسلة؛ ③ يتم تحديث الأوزان في الاتجاه المعاكس للتدرج. عند كتابة الكود فعليًا، يتولى الإطار جميع عمليات التفاضل لك.
س كم عدد الطبقات والعقد التي تحتاجها شبكة عصبية؟
ج لا توجد معادلة واحدة تناسب الجميع. عمليًا: ① البدء بشبكة صغيرة (1-2 طبقة مخفية، 32-128 عقدة لكل طبقة)؛ ② مراقبة أخطاء التدريب والتحقق لتحديد ما إذا كان يجب إضافة طبقات أخرى؛ ③ استخدام عدد أقل من العقد عندما يكون مجموعة البيانات صغيرة لمنع التجهيز المفرط؛ ④ النظر في شبكات أعمق وأوسع فقط عندما تكون مجموعة البيانات كبيرة والمعادلة معقدة. ضبط المعلمات الفائقة (الشبكي، العشوائي) هو نهج شائع.
س هل التعلم العميق أفضل دائمًا من التعلم الآلي التقليدي؟
ج ليس بالضرورة. يتمتع التعلم العميق بمزايا واضحة مع البيانات غير المنظمة مثل الصور والنصوص والكلام، لكن التعلم الآلي التقليدي يعمل أفضل في السيناريوهات التالية: ① مجموعات البيانات الصغيرة (< 1,000 عينة)؛ ② الميزات محددة جيدًا (بيانات جدولية منظمة)؛ ③ عندما تكون القابلية للتفسير مطلوبة؛ ④ عندما تكون الموارد الحاسوبية محدودة. يجب أن يعتمد اختيار النموذج على المهمة والبيانات والقيود، بدلاً من السعي الأعمى وراء "العمق".

📖 ملخص

المفهوم الأساسي: العصبون = مجموع مرجّح + تحويل غير خطي. الشبكة العصبية = العديد من العصبونات مكدّسة معًا. التعلم العميق = شبكة عصبية ذات طبقات كثيرة. من مُدرِك بـ 10 أسطر من الشيفرة إلى GPT، جميعها تتبع في الأساس نفس النموذج.

📝 تمارين

  1. الأساسيات (⭐): قم بتنفيذ خلية ادراك (perceptron) لبوابة OR. جدول الحقيقة للبوابة OR هو: (0,0) → 0، (0,1) → 1، (1,0) → 1، (1,1) → 1. قم بتعديل التسميات في كود تدريب الخلية العصبية من هذا الفصل، ثم قم بتدريب النموذج والتحقق من النتائج.
PYTHON
# Starter code: OR gate perceptron
X = [[0,0],[0,1],[1,0],[1,1]]
y_or = [0, 1, 1, 1]
# TODO: train and test
  1. متقدم (⭐⭐): استخدم MLPClassifier من sklearn لإجراء التصنيف على مجموعة بيانات Iris، وضبط المعلمات، وتسجيل الدقة للتكوينات المختلفة:
PYTHON
# Starter code: MLP on Iris
from sklearn.datasets import load_iris
from sklearn.neural_network import MLPClassifier
from sklearn.model_selection import train_test_split

iris = load_iris()
X_train, X_test, y_train, y_test = train_test_split(
    iris.data, iris.target, test_size=0.3, random_state=42)

# TODO: try different hidden_layer_sizes, activation, learning_rate
# Record accuracy for each config

جرب على الأقل 3 تكوينات مختلفة لـ hidden_layer_sizes (مثل (10,), (50,50), (100,)) و 2 دوال تنشيط، ولاحظ أي تكوين يعمل بشكل أفضل.

  1. تحدي (⭐⭐⭐): بناءً على تنفيذ MLP باستخدام Python النقي في هذا الفصل، قم برسم منحنى الخسارة للـ MLP الذي تم تنفيذه يدويًا:
PYTHON
# After training MLP from Section 9, plot the loss curve
import matplotlib.pyplot as plt

# mlp.losses is already recorded during training
plt.figure(figsize=(8, 5))
plt.plot(range(len(mlp.losses)), mlp.losses, linewidth=1)
plt.xlabel("العصر")
plt.ylabel("الخسارة (المتوسط التربيعي للخطأ)")
plt.title("منحنى خسارة تدريب MLP (XOR)")
plt.yscale('log')
plt.grid(True, alpha=0.3)
plt.savefig("mlp_loss_curve.png", dpi=100)
plt.show()

التمديدات المتقدمة: ① قارن منحنى الخسارة لمعدلات تعلم مختلفة (0.1، 0.5، 1.0، 2.0) على نفس الرسم البياني؛ ② جرب أحجام طبقات مخفية مختلفة (2، 4، 8) لمعرفة كيف تؤثر على معدل التقارب؛ ③ لاحظ ما إذا كانت الخسارة تتذبذب أو حتى تتباعد عندما يكون معدل التعلم مرتفعًا جدًا.

Web-Tutorial.com

فريق Web-Tutorial التقني

منصة دروس برمجية يديرها عدة مطورين. كل درس يتم كتابته ومراجعته بواسطة مطورين متخصصين في المجال. نعمل على ضمان دقة وموثوقية المحتوى — إذا لاحظت أي مشكلة، فيرجى إخبارنا.

100%