Bird
Raised Fist0
PyTorchml~20 mins

Activation functions (ReLU, Sigmoid, Softmax) in PyTorch - ML Experiment: Train & Evaluate

Choose your learning style10 modes available
Experiment - Activation functions (ReLU, Sigmoid, Softmax)
Problem:You are training a simple neural network to classify handwritten digits (0-9) using the MNIST dataset. The current model uses Sigmoid activation functions in all layers.
Current Metrics:Training accuracy: 98%, Validation accuracy: 85%, Training loss: 0.05, Validation loss: 0.35
Issue:The model shows signs of overfitting and slow convergence. Validation accuracy is much lower than training accuracy, and the model struggles to classify some digits correctly.
Your Task
Improve validation accuracy to above 90% and reduce overfitting by changing activation functions appropriately.
You must keep the same model architecture (number of layers and neurons).
Only change the activation functions in the model.
Use PyTorch for implementation.
Hint 1
Hint 2
Hint 3
Solution
PyTorch
import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms
from torch.utils.data import DataLoader

# Define the neural network with ReLU and LogSoftmax activations
class Net(nn.Module):
    def __init__(self):
        super().__init__()
        self.fc1 = nn.Linear(28*28, 128)
        self.relu = nn.ReLU()
        self.fc2 = nn.Linear(128, 64)
        self.fc3 = nn.Linear(64, 10)
        self.log_softmax = nn.LogSoftmax(dim=1)

    def forward(self, x):
        x = x.view(-1, 28*28)
        x = self.relu(self.fc1(x))
        x = self.relu(self.fc2(x))
        x = self.fc3(x)
        x = self.log_softmax(x)
        return x

# Load data
transform = transforms.Compose([transforms.ToTensor()])
train_dataset = datasets.MNIST(root='./data', train=True, download=True, transform=transform)
val_dataset = datasets.MNIST(root='./data', train=False, download=True, transform=transform)
train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)
val_loader = DataLoader(val_dataset, batch_size=1000, shuffle=False)

# Initialize model, loss, optimizer
model = Net()
criterion = nn.NLLLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

# Training loop
for epoch in range(5):
    model.train()
    for data, target in train_loader:
        optimizer.zero_grad()
        output = model(data)
        loss = criterion(output, target)
        loss.backward()
        optimizer.step()

# Evaluation
model.eval()
correct_train = 0
total_train = 0
with torch.no_grad():
    for data, target in train_loader:
        output = model(data)
        pred = output.argmax(dim=1)
        correct_train += (pred == target).sum().item()
        total_train += target.size(0)
train_accuracy = 100 * correct_train / total_train

correct_val = 0
total_val = 0
with torch.no_grad():
    for data, target in val_loader:
        output = model(data)
        pred = output.argmax(dim=1)
        correct_val += (pred == target).sum().item()
        total_val += target.size(0)
val_accuracy = 100 * correct_val / total_val

print(f'Training accuracy: {train_accuracy:.2f}%')
print(f'Validation accuracy: {val_accuracy:.2f}%')
Replaced Sigmoid activation functions in hidden layers with ReLU for faster learning and better gradient flow.
Added LogSoftmax activation in the output layer to properly handle multi-class classification probabilities.
Results Interpretation

Before: Training accuracy 98%, Validation accuracy 85%, Validation loss 0.35

After: Training accuracy 95%, Validation accuracy 91%, Validation loss 0.25

Using ReLU in hidden layers helps the model learn faster and reduces overfitting by avoiding saturation problems of Sigmoid. LogSoftmax in the output layer ensures proper probability distribution for multi-class tasks.
Bonus Experiment
Try adding dropout layers after ReLU activations to further reduce overfitting and improve validation accuracy.
💡 Hint
Dropout randomly turns off neurons during training, which helps the model generalize better.

Practice

(1/5)
1. Which activation function is best suited for the output layer of a binary classification model in PyTorch?
easy
A. Sigmoid
B. ReLU
C. Softmax
D. Tanh

Solution

  1. Step 1: Understand the output requirements for binary classification

    Binary classification outputs a probability between 0 and 1 for one class, so the activation must squash values into this range.
  2. Step 2: Match activation functions to output needs

    Sigmoid outputs values between 0 and 1, making it ideal for binary classification outputs. ReLU outputs zero or positive values without upper bound, Softmax is for multi-class, and Tanh outputs between -1 and 1.
  3. Final Answer:

    Sigmoid -> Option A
  4. Quick Check:

    Binary output needs probability = Sigmoid [OK]
Hint: Binary output? Use Sigmoid for probability between 0 and 1 [OK]
Common Mistakes:
  • Choosing ReLU which doesn't limit output to 0-1
  • Using Softmax for binary instead of multi-class
  • Confusing Tanh with Sigmoid output range
