$ init portfolio
R
Back to Blog
PyTorchPythonDeep Learning

PyTorch: A Practical Introduction

Get started with PyTorch — tensors, autograd, building models, and training your first neural network.

Raj Tiwari
Raj Tiwari
2026-07-126 min read
PyTorch: A Practical Introduction

Why PyTorch?

PyTorch is the most popular framework for deep learning research. Its dynamic computation graph (define-by-run) makes debugging intuitive and development fast.

Autograd: Automatic Differentiation

PyTorch tracks operations on tensors and can compute gradients automatically.

python
class="text-purple-400 font-medium">import torch

x = torch.tensor(class="text-amber-300">2.0, requires_grad=True)
y = x ** class="text-amber-300">3 + class="text-amber-300">2 * x ** class="text-amber-300">2 + x

y.backward()  class=class="text-emerald-class="text-amber-300">400">"text-gray-class="text-amber-300">500 italic"># Compute dy/dx
print(x.grad)  class=class="text-emerald-class="text-amber-300">400">"text-gray-class="text-amber-300">500 italic"># dy/dx at x=class="text-amber-300">2 = class="text-amber-300">3*class="text-amber-300">4 + class="text-amber-300">4*class="text-amber-300">2 + class="text-amber-300">1 = class="text-amber-300">21

Building a Classifier

python
class="text-purple-400 font-medium">import torch
class="text-purple-400 font-medium">import torch.nn as nn
class="text-purple-400 font-medium">import torch.optim as optim
class="text-purple-400 font-medium">from sklearn.datasets class="text-purple-400 font-medium">import load_iris
class="text-purple-400 font-medium">from sklearn.model_selection class="text-purple-400 font-medium">import train_test_split
class="text-purple-400 font-medium">from sklearn.preprocessing class="text-purple-400 font-medium">import StandardScaler

class=class="text-emerald-class="text-amber-300">400">"text-gray-class="text-amber-300">500 italic"># Load data
iris = load_iris()
X_train, X_test, y_train, y_test = train_test_split(
    iris.data, iris.target, test_size=class="text-amber-300">0.2
)

scaler = StandardScaler()
X_train = torch.FloatTensor(scaler.fit_transform(X_train))
X_test = torch.FloatTensor(scaler.transform(X_test))
y_train = torch.LongTensor(y_train)
y_test = torch.LongTensor(y_test)

class=class="text-emerald-class="text-amber-300">400">"text-gray-class="text-amber-300">500 italic"># Define model
class Classifier(nn.Module):
    class="text-purple-400 font-medium">def __init__(self):
        super().__init__()
        self.net = nn.Sequential(
            nn.Linear(class="text-amber-300">4, class="text-amber-300">32),
            nn.ReLU(),
            nn.Linear(class="text-amber-300">32, class="text-amber-300">16),
            nn.ReLU(),
            nn.Linear(class="text-amber-300">16, class="text-amber-300">3)
        )

    class="text-purple-400 font-medium">def forward(self, x):
        return self.net(x)

model = Classifier()
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=class="text-amber-300">0.01)

class=class="text-emerald-class="text-amber-300">400">"text-gray-class="text-amber-300">500 italic"># Training loop
for epoch in range(class="text-amber-300">100):
    outputs = model(X_train)
    loss = criterion(outputs, y_train)

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

    if (epoch + class="text-amber-300">1) % class="text-amber-300">20 == class="text-amber-300">0:
        print(class="text-emerald-class="text-amber-300">400">f"Epoch [{epoch+class="text-amber-300">1}/class="text-amber-300">100], Loss: {loss.item():.4f}")

class=class="text-emerald-class="text-amber-300">400">"text-gray-class="text-amber-300">500 italic"># Evaluate
with torch.no_grad():
    outputs = model(X_test)
    _, predicted = torch.max(outputs, class="text-amber-300">1)
    accuracy = (predicted == y_test).float().mean()
    print(class="text-emerald-class="text-amber-300">400">f"Accuracy: {accuracy:.class="text-amber-300">2%}")

Saving and Loading Models

python
class=class="text-emerald-class="text-amber-300">400">"text-gray-class="text-amber-300">500 italic"># Save
torch.save(model.state_dict(), class="text-emerald-class="text-amber-300">400">"model.pth")

class=class="text-emerald-class="text-amber-300">400">"text-gray-class="text-amber-300">500 italic"># Load
model = Classifier()
model.load_state_dict(torch.load(class="text-emerald-class="text-amber-300">400">"model.pth"))
model.eval()

Key Takeaways

  • PyTorch uses dynamic computation graphs for flexible model building
  • autograd handles gradient computation automatically
  • Use nn.Sequential for simple architectures, forward() for custom ones
  • Always call optimizer.zero_grad() before loss.backward()
0