Hi, I want to plot a confusion matrix for validation set. The code for my training is given below. Which is taken from pytorch example. During training phase it also computes and show the validation loss and accuracy as well as training loss and accuracy. But I also want to see the confusion matrix for validation set. How can I do it ?
def train_model(model, criterion, optimizer, scheduler, num_epochs):
since = time.time()
best_model_wts = copy.deepcopy(model.state_dict())
best_acc = 0.0
for epoch in range(num_epochs):
print('Epoch {}/{}'.format(epoch +1, num_epochs))
print('-' * 10)
# Each epoch has a training and validation phase
for phase in ['train', 'valid']:
if phase == 'train':
scheduler.step()
model.train() # Set model to training mode
else:
model.eval() # Set model to evaluate mode
running_loss = 0.0
running_corrects = 0
# Iterate over data.
for inputs, labels in dataloaders[phase]:
inputs = inputs.to(device)
labels = labels.to(device)
# zero the parameter gradients
optimizer.zero_grad()
# forward
# track history if only in train
with torch.set_grad_enabled(phase == 'train'):
outputs = model(inputs)
_, preds = torch.max(outputs, 1)
loss = criterion(outputs, labels)
# backward + optimize only if in training phase
if phase == 'train':
loss.backward()
optimizer.step()
# statistics
running_loss += loss.item() * inputs.size(0)
running_corrects += torch.sum(preds == labels.data)
#For graph generation
if phase == "train":
train_loss.append(running_loss/dataset_sizes[phase])
train_acc.append(running_corrects.double() / dataset_sizes[phase])
epoch_counter_train.append(epoch)
if phase == "valid":
val_loss.append(running_loss/ dataset_sizes[phase])
val_acc.append(running_corrects.double() / dataset_sizes[phase])
epoch_counter_val.append(epoch)
epoch_loss = running_loss / dataset_sizes[phase]
epoch_acc = running_corrects.double() / dataset_sizes[phase]
#for printing
if phase == "train":
epoch_loss = running_loss / dataset_sizes[phase]
epoch_acc = running_corrects.double() / dataset_sizes[phase]
if phase == "valid":
epoch_loss = running_loss / dataset_sizes[phase]
epoch_acc = running_corrects.double() / dataset_sizes[phase]
print('{} Loss: {:.4f} Acc: {:.4f}'.format(
phase, epoch_loss, epoch_acc))
# deep copy the best model
if phase == 'valid' and epoch_acc > best_acc:
best_acc = epoch_acc
best_model_wts = copy.deepcopy(model.state_dict())
print()
time_elapsed = time.time() - since
print('Training complete in {:.0f}m {:.0f}s'.format(
time_elapsed // 60, time_elapsed % 60))
print('Best val Acc: {:4f}'.format(best_acc))
# load best model weights
model.load_state_dict(best_model_wts)
#save the best model
torch.save(model.load_state_dict(best_model_wts), savePath+'bestModel.pth')
return model
Now , I know how to plot confusion matrix for my test set too, like
with torch.no_grad():
for i, (inputs, labels) in enumerate(dataloaders['test']):
inputs = inputs.to(device)
labels = labels.to(device)
outputs = model_ft(inputs)
_, predicted = torch.max(outputs, 1)
confusion_matrix.add(predicted, labels)
But I am confused how to add the code snippet:
confusion_matrix.add(predicted, labels)
add where to incorporate the line in my training function. If I add it in the training function after the line
if phase == "valid":
confusion_matrix.add(preds, labels)
It seems, the result is not correct if I plot it.
So, Can you please suggest how to get the confusion matrix on validation set? Should I have to do it in my training function where I am both training and validating or just like the test set, outside training function, looping through validation set again ?