2

First of all, I tried those solutions: 1, 2, 3, and 4, but did not work for me.

After training and testing the neural network, I am trying to show some examples to verify my work. I named the method predict which I pass the image to it to predict for which class it belongs:

def predict(model, image_path, topk=5):
''' Predict the class (or classes) of an image using a trained deep learning model.
'''

output = process_image(image_path)
output.unsqueeze_(0)
output = output.cuda().float()

model.eval()

with torch.no_grad():
    score = model(output)
    prob, idxs = torch.topk(score, topk)

    # Convert indices to classes
    idxs = np.array(idxs)
    idx_to_class = {val:key for key, val in model.class_to_idx.items()}
    classes = [idx_to_class[idx] for idx in idxs[0]]

    # Map the class name with collected topk classes
    names = []
    for cls in classes:
        names.append(cat_to_name[str(cls)])

    return prob, names

Then there is the final step which displays the final result based on the training of the neural network and done like this:

# TODO: Display an image along with the top 5 classes
x_pos, y_pos = predict(model, img_pil, topk=5)

ax_img = imshow(output)
ax_img.set_title(y_pos[0])

plt.figure(figsize=(4,4))
plt.barh(range(len(y_pos)), np.exp(x_pos[0]))
plt.yticks(range(len(y_pos)), y_pos)

plt.show()

The error is:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-45-e3f9951e9804> in <module>()
----> 1 x_pos, y_pos = predict(model, img_pil, topk=5)
      2
      3 ax_img = imshow(output)
      4 ax_img.set_title(y_pos[0])
      5

1 frames
<ipython-input-44-d77500f31561> in predict(model, image_path, topk)
     14
     15         # Convert indices to classes
---> 16         idxs = np.array(idxs)
     17         idx_to_class = {val:key for key, val in model.class_to_idx.items()}
     18         classes = [idx_to_class[idx] for idx in idxs[0]]

/usr/local/lib/python3.6/dist-packages/torch/tensor.py in __array__(self, dtype)
    456     def __array__(self, dtype=None):
    457         if dtype is None:
--> 458             return self.numpy()
    459         else:
    460             return self.numpy().astype(dtype, copy=False)

TypeError: can't convert CUDA tensor to numpy. Use Tensor.cpu() to copy the tensor to host memory first.

How do I solve this?

I tried to change idx to idxs = idxs.cpu().numpy() and the error is:

TypeError                                 Traceback (most recent call last)
<ipython-input-62-e3f9951e9804> in <module>()
      5
      6 plt.figure(figsize=(4,4))
----> 7 plt.barh(range(len(y_pos)), np.exp(x_pos[0]))
      8 plt.yticks(range(len(y_pos)), y_pos)
      9

/usr/local/lib/python3.6/dist-packages/torch/tensor.py in __array__(self, dtype)
    456     def __array__(self, dtype=None):
    457         if dtype is None:
--> 458             return self.numpy()
    459         else:
    460             return self.numpy().astype(dtype, copy=False)

TypeError: can't convert CUDA tensor to numpy. Use Tensor.cpu() to copy the tensor to host memory first.
Ahmad
  • 1,278
  • 5
  • 22
  • 39

2 Answers2

5

Try to change

idxs = np.array(idxs)

to

idxs = idxs.cpu().numpy()

And change

plt.barh(range(len(y_pos)), np.exp(x_pos[0]))

to

plt.barh(range(len(y_pos)), np.exp(x_pos[0].cpu().numpy()))
Peter Mortensen
  • 30,030
  • 21
  • 100
  • 124
one
  • 1,811
  • 12
  • 31
  • still the same error: TypeError: can't convert CUDA tensor to numpy. Use Tensor.cpu() to copy the tensor to host memory first. – Ahmad Sep 07 '19 at 10:03
  • 1
    you first change to `idxs = idxs.cpu().numpy()` and show the complete error information. there may be somewhere else existing the same error – one Sep 07 '19 at 10:03
  • may be you can't change at your post. I can't understand the comment as the disorder format. – one Sep 07 '19 at 10:11
1

So if you're here in 2021 and still have this "TypeError: can't convert CUDA tensor to numpy. Use Tensor.cpu() to copy the tensor to host memory first."

Try x.to("cpu").numpy() from this site https://jbencook.com/pytorch-numpy-conversion/

So something like idxs = idxs.to("cpu").numpy().squeeze() would work.

ArthurEzenwanne
  • 137
  • 2
  • 9