Chapter 14

PyTorch-এর মূল

PyTorch Fundamentals
🎬 কেন PyTorch?
Meta (Facebook)-এর তৈরি PyTorch — গবেষণা জগতের সবচেয়ে প্রিয়। Pythonic syntax, dynamic computational graph, এবং debug করা সহজ। আজকের প্রায় সব নতুন পেপার PyTorch-এ আসে — ChatGPT, Llama, Stable Diffusion সব এতে তৈরি।

Tensor — PyTorch-এর মূল

import torch

a = torch.tensor([[1., 2.], [3., 4.]])
b = torch.randn(2, 3)               # random
c = torch.zeros(3, 3)
d = torch.arange(10).reshape(2, 5)

print(a + a)
print(a @ a)                         # matrix mul
print(a.shape, a.dtype, a.device)

# GPU-তে নিয়ে যান
if torch.cuda.is_available():
    a = a.to("cuda")

Autograd — স্বয়ংক্রিয় derivative

x = torch.tensor(3.0, requires_grad=True)
y = x ** 2 + 5 * x + 4

y.backward()
print(x.grad)    # dy/dx = 2x + 5 = 11

nn.Module — মডেলের ভিত্তি

import torch.nn as nn
import torch.nn.functional as F

class MLP(nn.Module):
    def __init__(self):
        super().__init__()
        self.fc1 = nn.Linear(784, 128)
        self.fc2 = nn.Linear(128, 64)
        self.fc3 = nn.Linear(64, 10)

    def forward(self, x):
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        return self.fc3(x)             # CrossEntropyLoss নিজেই softmax করে

model = MLP()
print(model)

সম্পূর্ণ Training Loop — MNIST

from torchvision import datasets, transforms
from torch.utils.data import DataLoader

transform = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize((0.1307,), (0.3081,)),
])

train_ds = datasets.MNIST("./data", train=True, download=True, transform=transform)
test_ds  = datasets.MNIST("./data", train=False, transform=transform)

train_loader = DataLoader(train_ds, batch_size=64, shuffle=True)
test_loader  = DataLoader(test_ds, batch_size=256)

device = "cuda" if torch.cuda.is_available() else "cpu"
model = MLP().to(device)
optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)
loss_fn = nn.CrossEntropyLoss()

for epoch in range(5):
    model.train()
    for x, y in train_loader:
        x, y = x.view(-1, 784).to(device), y.to(device)
        pred = model(x)
        loss = loss_fn(pred, y)

        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

    # eval
    model.eval()
    correct = 0
    with torch.no_grad():
        for x, y in test_loader:
            x, y = x.view(-1, 784).to(device), y.to(device)
            pred = model(x).argmax(1)
            correct += (pred == y).sum().item()
    print(f"Epoch {epoch+1}: acc {correct/len(test_ds):.4f}")

Training Loop-এর ৪ মন্ত্র

pred = model(x)            # 1. Forward
loss = loss_fn(pred, y)    # 2. Loss
optimizer.zero_grad()      # 3a. পুরনো grad মুছুন
loss.backward()            # 3b. নতুন grad
optimizer.step()           # 4. Update

Save ও Load

# শুধু state_dict save (recommended)
torch.save(model.state_dict(), "model.pt")

# Load
model = MLP()
model.load_state_dict(torch.load("model.pt"))
model.eval()

PyTorch vs TensorFlow

PyTorch
TensorFlow
Graph
Dynamic (eager)
Eager + Graph
Syntax
Pythonic
API-heavy
Research
★★★★★
★★★
Production
TorchServe / ONNX
TF Serving, TFLite
Mobile
PyTorch Mobile
TFLite (পরিপক্ক)

সাধারণ ভুল ধারণা

⚠️ এড়িয়ে চলবেন
  • zero_grad() ভুলে যাওয়া — gradient জমে অদ্ভুত behavior।
  • model.train()model.eval() না বদলানো — Dropout/BN ভুল হবে।
  • Inference-এ torch.no_grad() না দেওয়া — memory waste।
  • Tensor CPU/GPU mismatch।

অনুশীলন

১. Fashion-MNIST-এ উপরের মডেল চালান।

২. Optimizer Adam → SGD+Momentum-এ বদলে দেখুন।

৩. nn.Dropout(0.3) যোগ করে overfit কমান।

মিনি প্রজেক্ট

🚀 আজকের চ্যালেঞ্জ
নিজের একটি custom Dataset class বানান — folder থেকে ছবি পড়ে label সহ দেবে। তারপর DataLoader-এ wrap করে train করুন।

ইন্টারভিউ প্রশ্ন

  1. requires_grad ও autograd কীভাবে কাজ করে?
  2. model.train() vs model.eval()
  3. PyTorch vs TensorFlow — পছন্দ কোনটি ও কেন।
  4. Dynamic vs static computational graph।

সারসংক্ষেপ

✨ এই অধ্যায়ে যা শিখলাম
  • PyTorch Tensor + Autograd।
  • nn.Module দিয়ে মডেল।
  • Training loop-এর ৪ মন্ত্র।
  • পরের অধ্যায়ে — পুরো training pipeline একসাথে।