PyTorch হাতে-কলমে: tensor, autograd, প্রথম training loop

প্রথম PyTorch model (Series 06, Episode 04)

🟡 INTERMEDIATE Series 06 — Deep Learning with PyTorch Episode 04 / 08

📑 এই পর্বে যা যা আছে

🧩 ১. গল্প: হাতের গণিত থেকে PyTorch-এ

গত পর্বে Rahim NumPy দিয়ে হাতে gradient হিসাব করে network শিখিয়েছে। কষ্টকর হলেও ভেতরটা পরিষ্কার হয়েছে। এখন Maya বলল — "ভালো, ভিত্তি হয়ে গেছে। এবার আসল কাজের হাতিয়ার শেখো, যেখানে gradient তোমাকে হাতে হিসাব করতে হবে না।"

Rahim: "মানে আমার এত কষ্টের chain rule বৃথা?"

Arif: "বৃথা না — ওটা তোমাকে বোঝাল ভেতরে কী হয়। কিন্তু production-এ কেউ হাতে gradient লেখে না। PyTorch-এর autograd সেটা automatically করে দেয়। তুমি শুধু forward pass আর loss লিখবে, loss.backward() বললেই backprop হয়ে যাবে। এবার তুমি বুঝবে কেন — কারণ ভেতরটা তুমি জানো।"

🔥 ২. PyTorch কী আর কেন এটাই বেছে নিচ্ছি?

PyTorch হলো Deep Learning-এর একটা framework (Meta AI-এর তৈরি)। এটা তিনটা জিনিস দেয়: (১) tensor — GPU-সমর্থিত array, (২) autograd — automatic differentiation, (৩) nn module — network বানানোর tools।

কেন PyTorch (TensorFlow নয়)? এই সিরিজে PyTorch primary কারণ — এর syntax Python-এর মতোই স্বাভাবিক ("Pythonic"), debugging সহজ (dynamic graph), research ও industry দুই জায়গায় এখন সবচেয়ে জনপ্রিয়, আর Hugging Face-এর মতো tools এর উপরই দাঁড়ানো। TensorFlow/Keras-এর তুলনা আমরা এই সিরিজের শেষ পর্বে (E08) করব। এখন একটা জিনিসে গভীর হওয়া ভালো।

📦 ৩. Setup ও install

Series 02-এর venv/uv মনে আছে? নতুন environment বানিয়ে PyTorch install করুন (CPU version যথেষ্ট শেখার জন্য):

# venv দিয়ে python -m venv .venv source .venv/bin/activate # Windows: .venv\Scripts\activate pip install torch torchvision # অথবা uv দিয়ে (দ্রুত) uv venv && source .venv/bin/activate uv pip install torch torchvision # যাচাই python -c "import torch; print(torch.__version__)"

কেন torchvision-ও? পরের পর্বগুলোতে (CNN, transfer learning) ছবি নিয়ে কাজ করব — torchvision দেয় dataset, pretrained model আর image transform।

🧱 ৪. Tensor — PyTorch-এর মূল বস্তু

Tensor হলো NumPy array-এর মতোই, শুধু (ক) GPU-তে চলতে পারে, (খ) gradient track করতে পারে। Series 03-এর NumPy জ্ঞান এখানে সরাসরি কাজে লাগবে।

import torch # তৈরি a = torch.tensor([1.0, 2.0, 3.0]) b = torch.zeros(2, 3) # 2x3 শূন্য c = torch.randn(2, 3) # random normal print(a.shape, b.shape) # torch.Size([3]) torch.Size([2, 3]) # NumPy-র মতোই operation print(a * 2) # tensor([2., 4., 6.]) print(a @ a) # dot product = 14.0 # NumPy <-> Tensor import numpy as np np_arr = np.array([1.0, 2.0]) t = torch.from_numpy(np_arr) # NumPy -> tensor back = t.numpy() # tensor -> NumPy

৫. Autograd — automatic gradient (backprop free!)