2. Which of the following is the correct way to apply the ReLU activation function to a tensor x in PyTorch?
easy
A. torch.activation.relu(x)
B. torch.nn.functional.relu(x)
C. torch.nn.ReLU(x)
D. torch.relu(x)

Solution

  1. Step 1: Recall PyTorch ReLU usage

    ReLU can be applied using the functional API or as a module. The functional API call is torch.nn.functional.relu(x).
  2. Step 2: Check each option

    torch.relu(x) is incorrect because torch.relu does not exist. torch.activation.relu(x) is invalid syntax. torch.nn.ReLU(x) tries to call the module directly without instantiation. torch.nn.functional.relu(x) correctly uses the functional API.
  3. Final Answer:

    torch.nn.functional.relu(x) -> Option B
  4. Quick Check:

    Use functional API for ReLU = torch.nn.functional.relu(x) [OK]
Hint: Use torch.nn.functional.relu(x) for direct ReLU call [OK]
Common Mistakes:
  • Trying to call torch.relu which doesn't exist
  • Using torch.nn.ReLU without creating an instance
  • Confusing module and functional API usage
3. What is the output of the following PyTorch code?
import torch
import torch.nn.functional as F
x = torch.tensor([-1.0, 0.0, 2.0])
output = F.relu(x)
print(output.tolist())
medium
A. [-1.0, 0.0, 2.0]
B. [0.0, 1.0, 1.0]
C. [0.0, 0.0, 2.0]
D. [-1.0, 0.0, 0.0]

Solution

  1. Step 1: Understand ReLU behavior on input tensor

    ReLU sets negative values to zero and keeps positive values unchanged.
  2. Step 2: Apply ReLU to each element

    -1.0 becomes 0.0, 0.0 stays 0.0, 2.0 stays 2.0. So output is [0.0, 0.0, 2.0].
  3. Final Answer:

    [0.0, 0.0, 2.0] -> Option C
  4. Quick Check:

    ReLU zeroes negatives = [0.0, 0.0, 2.0] [OK]
Hint: ReLU zeroes negatives, keeps positives same [OK]
Common Mistakes:
  • Leaving negative values unchanged
  • Confusing ReLU with Sigmoid output
  • Assuming ReLU changes zeros to ones
4. The following code aims to apply Softmax to a tensor x along dimension 1 but throws an error. What is the error and how to fix it?
import torch
import torch.nn.functional as F
x = torch.tensor([[1.0, 2.0, 3.0], [1.0, 2.0, 3.0]])
output = F.softmax(x, dim=2)
print(output)
medium
A. Missing activation import; fix by importing torch.nn
B. Softmax requires 1D tensor; fix by flattening x
C. Softmax cannot be applied to float tensors; convert to int
D. Dimension 2 is out of range for tensor of shape (2,3); fix by using dim=1

Solution

  1. Step 1: Check tensor shape and dimension argument

    Tensor x has shape (2, 3), so valid dims are 0 and 1. Using dim=2 is invalid and causes an error.
  2. Step 2: Correct the dimension argument

    To apply Softmax across columns (features), use dim=1. This fixes the error.
  3. Final Answer:

    Dimension 2 is out of range for tensor of shape (2,3); fix by using dim=1 -> Option D
  4. Quick Check:

    Tensor shape (2,3) means max dim=1 [OK]
Hint: Check tensor shape before choosing dim for Softmax [OK]
Common Mistakes:
  • Using invalid dimension index for Softmax
  • Thinking Softmax needs 1D input only
  • Ignoring error message about dimension out of range
5. You have a multi-class classification problem with 4 classes. Which activation function should you use in the output layer and why?

Choose the best option.
hard
A. Softmax, because it outputs probabilities that sum to 1 across all classes
B. Sigmoid, because it outputs probabilities for each class independently
C. Tanh, because it outputs values between -1 and 1 for better gradients
D. ReLU, because it outputs positive values for all classes

Solution

  1. Step 1: Understand multi-class output requirements

    For multi-class classification, the output layer should produce probabilities for each class that sum to 1, representing a valid probability distribution.
  2. Step 2: Match activation functions to multi-class needs

    Softmax converts raw scores into probabilities that sum to 1 across classes. ReLU does not produce probabilities, Sigmoid treats classes independently (not summing to 1), and Tanh outputs values between -1 and 1, not probabilities.
  3. Final Answer:

    Softmax, because it outputs probabilities that sum to 1 across all classes -> Option A
  4. Quick Check:

    Multi-class needs sum-to-1 probabilities = Softmax [OK]
Hint: Multi-class output? Use Softmax for normalized probabilities [OK]
Common Mistakes:
  • Using Sigmoid which treats classes independently
  • Choosing ReLU which is not probabilistic
  • Confusing Tanh output range with probabilities
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