Loss Functions — التعلم العميق
دوال الخسارة (Loss Functions)
دالة الخسارة رقم واحد يقيس كم يخطئ النموذج. التدريب = تعديل الأوزان لتصغير هذا الرقم. اختيارها يعتمد على نوع المشكلة.
الانحدار: MSE و MAE
MSE = متوسط (الفعلي − التنبؤ)² ← يعاقب الأخطاء الكبيرة بشدة
MAE = متوسط |الفعلي − التنبؤ| ← أقل حساسية للقيم الشاذةالتصنيف الثنائي: Binary Cross-Entropy
BCE = −[ y·log(p) + (1−y)·log(1−p) ]import numpy as np
def bce(y, p):
p = np.clip(p, 1e-7, 1 - 1e-7) # تجنب log(0)
return -(y * np.log(p) + (1 - y) * np.log(1 - p))
for p in [0.9, 0.6, 0.4, 0.01]:
print(f"الإجابة 1، الاحتمال {p}: خسارة {bce(1, p):.3f}")لاحظ: تنبؤ واثق وخاطئ (0.01 والإجابة 1) خسارته ضخمة (4.6). هذا ما نريده: الثقة الخاطئة أخطر من التردد.
لماذا لا MSE للتصنيف؟
مع sigmoid، MSE يعطي تدرجات ضعيفة جداً عندما يكون النموذج مخطئاً بثقة (منطقة تشبع sigmoid)، فيتعلم ببطء بالضبط حين يجب أن يتعلم أسرع. Cross-Entropy تلغي هذا التشبع رياضياً.
التصنيف المتعدد: Categorical Cross-Entropy
CCE = −log(احتمال الفئة الصحيحة)import numpy as np
probs = np.array([0.7, 0.2, 0.1]) # مخرج softmax لثلاث فئات
for correct in range(3):
print(f"الفئة الصحيحة {correct}: خسارة {-np.log(probs[correct]):.3f}")sparse أم لا؟
الفرق في صيغة الإجابات فقط:
| صيغة y | الخسارة في Keras |
|---|---|
| أرقام صحيحة: [2, 0, 1] | sparse_categorical_crossentropy |
| One-Hot: [[0,0,1], [1,0,0], ...] | categorical_crossentropy |
خلطهما من أشهر أخطاء المبتدئين (رسالة خطأ عن أشكال غير متطابقة).
جدول الربط النهائي
| المشكلة | طبقة المخرج | الخسارة |
|---|---|---|
| انحدار | Dense(1) بلا تنشيط | mse أو mae |
| ثنائي | Dense(1, activation="sigmoid") | binary_crossentropy |
| متعدد (فئة واحدة لكل عينة) | Dense(N, activation="softmax") | sparse_categorical_crossentropy |
| متعدد العلامات (عدة فئات معاً) | Dense(N, activation="sigmoid") | binary_crossentropy |
الخسارة ليست المقياس
الخسارة ما يحسّنه النموذج (يجب أن تكون قابلة للاشتقاق)، والمقياس (accuracy، F1) ما يهمك أنت. راقبهما معاً.
تمرين
لعينة إجابتها الفئة 2 من 4، احسب CCE لثلاثة مخرجات softmax مختلفة: واثق وصحيح، متردد، واثق وخاطئ. رتّبها من الأفضل للأسوأ.
import tensorflow as tf
from tensorflow import keras
# ===== التصنيف الثنائي =====
binary_model = keras.Sequential([
keras.layers.Dense(64, activation='relu'),
keras.layers.Dense(1, activation='sigmoid')
])
binary_model.compile(
optimizer='adam',
loss='binary_crossentropy', # للتصنيف الثنائي
metrics=['accuracy']
)
# ===== التصنيف المتعدد =====
multi_model = keras.Sequential([
keras.layers.Dense(64, activation='relu'),
keras.layers.Dense(10, activation='softmax')
])
# إذا y = [0, 0, 1, 0, ...] (one-hot)
multi_model.compile(
loss='categorical_crossentropy',
optimizer='adam'
)
# إذا y = [2, 5, 0, 3, ...] (أرقام)
multi_model.compile(
loss='sparse_categorical_crossentropy',
optimizer='adam'
)
# ===== الانحدار =====
regression_model = keras.Sequential([
keras.layers.Dense(64, activation='relu'),
keras.layers.Dense(1) # بدون activation
])
regression_model.compile(
loss='mse', # Mean Squared Error
optimizer='adam'
)
print("اختر Loss Function بناءً على نوع المشكلة!")اختبر فهمك