0–5 min
Real Hook
5–25 min
Core Concept
25–45 min
Live Coding
45–55 min
You Code It
55–60 min
Cheat Sheet
🔥 Real-World Hook (0–5 min)

India Post processes 100 million letters per year. Sorting by hand-reading ZIP codes = slow and error-prone. A neural network trained on MNIST-style digit images reads PINs with 99.7% accuracy — faster than any human.

Neural networks are the engine behind voice assistants, cancer detection, Google Translate, and ChatGPT. Today you build one from scratch.

📈 How a Neural Network Learns (5–25 min)

💡 Forward → Loss → Backward → Update

Forward pass — input flows through layers, each neuron: output = activation(weights · input + bias).
Loss — how wrong is the prediction? Cross-entropy for classification.
Backward pass — chain rule computes gradient of loss w.r.t. every weight.
Optimizer — SGD/Adam nudges weights in the direction that reduces loss.

💻 Live Demo — MNIST Digit Classifier (25–45 min)

>import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms
from torch.utils.data import DataLoader

# 1. Load MNIST (28x28 grayscale images, 10 digit classes)
transform = transforms.Compose([transforms.ToTensor()])
train_ds   = datasets.MNIST("./data", train=True,  download=True,  transform=transform)
test_ds    = datasets.MNIST("./data", train=False, download=True,  transform=transform)
train_dl   = DataLoader(train_ds, batch_size=64, shuffle=True)

# 2. Define network: 784 -> 256 -> 128 -> 10
class DigitNet(nn.Module):
    def __init__(self):
        super().__init__()
        self.net = nn.Sequential(
            nn.Flatten(),                # 28x28 -> 784
            nn.Linear(784, 256),
            nn.ReLU(),
            nn.Linear(256, 128),
            nn.ReLU(),
            nn.Linear(128, 10)            # 10 digit classes
        )
    def forward(self, x):
        return self.net(x)

model     = DigitNet()
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=1e-3)

# 3. Train for 3 epochs
for epoch in range(3):
    total_loss = 0
    for images, labels in train_dl:
        optimizer.zero_grad()
        loss = criterion(model(images), labels)
        loss.backward()
        optimizer.step()
        total_loss += loss.item()
    print(f"Epoch {epoch+1} loss: {total_loss/len(train_dl):.4f}" )

📋 You Code It (45–55 min)

✍ Task

Add a Dropout(0.3) layer after each ReLU. Run for 5 epochs. Does validation loss diverge less? Add an evaluation loop that prints test accuracy after training.

⚡ Day 7 Cheat Sheet

nn.Linear(in, out)
Fully-connected layer
nn.ReLU()
Activation (max(0,x))
nn.Sequential(...)
Stack layers in order
loss.backward()
Compute gradients
optimizer.step()
Update weights
optimizer.zero_grad()
Clear old gradients first
nn.Dropout(0.3)
Randomly zero 30% neurons
model.eval()
Switch off dropout/BN