Как найти матрицу путаницы и построить ее для классификатора изображений в PyTorch

#python #image-processing #computer-vision #pytorch #transfer-learning

#python #обработка изображений #компьютерное зрение #pytorch #передача-обучение

Вопрос:

По сути, это модель VGG-16, я выполнил обучение передаче и точно настроил модель, я обучил эту модель 2 недели назад и нашел точность тестирования и обучения, но теперь мне нужна точность модели с точки зрения класса, я пытаюсь выяснить матрицу путаницы и хочу построить матрицу тоже. Обучающий код:

 # Training the model again from the last CNN Block to The End of the Network
dataset = 'C:\Users\Sara Latif Khan\OneDrive\Desktop\FYP_\Scene15\15-Scene'
model = model.to(device)
optimizer = Adam(filter(lambda p: p.requires_grad, model.parameters()))

#Training Fixed Feature Extractor for 15 epochs
num_epochs = 5
batch_loss = 0
cum_epoch_loss = 0 #cumulative loss for each batch

for e in range(num_epochs):
    cum_epoch_loss = 0
  
    for batch, (images, labels) in enumerate(trainloader,1):
        images = images.to(device)
        labels = labels.to(device)

        optimizer.zero_grad()
        logps = model(images)
        loss = criterion(logps, labels)
        loss.backward()
        optimizer.step()
    
        batch_loss  = loss.item()
        print(f'Epoch({e}/{num_epochs} : Batch number({batch}/{len(trainloader)}) : Batch loss : {loss.item()}')
        torch.save(model, dataset '_model_' str(e) '.pt')
    
print(f'Training loss : {batch_loss/len(trainloader)}')
  

Это код, который я использую для проверки точности моей модели на основе данных из тестового загрузчика.

 model. to('cpu')

model.eval()
with torch.no_grad():
    num_correct = 0
    total = 0
    
    #set_trace ()
    for batch, (images,labels) in enumerate(testloader,1):
        
        logps = model(images)
        output = torch.exp(logps)
        
        pred = torch.argmax(output,1)
        total  = labels.size(0)
        
        num_correct  = (pred==labels).sum().item()
        print(f'Batch ({batch} / {len(testloader)})')
        
        # to check the accuracy of model on 5 batches
        # if batch == 5:
            # break
            
    print(f'Accuracy of the model on {total} test images: {num_correct * 100 / total }% ')  
  

Далее мне нужно найти точность модели с точки зрения класса. Я работаю над ноутбуком Jupyter. Должен ли я перезагрузить сохраненную модель и найти cm или какой будет подходящий способ сделать это.

Ответ №1:

Вы должны сохранить все прогнозы и целевые показатели тестового набора.

 predictions, targets = [], []
for images, labels in testloader:
    logps = model(images)
    output = torch.exp(logps)
    pred = torch.argmax(output, 1)

    # convert to numpy arrays
    pred = pred.detach().cpu().numpy()
    labels = labels.detach().cpu().numpy()
    
    for i in range(len(pred)):
        predictions.append(pred[i])
        targets.append(labels[i])
  

Теперь у вас есть все прогнозы и фактические цели тестового набора, сохраненные.
Следующий шаг — создать матрицу путаницы. Я думаю, что могу просто предоставить вам свою функцию, которую я всегда использую:

 def create_confusion_matrix(y_true, y_pred, classes):
    """ creates and plots a confusion matrix given two list (targets and predictions)
    :param list y_true: list of all targets (in this case integers bc. they are indices)
    :param list y_pred: list of all predictions (in this case one-hot encoded)
    :param dict classes: a dictionary of the countries with they index representation
    """

    amount_classes = len(classes)

    confusion_matrix = np.zeros((amount_classes, amount_classes))
    for idx in range(len(y_true)):
        target = y_true[idx][0]

        output = y_pred[idx]
        output = list(output).index(max(output))

        confusion_matrix[target][output]  = 1

    fig, ax = plt.subplots(1)

    ax.matshow(confusion_matrix)
    ax.set_xticks(np.arange(len(list(classes.keys()))))
    ax.set_yticks(np.arange(len(list(classes.keys()))))

    ax.set_xticklabels(list(classes.keys()))
    ax.set_yticklabels(list(classes.keys()))

    plt.setp(ax.get_xticklabels(), rotation=45, ha="left", rotation_mode="anchor")
    plt.setp(ax.get_yticklabels(), rotation=45, ha="right", rotation_mode="anchor")

    plt.show()
  

Итак, y_true — это все цели, y_pred — все предсказания и classes это словарь, который сопоставляет метки с фактическими именами классов, например:

 classes = {"dog": [1, 0], "cat": [0, 1]}
  

Затем просто вызовите:

 create_confusion_matrix(targets, predictions, classes)
  

Возможно, вам придется немного адаптировать ее к вашему коду, но я надеюсь, что это сработает для вас. 🙂

Комментарии:

1. Спасибо за ваш ответ, я собираюсь реализовать это, я надеюсь, что это сработает для меня.

2. У меня это сработало. Еще раз спасибо @Thoedor Peifer