Machine Learning: التعلم العميق مع PyTorch
آخر تحديث: 2026-08-26
يتيح التعلم العميق للآلات اكتشاف الميزات تلقائيًا - لا حاجة لتصميم يدوي. تجد الشبكة الأنماط في البيانات بنفسها.
1. ما ستتعلمه
- التعلم العميق مقابل ML التقليدي: متى تحتاج إلى شبكات عميقة، واعتبارات حول الحوسبة وحجم البيانات
- جوهر PyTorch: عمليات tensor، و autograd للتفاضل التلقائي، و تعريف نموذج nn.Module
- المتغير متعدد الطبقات (MLP): التمرير الأمامي، حساب الخسارة، الانتشار الخلفي، تحديث المعاملات
- تقنيات التدريب: تجميع DataLoader، جدولة معدل التعلم، التوقف المبكر، تدريب GPU
- متنبئ مبيعات MLP لـ Bob: مقارنة مع الانحدار الخطي من الدرس 7 لمعرفة ما إذا كانت الشبكة العصبية تحقق تحسنًا
2. قصة حقيقية من مهندس ML
(1) الألم: النماذج الخطية لا تستطيع التقاط تفاعلات الميزات
استخدم Bob الانحدار الخطي للتنبؤ بالمبيعات، لكنه حقق R² قدره 0.78 فقط. لاحظ أن التفاعل بين "الإنفاق الإعلاني × الترويج" له تأثير ضخم على المبيعات، لكن إضافة جميع مصطلحات التفاعل يدويًا (20 ميزة → 190 تفاعلًا) كانت مرهقة وعرضة للخطأ. افتراض النموذج الخطي (y = wx + b) بسيط جدًا - تفاعلات الميزات في العالم الحقيقي أكثر تعقيدًا بكثير مما يمكنك تصميمه يدويًا.
(2) حل التعلم العميق
تتعلم الشبكات العصبية تفاعلات الميزات والتحويلات غير الخطية تلقائيًا من خلال الطبقات المخفية - لا حاجة لهندسة يدوية.
import torch.nn as nn
model = nn.Sequential(
nn.Linear(20, 64),
nn.ReLU(),
nn.Linear(64, 32),
nn.ReLU(),
nn.Linear(32, 1),
)
(3) النتيجة: MLP يكتشف التفاعلات تلقائيًا، يقفز R² إلى 0.86
استبدل Bob الانحدار الخطي بـ MLP من 3 طبقات. تعلمت الشبكة تلقائيًا النمط "إنفاق إعلاني عالٍ + ترويج = قفزة في المبيعات"، دافعًا بـ R² من 0.78 إلى 0.86 - بدون تصميم مصطلح تفاعل واحد يدويًا.
3. التعلم العميق مقابل ML التقليدي
(1) متى تختار التعلم العميق
| المعيار | ML التقليدي (مثل XGBoost) | التعلم العميق (مثل MLP/CNN) |
|---|---|---|
| نوع البيانات | بيانات جدولية | صور / نص / صوت / جدولية معقدة |
| حجم البيانات | <100 ألف | >100 ألف |
| هندسة الميزات | تتطلب تصميمًا يدويًا | تتعلم الميزات تلقائيًا |
| وقت التدريب | دقائق إلى ساعات | ساعات إلى أيام |
| الأجهزة | وحدة المعالجة المركزية كافية | يوصى بـ GPU |
| القابلية للتفسير | عالية (المعاملات / الأهميات) | منخفضة (صندوق أسود) |
| الأداء الجدولي | عادة أفضل | ليس بالضرورة أفضل |
▶ مثال: تثبيت PyTorch والتحقق منه
import torch
print(f"PyTorch version: {torch.__version__}")
print(f"CUDA available: {torch.cuda.is_available()}")
if torch.cuda.is_available():
print(f"GPU: {torch.cuda.get_device_name(0)}")
# عمليات tensor الأساسية
a = torch.tensor([1.0, 2.0, 3.0])
b = torch.tensor([4.0, 5.0, 6.0])
print(f"a + b = {a + b}")
print(f"a * b = {a * b}")
print(f"Mean of a: {a.mean()}")
Output:
# Executed successfully
4. مفاهيم PyTorch الجوهرية
(1) عمليات Tensor
▶ مثال: إنشاء ومعالجة Tensors
import torch
# إنشاء tensors
a = torch.zeros(3, 4)
b = torch.ones(2, 3)
c = torch.randn(3, 3) # التوزيع الطبيعي
d = torch.arange(0, 10, 2)
# من NumPy
import numpy as np
arr = np.array([1, 2, 3])
t = torch.from_numpy(arr)
# Tensor إلى NumPy
back = t.numpy()
# GPU tensor
if torch.cuda.is_available():
gpu_tensor = torch.randn(3, 3).cuda()
cpu_back = gpu_tensor.cpu()
# إعادة التشكيل
x = torch.arange(12)
matrix = x.reshape(3, 4)
print(f"Shape: {matrix.shape}")
# البث
a = torch.ones(3, 1)
b = torch.ones(1, 4)
c = a + b # (3,4)
print(f"Broadcast result shape: {c.shape}")
Output:
# Executed successfully
(2) Autograd: التفاضل التلقائي
▶ مثال: التفاضل التلقائي
import torch
# مثال على التفاضل التلقائي
x = torch.tensor([2.0], requires_grad=True)
y = x ** 2 + 3 * x + 1 # y = x² + 3x + 1
y.backward() # dy/dx = 2x + 3
print(f"x = {x.item()}")
print(f"y = {y.item()}")
print(f"dy/dx = {x.grad.item()}") # يجب أن يكون 2*2+3 = 7
print(f"Manual check: 2*2 + 3 = {2*2+3}")
Output:
# Executed successfully
(3) تعريف النماذج باستخدام nn.Module
▶ مثال: نموذج MLP مخصص
import torch
import torch.nn as nn
class SalesPredictMLP(nn.Module):
def __init__(self, input_dim, hidden_dims, output_dim=1):
super().__init__()
layers = []
prev_dim = input_dim
for hidden_dim in hidden_dims:
layers.append(nn.Linear(prev_dim, hidden_dim))
layers.append(nn.BatchNorm1d(hidden_dim))
layers.append(nn.ReLU())
layers.append(nn.Dropout(0.2))
prev_dim = hidden_dim
layers.append(nn.Linear(prev_dim, output_dim))
self.network = nn.Sequential(*layers)
def forward(self, x):
return self.network(x)
model = SalesPredictMLP(input_dim=20, hidden_dims=[64, 32], output_dim=1)
print(model)
print(f"Total parameters: {sum(p.numel() for p in model.parameters()):,}")
Output:
# Functions defined successfully
5. خط أنابيب تدريب MLP الكامل
(1) حلقة التدريب
sequenceDiagram
participant Data as DataLoader
participant Fwd as التمرير الأمامي
participant Loss as حساب الخسارة
participant Zero as تصفير التدرجات
participant Bwd as التمرير الخلفي
participant Step as خطوة المحسن
loop كل حقبة
Data->>Fwd: دفعة من (X, y)
Fwd->>Loss: y_pred = model(X)
Loss->>Zero: loss = criterion(y_pred, y)
Zero->>Bwd: optimizer.zero_grad()
Bwd->>Step: loss.backward()
Step->>Data: optimizer.step()
end
▶ مثال: خط أنابيب تدريب MLP الكامل
import torch
import torch.nn as nn
from torch.utils.data import DataLoader, TensorDataset
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import r2_score, mean_absolute_error
import numpy as np
# توليد البيانات
rng = np.random.default_rng(42)
n = 5000
X = rng.uniform(0, 100, (n, 20))
y = (50 + X[:, :5] @ [0.8, 1.2, -0.5, 0.3, 0.1]
+ 0.5 * X[:, 0] * X[:, 1] # تفاعل
+ np.sin(X[:, 2]) * 5 # غير خطي
+ rng.normal(0, 5, n))
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
scaler = StandardScaler()
X_train_s = scaler.fit_transform(X_train)
X_test_s = scaler.transform(X_test)
# إنشاء DataLoaders
train_ds = TensorDataset(torch.FloatTensor(X_train_s), torch.FloatTensor(y_train))
test_ds = TensorDataset(torch.FloatTensor(X_test_s), torch.FloatTensor(y_test))
train_loader = DataLoader(train_ds, batch_size=64, shuffle=True)
test_loader = DataLoader(test_ds, batch_size=256)
# النموذج والخسارة والمحسن
model = SalesPredictMLP(input_dim=20, hidden_dims=[128, 64, 32])
criterion = nn.MSELoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001, weight_decay=1e-4)
scheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(optimizer, patience=10, factor=0.5)
# حلقة التدريب
train_losses, val_losses = [], []
best_val_loss = float("inf")
for epoch in range(100):
model.train()
epoch_loss = 0
for X_batch, y_batch in train_loader:
y_pred = model(X_batch).squeeze()
loss = criterion(y_pred, y_batch)
optimizer.zero_grad()
loss.backward()
optimizer.step()
epoch_loss += loss.item()
avg_train_loss = epoch_loss / len(train_loader)
train_losses.append(avg_train_loss)
# التحقق
model.eval()
val_loss = 0
with torch.no_grad():
for X_batch, y_batch in test_loader:
y_pred = model(X_batch).squeeze()
val_loss += criterion(y_pred, y_batch).item()
avg_val_loss = val_loss / len(test_loader)
val_losses.append(avg_val_loss)
scheduler.step(avg_val_loss)
# التوقف المبكر
if avg_val_loss < best_val_loss:
best_val_loss = avg_val_loss
best_state = model.state_dict().copy()
if epoch % 20 == 0:
print(f"Epoch {epoch:3d}: train_loss={avg_train_loss:.4f}, val_loss={avg_val_loss:.4f}")
# تحميل أفضل نموذج وتقييمه
model.load_state_dict(best_state)
model.eval()
with torch.no_grad():
y_pred = model(torch.FloatTensor(X_test_s)).squeeze().numpy()
print(f"\nMLP R²: {r2_score(y_test, y_pred):.4f}")
print(f"MLP MAE: {mean_absolute_error(y_test, y_pred):.2f}")
Output:
# Executed successfully
6. مواجهة MLP والانحدار الخطي لـ Bob
▶ مثال: مواجهة مباشرة على نفس مجموعة البيانات
from sklearn.linear_model import LinearRegression
from sklearn.metrics import r2_score, mean_absolute_error
# خط أساس الانحدار الخطي
lr = LinearRegression()
lr.fit(X_train_s, y_train)
lr_pred = lr.predict(X_test_s)
print("=" * 50)
print("MODEL COMPARISON")
print("=" * 50)
print(f"Linear Regression: R²={r2_score(y_test, lr_pred):.4f}, MAE={mean_absolute_error(y_test, lr_pred):.2f}")
print(f"MLP (3-layer): R²={r2_score(y_test, y_pred):.4f}, MAE={mean_absolute_error(y_test, y_pred):.2f}")
Output:
=
MODEL COMPARISON
=
| البُعد | LinearRegression | MLP (3 طبقات) |
|---|---|---|
| R² | 0.78 | 0.86 |
| MAE | 12.5 | 9.3 |
| تفاعلات الميزات | تُضاف يدويًا | تُتعلم تلقائيًا |
| وقت التدريب | <1 ثانية | ~30 ثانية |
| القابلية للتفسير | عالية (المعاملات) | منخفضة (صندوق أسود) |
| مخاطرة فرط التجهيز | منخفضة | متوسطة |
❓ أسئلة شائعة
📖 ملخص
- التعلم العميق يتعلم تمثيلات الميزات تلقائيًا؛ ML التقليدي يتطلب هندسة ميزات يدوية
- جوهر PyTorch: tensors (مصفوفات متعددة الأبعاد)، autograd (التفاضل التلقائي)، nn.Module (تعريف النموذج)
- حلقة تدريب MLP ذات خمس خطوات: forward → loss → zero_grad → backward → step
- DataLoader للتجميع، جداول لاضمحلال معدل التعلم، التوقف المبكر لمنع فرط التجهيز
- MLP مقابل الانحدار الخطي: يتعلم التفاعلات تلقائيًا، R² أعلى، لكن قابلية التفسير أقل
- على البيانات الجدولية، يتفوق GBDT عادة على MLPs؛ يتألق MLPs عندما تكون تفاعلات الميزات معقدة أو البيانات غير منظمة
📝 تمارين
- أساسي (الصعوبة ⭐): أنشئ MLP من طبقتين في PyTorch (إدخال 4-أبعاد → 16 → 8 → مخرج 1). اطبع بنية النموذج والعدد الإجمالي للمعاملات. تلميح: nn.Sequential +
sum(p.numel()...). - متوسط (الصعوبة ⭐⭐): استخدم MLP للتنبؤ بأسعار California Housing. نفّذ حلقة تدريب كاملة (مع تحقق وتوقف مبكر)، ثم قارن R² مع LinearRegression. تلميح: راجع خط أنابيب التدريب الكامل في القسم 5.
- تحدٍّ (الصعوبة ⭐⭐⭐): جرب بنيات MLP مختلفة (1/2/3 طبقات، أحجام مخفية متفاوتة). ارسم منحنى "عدد الطبقات المخفية مقابل R²" واعثر على البنية المثلى. تلميح: حلقة على configs hidden_dims مختلفة وسجل R² التحقق.
← الدرس السابق: أساسيات NLP | الدرس التالي: الشبكات العصبية التلافيفية →