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.
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()))
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.
Numpy does not use GPU; Numpy operations have to be done in CPU. Torch.Tensor can be done in GPU. So wherever numpy operations are there you need to move it to CPU
Ex device
below is CPU; Model is run in GPU
df["x"] = df["x"].apply(lambda x: torch.tensor(x).unsqueeze(0))
df["y"] = df["x"].apply(lambda x: model(x.to(device))[0].detach())
and below when you need to use np.pad, you move it back to cpu
df["y"] = df["y"].apply(lambda x: np.pad(x.to("cpu"), [(0, 0), (0, max_length - x.shape[1])], 'constant') )
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.