Bird
Raised Fist0
PyTorchml~20 mins

Validation loop in PyTorch - ML Experiment: Train & Evaluate

Choose your learning style10 modes available
Experiment - Validation loop
Problem:You have trained a PyTorch model on a training dataset, but you do not have a proper validation loop to check how well the model performs on unseen data during training.
Current Metrics:Training accuracy: 92%, Validation accuracy: Not measured
Issue:Without a validation loop, you cannot monitor if the model is overfitting or generalizing well. This can lead to poor model selection and unexpected results on new data.
Your Task
Implement a validation loop in PyTorch that evaluates the model on a validation dataset after each training epoch and reports validation loss and accuracy.
Use PyTorch framework only.
Do not change the model architecture or training hyperparameters.
Keep the training loop intact; only add the validation loop.
Hint 1
Hint 2
Hint 3
Hint 4
Solution
PyTorch
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader, TensorDataset

# Sample dataset
X_train = torch.randn(1000, 20)
y_train = (torch.sum(X_train, dim=1) > 0).long()
X_val = torch.randn(200, 20)
y_val = (torch.sum(X_val, dim=1) > 0).long()

train_dataset = TensorDataset(X_train, y_train)
val_dataset = TensorDataset(X_val, y_val)

train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)
val_loader = DataLoader(val_dataset, batch_size=32)

# Simple model
class SimpleNet(nn.Module):
    def __init__(self):
        super().__init__()
        self.fc = nn.Linear(20, 2)
    def forward(self, x):
        return self.fc(x)

model = SimpleNet()
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.01)

epochs = 5

