Loading
Loading
PyTorch is the most widely used library in deep learning research. It's flexible, intuitive, and GPU-ready. Most modern AI models are built with it.
Pythonic, easy to debug (standard Python execution), largest research community, and the backbone of Hugging Face (the go-to model hub).
Tensor: Multi-dimensional array with GPU support and automatic differentiation.
Autograd: PyTorch automatically tracks all operations and computes gradients:
x = torch.tensor(3.0, requires_grad=True)
y = x ** 2 # y = 9
y.backward() # computes dy/dx
x.grad # = 2x = 6
optimizer.zero_grad() # 1. clear gradients
output = model(X) # 2. forward pass
loss = criterion(output, y) # 3. compute loss
loss.backward() # 4. backpropagation
optimizer.step() # 5. update weights
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import Dataset, DataLoader, random_split
import numpy as np
print("=" * 55)
print("PyTorch: بناء شبكة عصبية كاملة")
print("=" * 55)
print(f"\nPyTorch version: {torch.__version__}")
print(f"GPU متاح: {torch.cuda.is_available()}")
device = "cuda" if torch.cuda.is_available() else "cpu"
print(f"Device: {device}")
# ─────────────────────────────────────────
# 1. Dataset مخصص
# ─────────────────────────────────────────
class CirclesDataset(Dataset):
"""بيانات دوائر — تصنيف غير خطي"""
def __init__(self, n_samples: int = 1000, noise: float = 0.1):
torch.manual_seed(42)
# دائرة داخلية
r1 = torch.randn(n_samples // 2, 2) * 0.5
# دائرة خارجية
angles = torch.rand(n_samples // 2) * 2 * 3.14159
r2 = torch.stack([torch.cos(angles) * 2, torch.sin(angles) * 2], dim=1)
r2 += torch.randn_like(r2) * noise
self.X = torch.vstack([r1, r2]).float()
self.y = torch.cat([torch.zeros(n_samples // 2),
torch.ones(n_samples // 2)]).long()
def __len__(self): return len(self.y)
def __getitem__(self, i): return self.X[i], self.y[i]
dataset = CirclesDataset(n_samples=1000)
train_set, val_set = random_split(dataset, [800, 200])
train_loader = DataLoader(train_set, batch_size=32, shuffle=True)
val_loader = DataLoader(val_set, batch_size=64)
print(f"\n1. Dataset جاهز: {len(train_set)} train / {len(val_set)} val")
# ─────────────────────────────────────────
# 2. بناء الشبكة
# ─────────────────────────────────────────
class DeepClassifier(nn.Module):
def __init__(self, input_dim: int = 2, hidden_dim: int = 64, num_classes: int = 2):
super().__init__()
self.net = nn.Sequential(
nn.Linear(input_dim, hidden_dim),
nn.BatchNorm1d(hidden_dim),
nn.ReLU(),
nn.Dropout(0.2),
nn.Linear(hidden_dim, hidden_dim),
nn.BatchNorm1d(hidden_dim),
nn.ReLU(),
nn.Dropout(0.2),
nn.Linear(hidden_dim, hidden_dim // 2),
nn.ReLU(),
nn.Linear(hidden_dim // 2, num_classes),
)
def forward(self, x: torch.Tensor) -> torch.Tensor:
return self.net(x)
model = DeepClassifier().to(device)
criterion = nn.CrossEntropyLoss()
optimizer = optim.AdamW(model.parameters(), lr=0.01, weight_decay=1e-4)
scheduler = optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=20)
total_params = sum(p.numel() for p in model.parameters())
print(f"2. النموذج: {total_params:,} معامل")
# ─────────────────────────────────────────
# 3. حلقة التدريب
# ─────────────────────────────────────────
def train_epoch(model, loader, optimizer, criterion):
model.train()
total_loss, correct, total = 0, 0, 0
for X, y in loader:
X, y = X.to(device), y.to(device)
optimizer.zero_grad()
out = model(X)
loss = criterion(out, y)
loss.backward()
optimizer.step()
total_loss += loss.item() * len(y)
correct += (out.argmax(1) == y).sum().item()
total += len(y)
return total_loss / total, correct / total
def eval_epoch(model, loader, criterion):
model.eval()
total_loss, correct, total = 0, 0, 0
with torch.no_grad():
for X, y in loader:
X, y = X.to(device), y.to(device)
out = model(X)
total_loss += criterion(out, y).item() * len(y)
correct += (out.argmax(1) == y).sum().item()
total += len(y)
return total_loss / total, correct / total
print("\n3. التدريب:")
print(f" {'Epoch':6s} | {'Train Loss':10s} | {'Train Acc':9s} | {'Val Acc':8s} | LR")
print(" " + "-" * 55)
best_val_acc = 0
for epoch in range(1, 21):
tr_loss, tr_acc = train_epoch(model, train_loader, optimizer, criterion)
vl_loss, vl_acc = eval_epoch(model, val_loader, criterion)
scheduler.step()
lr = optimizer.param_groups[0]["lr"]
if vl_acc > best_val_acc:
best_val_acc = vl_acc
torch.save(model.state_dict(), "best_model.pt")
if epoch % 5 == 0 or epoch == 1:
print(f" {epoch:6d} | {tr_loss:10.4f} | {tr_acc:9.1%} | {vl_acc:8.1%} | {lr:.5f}")
print(f"\n أفضل Val Accuracy: {best_val_acc:.1%}")