⏱️ 70 min

Image Classification Project

Build an end-to-end image classifier

Complete Image Classification Pipeline

Build a classifier for CIFAR-10 dataset:

python
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader
import torchvision
import torchvision.transforms as transforms

# Data preprocessing
transform_train = transforms.Compose([
    transforms.RandomCrop(32, padding=4),
    transforms.RandomHorizontalFlip(),
    transforms.ToTensor(),
    transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
])

transform_test = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
])

# Load CIFAR-10 (simulated for this example)
# trainset = torchvision.datasets.CIFAR10(root='./data', train=True, 
#                                          download=True, transform=transform_train)
# testset = torchvision.datasets.CIFAR10(root='./data', train=False,
#                                         download=True, transform=transform_test)

# For demonstration, create dummy data
trainset = [(torch.randn(3, 32, 32), i % 10) for i in range(1000)]
testset = [(torch.randn(3, 32, 32), i % 10) for i in range(200)]

trainloader = DataLoader(trainset, batch_size=32, shuffle=True)
testloader = DataLoader(testset, batch_size=32, shuffle=False)

# Define improved CNN
class ImprovedCNN(nn.Module):
    def __init__(self):
        super().__init__()
        self.features = nn.Sequential(
            nn.Conv2d(3, 64, 3, padding=1),
            nn.BatchNorm2d(64),
            nn.ReLU(),
            nn.Conv2d(64, 64, 3, padding=1),
            nn.BatchNorm2d(64),
            nn.ReLU(),
            nn.MaxPool2d(2),
            
            nn.Conv2d(64, 128, 3, padding=1),
            nn.BatchNorm2d(128),
            nn.ReLU(),
            nn.Conv2d(128, 128, 3, padding=1),
            nn.BatchNorm2d(128),
            nn.ReLU(),
            nn.MaxPool2d(2),
        )
        self.classifier = nn.Sequential(
            nn.Flatten(),
            nn.Linear(128 * 8 * 8, 512),
            nn.ReLU(),
            nn.Dropout(0.5),
            nn.Linear(512, 10)
        )
    
    def forward(self, x):
        x = self.features(x)
        x = self.classifier(x)
        return x

model = ImprovedCNN()
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

# Training loop
print("Training:")
model.train()
for epoch in range(5):
    running_loss = 0.0
    correct = 0
    total = 0
    
    for i, (inputs, labels) in enumerate(trainloader):
        optimizer.zero_grad()
        outputs = model(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()
        
        running_loss += loss.item()
        _, predicted = outputs.max(1)
        total += labels.size(0)
        correct += predicted.eq(labels).sum().item()
    
    acc = 100. * correct / total
    print(f"Epoch {epoch+1}: Loss = {running_loss/len(trainloader):.4f}, Accuracy = {acc:.2f}%")

# Evaluation
model.eval()
correct = 0
total = 0
with torch.no_grad():
    for inputs, labels in testloader:
        outputs = model(inputs)
        _, predicted = outputs.max(1)
        total += labels.size(0)
        correct += predicted.eq(labels).sum().item()

print(f"\nTest Accuracy: {100. * correct / total:.2f}%")
Output:
Training:
Epoch 1: Loss = 2.3087, Accuracy = 10.20%
Epoch 2: Loss = 2.2945, Accuracy = 11.80%
Epoch 3: Loss = 2.2756, Accuracy = 14.30%
Epoch 4: Loss = 2.2512, Accuracy = 17.60%
Epoch 5: Loss = 2.2201, Accuracy = 21.40%

Test Accuracy: 12.50%

Note: Results are from random data. With real CIFAR-10, 
expect 85-90% accuracy after 100 epochs.
Sharan Initiatives - Making a Difference Together