এখানেই PyTorch-এর জাদু। requires_grad=True দিলে PyTorch প্রতিটা operation মনে রাখে, আর .backward() বললে chain rule দিয়ে সব gradient হিসাব করে দেয় — গত পর্বে যেটা আমরা হাতে করেছিলাম।

import torch # গত পর্বের সেই y = 2x সমস্যা, এবার autograd দিয়ে X = torch.tensor([1., 2., 3., 4.]) Y = torch.tensor([2., 4., 6., 8.]) w = torch.tensor(0.0, requires_grad=True) # gradient track করবে # forward y_pred = w * X loss = ((y_pred - Y) ** 2).mean() # backward: autograd নিজে gradient বের করবে loss.backward() print("loss:", loss.item()) print("w-এর gradient:", w.grad.item()) # হাতে হিসাব করা লাগল না!
গত পর্বে আমরা grad = mean(2*(y_pred-Y)*X) হাতে লিখেছিলাম। এখন loss.backward() সেটাই স্বয়ংক্রিয়ভাবে w.grad-এ রেখে দিল। বড় network-এ লাখ লাখ weight-এর জন্য এটা জীবন বাঁচায়।

🏗️ ৬. nn.Module — model বানানোর ঠিক উপায়

ছোট উদাহরণে আলগা tensor চলে, কিন্তু আসল model বানাই nn.Module দিয়ে (Series 02-এর OOP এখানে কাজে লাগছে — class, __init__, method)।

import torch.nn as nn class TinyNet(nn.Module): def __init__(self, in_features, hidden, out_features): super().__init__() self.fc1 = nn.Linear(in_features, hidden) # layer 1 self.relu = nn.ReLU() self.fc2 = nn.Linear(hidden, out_features) # layer 2 def forward(self, x): x = self.relu(self.fc1(x)) # W1·x+b1 -> ReLU x = self.fc2(x) # W2·a1+b2 return x model = TinyNet(in_features=3, hidden=8, out_features=2) print(model) # parameters (weight+bias) কতগুলো total = sum(p.numel() for p in model.parameters()) print("মোট parameter:", total)

nn.Linear ভেতরে ঠিক সেই W·x + b করছে যা আমরা E02-এ NumPy-তে হাতে লিখেছিলাম।

🎚️ ৭. Optimizer — gradient descent PyTorch-এ

গত পর্বে w = w - lr*grad হাতে লিখেছিলাম। PyTorch-এ এটা করে optimizer। সবচেয়ে সাধারণ: SGD (সরল gradient descent) আর Adam (স্মার্ট, দ্রুত — ডিফল্ট পছন্দ)।

import torch.optim as optim optimizer = optim.Adam(model.parameters(), lr=0.01) # lr = learning rate (গত পর্বের সেই "পায়ের সাইজ")
optimizer.step() ঠিক কী করে? — .backward()-এ জমা হওয়া gradient ব্যবহার করে প্রতিটা parameter update করে (weight = weight − lr × grad)। এটাই gradient descent, শুধু PyTorch-এ মোড়ানো।

🔁 ৮. প্রথম সম্পূর্ণ training loop

এবার সব একসাথে — একটা আসল PyTorch training loop:

import torch import torch.nn as nn import torch.optim as optim # ডামি data: 3 feature, 2 class torch.manual_seed(0) X = torch.randn(100, 3) y = (X.sum(dim=1) > 0).long() # sum > 0 হলে class 1, নাহলে 0 model = TinyNet(3, 8, 2) criterion = nn.CrossEntropyLoss() # classification loss optimizer = optim.Adam(model.parameters(), lr=0.05) for epoch in range(100): optimizer.zero_grad() # 1) আগের gradient মুছে ফেলা (জরুরি!) logits = model(X) # 2) forward pass loss = criterion(logits, y) # 3) loss হিসাব loss.backward() # 4) backprop (autograd) optimizer.step() # 5) weight update if epoch % 20 == 0: acc = (logits.argmax(1) == y).float().mean() print(f"epoch {epoch:3d} | loss {loss.item():.3f} | acc {acc.item():.2f}")
⚠️ সবচেয়ে সাধারণ ভুল: optimizer.zero_grad() ভুলে যাওয়া। PyTorch gradient জমা (accumulate) করে; প্রতি step-এ আগেরটা মুছতে না হলে gradient যোগ হতে থাকে আর training ভেঙে পড়ে।

