Can't convert cuda:0 device type tensor to numpy. Use Tensor.cpu() to copy the tensor to host memory first

I am trying to run the inference code to create confusion matrix in the system can anyone tell me what i should change on the code to make this run

import torch
import torch.nn as nn
from torchvision.transforms import transforms
import numpy as np
import torchvision
from torch.autograd import Variable
from torchvision import models
import torch.functional as F
from io import open
import os
from torchvision.transforms import transforms
from PIL import Image
import pathlib
import glob
from torch.utils.data import DataLoader
import time


mean = [0.5, 0.5, 0.5]
std = [0.5, 0.5, 0.5]

transformer = transforms.Compose([
        transforms.Resize((224,224)),
        transforms.ToTensor(),
        transforms.Normalize(torch.Tensor(mean), torch.Tensor(std))
])

#Allocating the device to the GPU or CPU
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
#Checking for the device in use
print("Using Device",device)

pred_path='D:/Anaconda Environment/Dataset/Infence Images'


test_path='D:/Anaconda Environment/Dataset/final/val'

test_loader=DataLoader(
    torchvision.datasets.ImageFolder(test_path,transform=transformer),
    batch_size=8, num_workers=2, shuffle=True
)

classes = [
    'Bacterial_spot',
    'Black_mold',
    'Early_blight',
    'Healthy',
    'Late_blight',
    'Mosaic_virus',
    'Septoria_spot',
]


model = torch.load('Inference model/resnext50_32x4d(8).pth')
model.eval()
model.cuda()

def prediction(img_path,transformer):
    image=Image.open(img_path)
    
    image_tensor=transformer(image).float()
    
    
    image_tensor=image_tensor.unsqueeze_(0)

    if torch.cuda.is_available():
        image_tensor = image_tensor.cuda()
        
    input=Variable(image_tensor)
    
    output=model(input)
    
    index = output.cpu().data.numpy().argmax()
    
    pred=classes[index]

    return pred


images_path=glob.glob(pred_path+'/*.jpg')

pred_dict={}

since =time.time()

for i in images_path:
    pred_dict[i[i.rfind('/')+1:]]=prediction(i,transformer)
    
time_elapsed = time.time() - since
print('Inference complete in {:.0f}ms'.format(
        time_elapsed * 1000))


pred_dict


y_true = []
y_predict = []
with torch.no_grad():
    for data in test_loader:
        images, labels = data
        if torch.cuda.is_available():
            image = images.cuda()
        outputs = model(image)
        _, predicted = torch.max(outputs.data, 1)
        y_true += list(labels)
        y_predict += list(predicted)

from sklearn.metrics import confusion_matrix
cm = confusion_matrix(y_true, y_predict)
print(cm)

TypeError: can’t convert cuda:0 device type tensor to numpy. Use Tensor.cpu() to copy the tensor to host memory first.
can anyone help me create Confusion matrix

1 Like

I would try something like confusion_matrix(y_true.cpu(), y_predict.cpu()) first.

if you run this
I Got this error

AttributeError: ‘list’ object has no attribute ‘cpu’

I loaded the model without cuda Like this

y_true = []
y_predict = []
with torch.no_grad():
    for data in test_loader:
        images, labels = data
        outputs = model(image)
        _, predicted = torch.max(outputs.data, 1)
        y_true += list(labels)
        y_predict += list(predicted)

then the error was

ValueError: Found input variables with inconsistent numbers of samples: [279, 245]

It’s difficult to debug without visibility into the confusion_matrix function, which appears to use numpy. Could you post the implementation of that function and some sample data?

The model loading shouldn’t affect the samples error, which sounds like a mismatch between the number of inputs X and outputs Y somewhere.