Unlocking Performance Insights: Calculating Accuracy per Epoch in PyTorch
Understanding Accuracy Calculation
- Epoch: One complete pass through the entire training dataset.
- Accuracy: The percentage of predictions your model makes that are correct compared to the actual labels.
Steps Involved
-
Track Correct Predictions: Within your training loop (typically iterating over batches in an epoch), you'll need to keep track of the number of correct predictions made by your model. Here's how:
- Get the model's predictions: Use the model's
forward
method to pass a batch of input data (x
) and obtain the predicted labels (y_pred
). - Compare predictions with actual labels (
y
): Use functions liketorch.argmax
to find the index of the maximum value in the prediction tensor. This represents the predicted class for each sample. Compare this with the corresponding labels in they
tensor. - Count correct predictions: Increment a counter (
num_correct
) by 1 for each batch element where the prediction matches the actual label.
- Get the model's predictions: Use the model's
-
Calculate Accuracy per Epoch: After iterating through all batches in an epoch:
- Divide the total number of correct predictions (
num_correct
) by the total number of samples in the epoch (total_samples
). - Multiply by 100 to express accuracy as a percentage.
- Divide the total number of correct predictions (
Code Example (assuming classification task):
import torch
def train_one_epoch(model, optimizer, criterion, train_loader):
model.train() # Set model to train mode
num_correct = 0
total_samples = 0
for data, target in train_loader:
# Forward pass and get predictions
outputs = model(data)
_, predicted = torch.max(outputs.data, 1)
# Count correct predictions
num_correct += (predicted == target).sum().item()
total_samples += target.size(0)
# Backpropagation and optimization
loss = criterion(outputs, target)
optimizer.zero_grad()
loss.backward()
optimizer.step()
# Calculate accuracy for the epoch
accuracy = (num_correct / total_samples) * 100
print(f'Training Accuracy: {accuracy:.2f}%')
return accuracy
Key Points
- This code snippet calculates training accuracy. You can adapt it for validation accuracy by using a separate validation loader within a loop iterating over epochs.
- Consider using libraries like
torchmetrics
for more robust and reusable accuracy calculation. - Track both training and validation accuracy to monitor model performance and avoid overfitting.
- Print or store the calculated accuracy values for later analysis or visualization (e.g., accuracy vs. epoch plots).
By following these steps and incorporating the code example, you'll be able to effectively calculate and track the accuracy of your PyTorch neural network every epoch during training.
Example 1: Basic Calculation (Classification Task)
import torch
def train_one_epoch(model, optimizer, criterion, train_loader):
model.train() # Set model to train mode
num_correct = 0
total_samples = 0
for data, target in train_loader:
# Move data to device (CPU or GPU) if necessary
data, target = data.to(device), target.to(device)
# Forward pass and get predictions
outputs = model(data)
_, predicted = torch.max(outputs.data, 1) # Assuming classification
# Count correct predictions
num_correct += (predicted == target).sum().item()
total_samples += target.size(0)
# Backpropagation and optimization
loss = criterion(outputs, target)
optimizer.zero_grad()
loss.backward()
optimizer.step()
# Calculate accuracy for the epoch
accuracy = (num_correct / total_samples) * 100
print(f'Training Accuracy: {accuracy:.2f}%')
return accuracy
Explanation:
- Function Definition: The
train_one_epoch
function takes the model, optimizer, loss criterion, and training data loader as input. - Set Train Mode:
model.train()
sets the model to training mode. - Initialize Counters: Variables
num_correct
andtotal_samples
are initialized to track correct predictions and total samples, respectively. - Iterate over Batches: The loop iterates through each data batch (
data
) and its corresponding labels (target
) in the training loader. - Move Data to Device: If using a GPU, the data and labels are transferred to the device using
data.to(device)
andtarget.to(device)
. - Forward Pass and Predictions: The model's
forward
method is called on the input data to get predictions (outputs
).torch.max
is used to find the most likely class for each sample (predicted
). - Count Correct Predictions: The code checks if the predicted class (
predicted
) matches the actual label (target
) for each sample in the batch. Thesum().item()
converts the tensor containing correct predictions to a scalar and then sums them up across the batch. This is added tonum_correct
. - Track Total Samples: The total number of samples is accumulated in
total_samples
. - Backpropagation and Optimization: The standard training loop continues with calculating the loss (
loss
), zeroing gradients (optimizer.zero_grad()
), performing backpropagation (loss.backward()
), and updating model parameters (optimizer.step()
). - Calculate Accuracy: After iterating through all batches, the accuracy is calculated by dividing
num_correct
bytotal_samples
and multiplying by 100 for a percentage. - Print Accuracy: The calculated training accuracy is printed.
- Return Accuracy: The function returns the calculated accuracy.
Example 2: Using torchmetrics (Classification or Regression)
import torch
from torchmetrics import Accuracy
def train_one_epoch(model, optimizer, criterion, train_loader):
model.train() # Set model to train mode
metric = Accuracy() # Create Accuracy metric object
for data, target in train_loader:
# Move data to device (CPU or GPU) if necessary
data, target = data.to(device), target.to(device)
# Forward pass and get predictions
outputs = model(data)
# Update accuracy metric
metric.update(outputs, target)
# Backpropagation and optimization
loss = criterion(outputs, target)
optimizer.zero_grad()
loss.backward()
optimizer.step()
# Calculate and print accuracy
accuracy = metric.compute() * 100
print(f'Training Accuracy: {accuracy:.2f}%')
return accuracy
- Import Accuracy: This code imports the
Accuracy
metric fromtorchmetrics
. - Create Metric Object: An
Accuracy
object (metric
) is created to track accuracy during training. - Update Metric: Inside the training loop, the
metric.update(outputs, target)
call updates the accuracy metric with the model's predictions (outputs
) and the ground-truth labels (target
). - **
Using torch.tensor.eq (Classification):
This approach leverages the torch.tensor.eq
function for element-wise comparison between tensors:
import torch
def train_one_epoch(model, optimizer, criterion, train_loader):
model.train() # Set model to train mode
num_correct = 0
total_samples = 0
for data, target in train_loader:
# Move data to device (CPU or GPU) if necessary
data, target = data.to(device), target.to(device)
# Forward pass and get predictions
outputs = model(data)
_, predicted = torch.max(outputs.data, 1)
# Count correct predictions (using element-wise comparison)
num_correct += torch.tensor.eq(predicted, target).sum().item()
total_samples += target.size(0)
# Backpropagation and optimization
loss = criterion(outputs, target)
optimizer.zero_grad()
loss.backward()
optimizer.step()
# Calculate accuracy for the epoch
accuracy = (num_correct / total_samples) * 100
print(f'Training Accuracy: {accuracy:.2f}%')
return accuracy
- The
torch.tensor.eq(predicted, target)
comparison creates a boolean tensor indicating correct predictions (True) and incorrect predictions (False). - The
sum()
function calculates the total number of True values, which represents the number of correct predictions in the batch.
This method employs torch.mean
to calculate the average value of a tensor, useful for both classification and regression tasks:
import torch
def train_one_epoch(model, optimizer, criterion, train_loader):
model.train() # Set model to train mode
for data, target in train_loader:
# Move data to device (CPU or GPU) if necessary
data, target = data.to(device), target.to(device)
# Forward pass and get predictions
outputs = model(data)
# Calculate accuracy (classification)
if isinstance(criterion, torch.nn.CrossEntropyLoss): # Assuming classification
_, predicted = torch.max(outputs.data, 1)
accuracy = (predicted == target).float().mean().item() * 100
# Calculate accuracy (regression) - Replace with your specific loss function
else:
accuracy = (criterion(outputs, target) == 0).float().mean().item() * 100
# Backpropagation and optimization
loss = criterion(outputs, target)
optimizer.zero_grad()
loss.backward()
optimizer.step()
print(f'Training Accuracy: {accuracy:.2f}%')
return accuracy
- This approach leverages the loss function to determine accuracy.
- For classification with
CrossEntropyLoss
, accuracy is calculated based on correct predictions (predicted == target
). - For regression (replace with your specific loss function), accuracy is calculated based on whether the loss is zero (indicating a perfect fit).
- For classification with
float().mean().item()
converts the accuracy tensor to a float, calculates the mean (average), and extracts the scalar value for printing.
Choosing the Right Method:
- The basic calculation with
torch.argmax
is suitable for simple classification tasks. torchmetrics.Accuracy
offers a more robust and reusable approach.torch.tensor.eq
can be a concise alternative for classification.torch.mean
provides flexibility for both classification and regression, but requires adapting the accuracy calculation based on the loss function.
Remember to consider the specific task (classification vs. regression) and desired level of flexibility when selecting the most appropriate method for your PyTorch project.
python neural-network pytorch