🖼️ ৯. Visual: PyTorch training loop-এর ৫ ধাপ

প্রতি epoch-এ: ┌─────────────────────────────────────────────┐ │ 1. optimizer.zero_grad() ← আগের grad মুছে ফেলা │ │ 2. pred = model(X) ← forward pass │ │ 3. loss = criterion(...) ← ভুল মাপা │ │ 4. loss.backward() ← autograd backprop │ │ 5. optimizer.step() ← weight update │ └─────────────────────────────────────────────┘ এই ৫ ধাপ = আপনার হাতে লেখা সেই ৪ ধাপেরই PyTorch রূপ

🧪 ১০. Experiment: autograd মিলিয়ে দেখুন

E05-এর autograd উদাহরণে w.grad-এর মান print করুন, তারপর গত পর্বের NumPy formula mean(2*(w*X - Y)*X) হাতে/আলাদা করে হিসাব করে মিলিয়ে দেখুন — একদম মিলবে। এতে বিশ্বাস জন্মাবে যে autograd কোনো জাদু নয়, ঠিক আপনার শেখা chain rule-ই করছে।

🖥️ ১১. GPU-তে চালানো (.to(device))

device = "cuda" if torch.cuda.is_available() else "cpu" model = model.to(device) X = X.to(device) y = y.to(device) # ব্যস — বাকি কোড একই। tensor আর model একই device-এ থাকলেই হবে।
Must Know: model আর data একই device-এ না থাকলে PyTorch error দেয় — junior-দের অতি সাধারণ bug। শেখার জন্য CPU যথেষ্ট; বড় image model-এ GPU লাগে (E06-এ কথা হবে)।

🇧🇩 ১২. বাংলাদেশের বাস্তব উদাহরণ

দেশের প্রায় সব AI-focused কোম্পানি (health-tech, agri-tech, NLP startup) এখন PyTorch-এ কাজ করে। Job description-এ "PyTorch" প্রায় ডিফল্ট। একজন junior যদি এই ৫-ধাপের training loop নিজে লিখতে পারে আর ব্যাখ্যা করতে পারে, সে সরাসরি অন্যদের থেকে এগিয়ে।

💼 ১৩. Boss Question

Boss: "এই PyTorch শেখা কি আমাদের product-এ সরাসরি লাগবে, নাকি শুধু গবেষণার জিনিস?"

উত্তর: "স্যার, সরাসরি লাগবে। আমাদের যেকোনো image বা text-ভিত্তিক feature — যেমন document থেকে তথ্য বের করা বা Bangla text classification — এসবের model PyTorch-এ বানানো ও train করা হয়। এটা শেখা মানে আমরা বাইরের vendor-এর উপর নির্ভরতা কমিয়ে নিজেরা custom model বানাতে পারব, যা দীর্ঘমেয়াদে খরচ কমায়।"

🔎 ১৪. Job Requirement Decoder

"Hands-on experience with PyTorch (or TensorFlow)."
প্রশ্নউত্তর
কী বোঝায়?আপনি PyTorch-এ model define, train, save ও inference করতে পারেন।
কেন চায়?প্রায় সব DL কাজ এই framework-এ হয়; আপনাকে দ্রুত productive হতে হবে।
কোন সমস্যা সমাধান করে?scratch থেকে গণিত না লিখে দ্রুত ও নির্ভরযোগ্য model বানানো।
junior-এর কী জানা লাগে?tensor, autograd, nn.Module, optimizer, ৫-ধাপের training loop, zero_grad-এর গুরুত্ব।
এখনই কী master লাগে না?custom CUDA kernel, distributed training, TorchScript/compile internals।
GitHub-এ কীভাবে দেখাবে?একটা clean PyTorch training script + README-তে loop-এর ব্যাখ্যা।
interview-তে কী?"optimizer.step() কী করে?", "zero_grad() কেন লাগে?", "loss.backward() কী করে?"

