Machine Learning: الشبكات العصبية التلافيفية
آخر تحديث: 2026-08-26
تمنح CNNs أجهزة الكمبيوتر "عيونًا" — تعمل نوى التلافيف كمستقبلات بصرية، وتتعرف على الصور طبقة بعد طبقة، من الحواف إلى الأشياء.
1. ما ستتعلمه
- عمليات التلافيف: النوى/المرشحات، الخطوة، الحشو، التلافيف متعدد القنوات
- طبقات التجميع: MaxPool/AvgPool، الاختزال المكاني وثبات الترجمة
- البنيات الكلاسيكية: التطور من LeNet → AlexNet → VGG → ResNet والوصلات المتبقية
- التعلم بالنقل: النماذج المدربة مسبقًا (ImageNet) + الضبط الدقيق للدقة العالية مع بيانات محدودة
- تصنيف صور منتجات SalesPredict: التعرف التلقائي على فئة المنتج
2. قصة حقيقية من التجارة الإلكترونية
(1) نقطة الألم: تصنيف المنتجات اليدوي بطيء وغير متسق
تسرد منصة Bob 1000 منتج جديد كل يوم، ويجب على فريق العمليات فرز صور المنتجات يدويًا إلى الفئات الصحيحة. التصنيف اليدوي بطيء (5 ثوانٍ لكل صورة)، وغير متسق (أشخاص مختلفون يضعون نفس المنتج في فئات مختلفة)، ومكلف (30 ألف دولار شهريًا في تكاليف العمالة). تصنيف الصور هو عنق الزجاجة في عمليات التجارة الإلكترونية.
(2) حل CNN
تتعلم CNNs تلقائيًا الميزات البصرية من صور المنتجات لأداء التصنيف — سرعة على مستوى المللي ثانية، اتساق قوي، وصفر تكلفة عمالة.
import torchvision.models as models
# التعلم بالنقل: استخدم ResNet المدرب مسبقًا
model = models.resnet18(pretrained=True)
model.fc = nn.Linear(model.fc.in_features, num_classes) # استبدل الطبقة الأخيرة
(3) النتائج: دقة تصنيف 95%، توفير 30 ألف دولار شهريًا
استخدم Bob CNN + التعلم بالنقل لأتمتة تصنيف المنتجات، محققًا دقة تتجاوز 95%. تحسنت سرعة المعالجة من 5 ثوانٍ لكل صورة إلى 0.01 ثانية لكل صورة، مما يوفر 30 ألف دولار من تكاليف العمالة الشهرية.
3. كيف يعمل التلافيف
(1) النوى واستخراج الميزات
graph TB
INPUT[صورة الإدخال<br/>H x W x C] --> CONV1[طبقة تلافيف 1<br/>حواف وخطوط]
CONV1 --> POOL1[طبقة تجميع 1<br/>تقليل المكاني]
POOL1 --> CONV2[طبقة تلافيف 2<br/>قوام وأجزاء]
CONV2 --> POOL2[طبقة تجميع 2]
POOL2 --> CONV3[طبقة تلافيف 3<br/>أشياء وأشكال]
CONV3 --> FLATTEN[تسطيح]
FLATTEN --> FC[متصل بالكامل]
FC --> OUTPUT[احتمالات الفئة]
▶ مثال: تنفيذ التلافيف يدويًا
import torch
import torch.nn as nn
# الإدخال: صورة واحدة، قناة واحدة، 5x5
input_img = torch.tensor([[
[1, 2, 0, 1, 3],
[0, 1, 2, 3, 1],
[1, 3, 1, 0, 2],
[2, 0, 3, 1, 1],
[0, 1, 2, 0, 1],
]], dtype=torch.float32).unsqueeze(0) # الشكل: (1, 1, 5, 5)
# Conv2d: قناة إدخال واحدة، قناة إخراج واحدة، نواة 3x3
conv = nn.Conv2d(in_channels=1, out_channels=1, kernel_size=3, stride=1, padding=0)
print(f"Kernel weights:\n{conv.weight.data.squeeze()}")
print(f"Bias: {conv.bias.data.item():.4f}")
output = conv(input_img)
print(f"\nInput shape: {input_img.shape}")
print(f"Output shape: {output.shape}")
print(f"Output:\n{output.squeeze().detach()}")
Output:
# Execution successful
(2) معاملات التلافيف
| المعامل | المعنى | التأثير |
|---|---|---|
| kernel_size | حجم النواة | 3x3 (شائع) / 5x5 / 7x7 |
| stride | حجم الخطوة | 1 (افتراضي) / 2 (اختزال) |
| padding | حشو بالأصفار | 0 (يصغر) / 1 (يحافظ على الحجم) |
| in_channels | عدد قنوات الإدخال | RGB=3، رمادي=1 |
| out_channels | عدد قنوات الإخراج | يساوي عدد النوى |
▶ مثال: مقارنة تكوينات التلافيف المختلفة
import torch.nn as nn
x = torch.randn(1, 3, 32, 32) # دفعة واحدة، 3 قنوات، 32x32
configs = {
"3x3, stride=1, pad=1": nn.Conv2d(3, 16, 3, stride=1, padding=1),
"3x3, stride=2, pad=1": nn.Conv2d(3, 16, 3, stride=2, padding=1),
"5x5, stride=1, pad=2": nn.Conv2d(3, 16, 5, stride=1, padding=2),
"5x5, stride=2, pad=0": nn.Conv2d(3, 16, 5, stride=2, padding=0),
}
for name, layer in configs.items():
out = layer(x)
print(f"{name:25s}: {x.shape} → {out.shape}")
Output:
# Execution successful
4. طبقات التجميع وبنيات CNN
(1) عمليات التجميع
▶ مثال: MaxPool مقابل AvgPool
import torch
import torch.nn as nn
x = torch.tensor([[
[1, 3, 2, 4],
[5, 6, 7, 8],
[9, 2, 1, 3],
[4, 5, 6, 7],
]], dtype=torch.float32).unsqueeze(0) # (1, 1, 4, 4)
maxpool = nn.MaxPool2d(kernel_size=2, stride=2)
avgpool = nn.AvgPool2d(kernel_size=2, stride=2)
print(f"Input:\n{x.squeeze()}")
print(f"\nMaxPool (2x2):\n{maxpool(x).squeeze()}")
print(f"\nAvgPool (2x2):\n{avgpool(x).squeeze()}")
Output:
# Execution successful
(2) تطور البنيات الكلاسيكية
| البنية | السنة | الابتكار | العمق | المعاملات |
|---|---|---|---|---|
| LeNet | 1998 | أول CNN | 5 | 60 ألف |
| AlexNet | 2012 | ReLU + Dropout + GPU | 8 | 60 مليون |
| VGG | 2014 | نوى صغيرة مكدسة (3x3) | 16-19 | 138 مليون |
| ResNet | 2015 | وصلات متبقية (وصلات تخطي) | 18-152 | 11-60 مليون |
▶ مثال: بناء CNN بسيط باستخدام PyTorch
import torch
import torch.nn as nn
class SimpleCNN(nn.Module):
def __init__(self, num_classes=5):
super().__init__()
self.features = nn.Sequential(
nn.Conv2d(3, 32, 3, padding=1), # 3→32 قناة، 32x32
nn.ReLU(),
nn.MaxPool2d(2, 2), # 32→16x16
nn.Conv2d(32, 64, 3, padding=1), # 32→64 قناة، 16x16
nn.ReLU(),
nn.MaxPool2d(2, 2), # 16→8x8
nn.Conv2d(64, 128, 3, padding=1), # 64→128 قناة، 8x8
nn.ReLU(),
nn.MaxPool2d(2, 2), # 8→4x4
)
self.classifier = nn.Sequential(
nn.Flatten(),
nn.Linear(128 * 4 * 4, 256),
nn.ReLU(),
nn.Dropout(0.5),
nn.Linear(256, num_classes),
)
def forward(self, x):
x = self.features(x)
x = self.classifier(x)
return x
model = SimpleCNN(num_classes=5)
print(model)
print(f"Parameters: {sum(p.numel() for p in model.parameters()):,}")
Output:
# Function defined successfully
5. التعلم بالنقل
(1) لماذا يعمل التعلم بالنقل
تعلمت النماذج المدربة مسبقًا على ImageNet ميزات بصرية عامة (حواف → قوام → أجزاء الكائنات). تحتاج فقط إلى استبدال الطبقة الأخيرة للتكيف مع مهمة جديدة.
▶ مثال: التعلم بالنقل مع ResNet18
import torch
import torch.nn as nn
import torchvision.models as models
import torchvision.transforms as transforms
from torch.utils.data import DataLoader
import numpy as np
# تحميل ResNet18 المدرب مسبقًا
model = models.resnet18(weights=models.ResNet18_Weights.DEFAULT)
# تجميد جميع الطبقات (وضع مستخرج الميزات)
for param in model.parameters():
param.requires_grad = False
# استبدل آخر طبقة متصلة بالكامل
num_classes = 5 # Electronics, Clothing, Food, Books, Home
model.fc = nn.Linear(model.fc.in_features, num_classes)
# فقط طبقة fc الجديدة لها معاملات قابلة للتدريب
trainable = sum(p.numel() for p in model.parameters() if p.requires_grad)
total = sum(p.numel() for p in model.parameters())
print(f"Trainable: {trainable:,} / Total: {total:,} ({trainable/total*100:.1f}%)")
# تحويلات البيانات للنموذج المدرب مسبقًا
transform = transforms.Compose([
transforms.Resize(256),
transforms.CenterCrop(224),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])
Output:
# Execution successful
(2) استراتيجيات الضبط الدقيق
| الاستراتيجية | الطبقات المجمدة | حجم بيانات التدريب | وقت التدريب | الأفضل لـ |
|---|---|---|---|---|
| مستخرج الميزات | الكل (تدريب fc فقط) | صغير (<1k) | سريع | بيانات محدودة جدًا |
| ضبط دقيق جزئي | الطبقات الأخيرة القليلة | متوسط (1-10k) | متوسط | بيانات معتدلة |
| ضبط دقيق كامل | لا شيء | كبير (>10k) | بطيء | بيانات وفيرة |
▶ مثال: ضبط دقيق للطبقات الأخيرة القليلة
import torchvision.models as models
import torch.nn as nn
model = models.resnet18(weights=models.ResNet18_Weights.DEFAULT)
# تجميد الطبقات المبكرة، أطلق تجميد layer4
for name, param in model.named_parameters():
if "layer4" in name or "fc" in name:
param.requires_grad = True
else:
param.requires_grad = False
model.fc = nn.Linear(model.fc.in_features, 5)
trainable = sum(p.numel() for p in model.parameters() if p.requires_grad)
print(f"Fine-tune trainable params: {trainable:,}")
Output:
# Execution successful
6. تصنيف صور منتج SalesPredict
▶ مثال: خط أنابيب تدريب التعلم بالنقل الكامل
import torch
import torch.nn as nn
import torchvision.models as models
from torch.utils.data import DataLoader, TensorDataset
from sklearn.model_selection import train_test_split
import numpy as np
# محاكاة بيانات الصور (عمليًا، حمّل صورًا حقيقية مع ImageFolder)
rng = np.random.default_rng(42)
n = 2000
X = rng.standard_normal((n, 3, 224, 224)).astype(np.float32) # 3 قنوات 224x224
y = rng.integers(0, 5, n) # 5 فئات منتجات
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
train_ds = TensorDataset(torch.FloatTensor(X_train), torch.LongTensor(y_train))
test_ds = TensorDataset(torch.FloatTensor(X_test), torch.LongTensor(y_test))
train_loader = DataLoader(train_ds, batch_size=32, shuffle=True)
test_loader = DataLoader(test_ds, batch_size=64)
# ResNet18 المدرب مسبقًا مع رأس مخصص
model = models.resnet18(weights=models.ResNet18_Weights.DEFAULT)
for param in model.parameters():
param.requires_grad = False
model.fc = nn.Linear(model.fc.in_features, 5)
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.fc.parameters(), lr=0.001)
# التدريب
for epoch in range(10):
model.train()
correct, total = 0, 0
for X_batch, y_batch in train_loader:
y_pred = model(X_batch)
loss = criterion(y_pred, y_batch)
optimizer.zero_grad()
loss.backward()
optimizer.step()
correct += (y_pred.argmax(1) == y_batch).sum().item()
total += y_batch.size(0)
if epoch % 2 == 0:
print(f"Epoch {epoch}: loss={loss.item():.4f}, acc={correct/total:.3f}")
# تقييم
model.eval()
correct, total = 0, 0
with torch.no_grad():
for X_batch, y_batch in test_loader:
y_pred = model(X_batch)
correct += (y_pred.argmax(1) == y_batch).sum().item()
total += y_batch.size(0)
print(f"\nTest Accuracy: {correct/total:.3f}")
Output:
# Execution successful
❓ أسئلة شائعة
📖 ملخص
- تعمل نوى التلافيف كمستقبلات بصرية، تستخرج الميزات طبقة بعد طبقة: حواف → قوام → أجزاء → أشياء
- تقلل طبقات التجميع الأبعاد المكانية، وتزيد ثبات الترجمة، وتخفض التكلفة الحسابية
- تطورت بنيات CNN من LeNet إلى ResNet؛ تحل الوصلات المتبقية مشكلة تدريب الشبكات العميقة
- التعلم بالنقل: تجميد الطبقات المدربة مسبقًا + استبدال رأس التصنيف للدقة العالية مع بيانات محدودة
- ثلاث استراتيجيات لتصنيف المنتجات: مستخرج الميزات (بيانات قليلة)، ضبط دقيق جزئي (بيانات معتدلة)، ضبط دقيق كامل (بيانات وفيرة)
- يجب أن تتطابق المعالجة المسبقة للصور مع النموذج المدرب مسبقًا (Resize + Normalize)
📝 تمارين
- أساسي (الصعوبة ⭐): ابنِ CNN من طبقتين باستخدام nn.Conv2d + nn.MaxPool2d بإدخال 3x32x32 ومخرج 16x8x8. اطبع الشكل بعد كل طبقة. تلميح: Conv2d(3,8,3,pad=1) → Pool → Conv2d(8,16,3,pad=1) → Pool.
- متوسط (الصعوبة ⭐⭐): استخدم التعلم بالنقل (ResNet18) لتصنيف CIFAR-10 (10 فئات). تجميد جميع الطبقات باستثناء fc ودرب لـ 5 حقب. تلميح: torchvision.datasets.CIFAR10 + transforms.
- تحدٍّ (الصعوبة ⭐⭐⭐): قارن مستخرج الميزات مقابل الضبط الدقيق الجزئي مقابل الضبط الدقيق الكامل على CIFAR-10 من حيث الدقة ووقت التدريب. ارسم منحنيات الدقة مقابل الحقبة للاستراتيجيات الثلاث. تلميح: تجميد أعداد مختلفة من الطبقات وسجل دقة الاختبار في كل حقبة.
← الدرس السابق: مقدمة في التعلم العميق | الدرس التالي: تقييم النموذج والضبط →