Convert CUDA tensor to NumPy

10,044

Solution 1

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()))

Solution 2

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.

Share:
10,044
Ahmad
Author by

Ahmad

Age: 26 Trying to code for a better life! 01010000 01111001 01110100 01101000 01101111 01101110 00100000 01000100 01100101 01110110 01100101 01101100 01101111 01110000 01100101 01110010

Updated on July 16, 2022

Comments

  • Ahmad
    Ahmad almost 2 years

    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.
    
    • one
      one over 4 years
      you error log is not complete. you should copy your error log as text, not a figure
    • Ahmad
      Ahmad over 4 years
      fixed it and removed the figure
    • one
      one over 4 years
      are you sure you post all of the error log?
    • Ahmad
      Ahmad over 4 years
      yes for sure, didn't miss anything
    • one
      one over 4 years
      there may be some information collapsed? what's 1 frames ?
    • Ahmad
      Ahmad over 4 years
      you were right there was missing lines and added now
    • tevemadar
      tevemadar over 4 years
      Blind guess: what happens if you write idxs = np.array(idxs.cpu()) (.cpu() being the new part)
    • Ahmad
      Ahmad over 4 years
      still the same:: TypeError: can't convert CUDA tensor to numpy. Use Tensor.cpu() to copy the tensor to host memory first.
  • Ahmad
    Ahmad over 4 years
    still the same error: TypeError: can't convert CUDA tensor to numpy. Use Tensor.cpu() to copy the tensor to host memory first.
  • one
    one over 4 years
    you first change to idxs = idxs.cpu().numpy() and show the complete error information. there may be somewhere else existing the same error
  • one
    one over 4 years
    may be you can't change at your post. I can't understand the comment as the disorder format.