⚠️ ১৫. সাধারণ ভুল ধারণা

ভুল ১: optimizer.zero_grad() না দেওয়া → gradient জমে training ভাঙে।

ভুল ২: model .eval() mode ভুলে যাওয়া inference-এ → dropout/batchnorm ভুল আচরণ (পরে বিস্তারিত)।

ভুল ৩: "autograd জাদু" ভেবে ভেতরটা না বোঝা → debug করতে না পারা।

ভুল ৪: model GPU-তে, data CPU-তে → device mismatch error।

ভুল ৫: loss-এর জন্য .item() না নিয়ে পুরো tensor জমানো → memory leak।

🎤 ১৬. Interview Prep

প্রশ্ন ১: loss.backward() কী করে?
উত্তর: autograd দিয়ে সব parameter-এর gradient হিসাব করে .grad-এ রাখে (backprop)।

প্রশ্ন ২: optimizer.step() কী করে?
উত্তর: জমা gradient দিয়ে parameter update করে (gradient descent)।

প্রশ্ন ৩: zero_grad() কেন?
উত্তর: PyTorch gradient accumulate করে; প্রতি step-এ আগেরটা মুছতে না হলে ভুল update হয়।

প্রশ্ন ৪: Tensor আর NumPy array-এর পার্থক্য?
উত্তর: tensor GPU-তে চলে ও gradient track করে; বাকিটা প্রায় একই API।

✍️ ১৭. হাতে-কলমে

১. উপরের training loop চালিয়ে accuracy ০.৯-এর উপরে নিতে epoch/lr টিউন করুন।
২. hidden size ৮ থেকে ৩২ করুন — parameter সংখ্যা কত বাড়ল?
৩. optimizer.zero_grad() লাইনটা মুছে চালান — কী হয় নিজ চোখে দেখুন (loss কেমন আচরণ করে)।
৪. model save করুন: torch.save(model.state_dict(), "model.pt")

📌 ১৮. Project Connection ও সারসংক্ষেপ

এই PyTorch skeleton-ই আমাদের flagship-এর Deep Learning module আর এই সিরিজের P4 image classifier-এর ভিত্তি। পরের পর্বগুলোতে আমরা শুধু এই loop-এর ভেতরে ভালো model (MLP, CNN) আর ভালো data pipeline বসাব।

এই পর্বে শিখলাম:
✓ PyTorch = tensor + autograd + nn module; কেন এটা primary বেছে নিলাম
✓ tensor (GPU + gradient), autograd দিয়ে backprop স্বয়ংক্রিয়
✓ nn.Module দিয়ে model, optimizer দিয়ে update
✓ ৫-ধাপের training loop: zero_grad → forward → loss → backward → step
✓ zero_grad ভোলা, device mismatch — সবচেয়ে সাধারণ bug
পরবর্তী পর্ব (S06E05): "MLP দিয়ে classification" — একটা আসল Multi-Layer Perceptron বানিয়ে train করব; epoch, batch, learning rate কীভাবে টিউন করে model কার্যকর করব।
© 2025 Sheikh Thanbir Alam. All Rights Reserved. thanbirtamim.github.io
এই লেখা মূল লেখকের সম্পত্তি — লিখিত অনুমতি ছাড়া কপি করে অন্য কোনো ওয়েবসাইট, ব্লগ, বই বা প্ল্যাটফর্মে প্রকাশ/বিতরণ করা কঠোরভাবে নিষিদ্ধ। Content may not be copied or republished without permission.