for epoch in range(1, epochs + 1):
    model.train()
    running_loss = 0.0
    correct = 0
    total = 0
    for inputs, labels in train_loader:
        optimizer.zero_grad()
        outputs = model(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

        running_loss += loss.item() * inputs.size(0)
        _, predicted = torch.max(outputs, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum().item()

    train_loss = running_loss / total
    train_acc = correct / total * 100

    # Validation loop
    model.eval()
    val_loss = 0.0
    val_correct = 0
    val_total = 0
    with torch.no_grad():
        for inputs, labels in val_loader:
            outputs = model(inputs)
            loss = criterion(outputs, labels)
            val_loss += loss.item() * inputs.size(0)
            _, predicted = torch.max(outputs, 1)
            val_total += labels.size(0)
            val_correct += (predicted == labels).sum().item()

    val_loss /= val_total
    val_acc = val_correct / val_total * 100

    print(f"Epoch {epoch}: Train Loss={train_loss:.4f}, Train Acc={train_acc:.2f}%, Val Loss={val_loss:.4f}, Val Acc={val_acc:.2f}%")
    model.train()
Added a validation DataLoader for the validation dataset.
Implemented a validation loop inside the training epochs using model.eval() and torch.no_grad().
Calculated validation loss and accuracy after each epoch.
Printed validation metrics alongside training metrics.
Added model.train() after validation loop to switch back to training mode.
Results Interpretation

Before adding validation loop:
Training accuracy: 92%
Validation accuracy: Not measured

After adding validation loop:
Training accuracy: ~92%
Validation accuracy: ~90%

Adding a validation loop helps monitor the model's performance on unseen data during training. This is crucial to detect overfitting and to choose the best model.
Bonus Experiment
Try adding early stopping based on validation loss to stop training when validation loss stops improving.
💡 Hint
Keep track of the best validation loss and stop training if it does not improve for a set number of epochs.

Practice

(1/5)
1. What is the main purpose of a validation loop in PyTorch?
easy
A. To update the model weights during training
B. To check how well the model performs on unseen data
C. To load the training dataset
D. To save the model to disk

Solution

  1. Step 1: Understand the role of validation

    The validation loop is used to test the model on new data that it has not seen during training.
  2. Step 2: Differentiate from training

    Unlike training, validation does not update model weights but measures performance like accuracy or loss.
  3. Final Answer:

    To check how well the model performs on unseen data -> Option B
  4. Quick Check:

    Validation loop = test model on new data [OK]
Hint: Validation loop tests model without changing weights [OK]
Common Mistakes:
  • Confusing validation with training
  • Thinking validation updates model weights
  • Mixing validation with data loading
2. Which PyTorch code snippet correctly sets the model for validation?
easy
A. model.eval()
B. model.train()
C. model.validate()
D. model.test()

Solution

  1. Step 1: Recall PyTorch model modes

    In PyTorch, model.eval() sets the model to evaluation mode, disabling dropout and batch norm updates.
  2. Step 2: Identify correct method for validation

    Validation requires evaluation mode, so model.eval() is correct; others do not exist or are for training.
  3. Final Answer:

    model.eval() -> Option A
  4. Quick Check:

    Use model.eval() for validation [OK]
Hint: Use model.eval() to disable training behaviors [OK]
Common Mistakes:
  • Using model.train() during validation
  • Assuming model.validate() exists
  • Confusing test() with eval()
3. What will be the output of the following validation loop snippet?
model.eval()
correct = 0
with torch.no_grad():
    for inputs, labels in val_loader:
        outputs = model(inputs)
        predicted = outputs.argmax(dim=1)
        correct += (predicted == labels).sum().item()
accuracy = correct / len(val_loader.dataset)
print(f"Accuracy: {accuracy:.2f}")
medium
A. Prints loss value instead of accuracy
B. Raises an error because of missing optimizer
C. Prints the accuracy of the model on validation data
D. Prints training accuracy instead of validation accuracy

Solution

  1. Step 1: Analyze the code logic

    The code sets model to eval mode, disables gradient calculation, and counts correct predictions over validation data.
  2. Step 2: Understand the output calculation

    Accuracy is computed as correct predictions divided by total validation samples, then printed.
  3. Final Answer:

    Prints the accuracy of the model on validation data -> Option C
  4. Quick Check:

    Validation loop code prints accuracy [OK]
Hint: Check if code counts correct predictions for accuracy [OK]
Common Mistakes:
  • Expecting loss instead of accuracy
  • Thinking optimizer is needed in validation
  • Confusing training and validation accuracy
4. Identify the error in this validation loop code:
model.eval()
for inputs, labels in val_loader:
    outputs = model(inputs)
    loss = criterion(outputs, labels)
    loss.backward()
    total_loss += loss.item()
medium
A. Not zeroing gradients before backward
B. Not using model.train() before loop
C. Missing optimizer.step() after loss.backward()
D. Calling loss.backward() during validation

Solution

  1. Step 1: Understand validation loop purpose

    Validation should not update model weights or compute gradients, so backward() is not needed.
  2. Step 2: Identify the error

    Calling loss.backward() computes gradients, which is incorrect in validation; it wastes resources and may cause errors.
  3. Final Answer:

    Calling loss.backward() during validation -> Option D
  4. Quick Check:

    No backward() in validation loop [OK]
Hint: No backward() in validation, only in training [OK]
Common Mistakes:
  • Running backward() in validation
  • Confusing train and eval modes
  • Forgetting torch.no_grad() in validation
5. You want to add accuracy tracking in your validation loop. Which code snippet correctly computes and updates accuracy inside the loop?
model.eval()
total_correct = 0
total_samples = 0
with torch.no_grad():
    for inputs, labels in val_loader:
        outputs = model(inputs)
        predicted = outputs.argmax(dim=1)
        # What goes here?
accuracy = total_correct / total_samples
print(f"Validation Accuracy: {accuracy:.2f}")
hard
A. total_correct += (predicted == labels).sum().item() total_samples += labels.size(0)
B. total_correct += predicted.sum().item() total_samples += labels.size(0)
C. total_correct += (predicted != labels).sum().item() total_samples += labels.size(0)
D. total_correct += (predicted == labels).sum() total_samples += len(val_loader)

Solution

  1. Step 1: Calculate correct predictions

    Use (predicted == labels).sum().item() to count correct predictions as a Python number.
  2. Step 2: Update total samples count

    Use labels.size(0) to add the batch size to total samples for accurate accuracy calculation.
  3. Final Answer:

    total_correct += (predicted == labels).sum().item() total_samples += labels.size(0) -> Option A
  4. Quick Check:

    Sum correct matches and batch size for accuracy [OK]
Hint: Sum correct predictions and batch size for accuracy [OK]
Common Mistakes:
  • Summing predicted values instead of correct matches
  • Using != instead of == for correct count
  • Adding batch count incorrectly as len(val_loader)
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard