问题解决之 TypeError: can‘t convert CUDA tensor to numpy. Use Tensor.cpu() to copy the tensor to

问题描述

运行程序,出现报错信息 TypeError: can't convert CUDA tensor to numpy. Use Tensor.cpu() to copy the tensor to host memory first.

具体信息如下所示:

Traceback (most recent call last):
  File "tools/demo.py", line 97, in <module>
    visualize_result(gallery_img, detections, similarities)
  File "tools/demo.py", line 41, in visualize_result
    (x1, y1), x2 - x1, y2 - y1, fill=False, edgecolor="#4CAF50", linewidth=3.5
  File "/environment/miniconda3/lib/python3.7/site-packages/matplotlib/axes/_base.py", line 2358, in add_patch
    self._update_patch_limits(p)
  File "/environment/miniconda3/lib/python3.7/site-packages/matplotlib/axes/_base.py", line 2381, in _update_patch_limits
    patch_trf = patch.get_transform()
  File "/environment/miniconda3/lib/python3.7/site-packages/matplotlib/patches.py", line 278, in get_transform
    return self.get_patch_transform() + artist.Artist.get_transform(self)
  File "/environment/miniconda3/lib/python3.7/site-packages/matplotlib/patches.py", line 752, in get_patch_transform
    bbox = self.get_bbox()
  File "/environment/miniconda3/lib/python3.7/site-packages/matplotlib/patches.py", line 845, in get_bbox
    return transforms.Bbox.from_extents(x0, y0, x1, y1)
  File "/environment/miniconda3/lib/python3.7/site-packages/matplotlib/transforms.py", line 839, in from_extents
    bbox = Bbox(np.reshape(args, (2, 2)))
  File "<__array_function__ internals>", line 6, in reshape
  File "/home/featurize/work/.local/lib/python3.7/site-packages/numpy/core/fromnumeric.py", line 298, in reshape
    return _wrapfunc(a, 'reshape', newshape, order=order)
  File "/home/featurize/work/.local/lib/python3.7/site-packages/numpy/core/fromnumeric.py", line 54, in _wrapfunc
    return _wrapit(obj, method, *args, **kwds)
  File "/home/featurize/work/.local/lib/python3.7/site-packages/numpy/core/fromnumeric.py", line 43, in _wrapit
    result = getattr(asarray(obj), method)(*args, **kwds)
  File "/home/featurize/work/.local/lib/python3.7/site-packages/torch/tensor.py", line 458, in __array__
    return self.numpy()
TypeError: can't convert CUDA tensor to numpy. Use Tensor.cpu() to copy the tensor to host memory first.

解决办法

这个问题是由 python 3.7 版本引起的。修改部分 python 源码即可。

根据报错信息,定位到 /home/featurize/work/.local/lib/python3.7/site-packages/torch/tensor.py

将 self.numpy() 改成 self.cpu().numpy(),即找到 tensor.py 的第 458 行

    def __array__(self, dtype=None):
        if dtype is None:
            return self.numpy()
        else:
            return self.numpy().astype(dtype, copy=False)

改成

    def __array__(self, dtype=None):
        if dtype is None:
            return self.cpu().numpy()
        else:
            return self.cpu().numpy().astype(dtype, copy=False)

使用 vim 修改

  1. 如果服务器上装有 vim,可以使用 vim 打开 tensor.py 文件
cd /home/featurize/work/.local/lib/python3.7/site-packages/torch
vim tensor.py
  1. 在 vim 中键入 /numpy 搜索 numpy ,输入 n 向下搜索,N 向上搜索
  2. 输入 i 切换到编辑模式,进行修改
  3. 修改完成,使用 Esc 键切换到普通模式。输入 :wq 保存 tensor.py 文件并退出 vim

使用 Jupyter notebook

如果使用 notebook 运行代码,如 colab 环境下,则可以使用魔术命令修改 tensor.py 文件。

  1. 首先切换到 tensor.py 所在目录下
cd /home/featurize/work/.local/lib/python3.7/site-packages/torch

注意:colab 的 tensor 在 usr/local/lib/python3.7/dist-packages/torch

  1. 使用 %pycat tensor.py 打开 tensor.py 文件
  2. 复制 tensor.py 中的所有代码到一个单元格中,将 self.numpy() 改成 self.cpu().numpy()
  3. 移除原有 tensor.py 文件 !rm tensor.py
  4. 在单元格的开头加入 %%writefile tensor.py,运行单元格生成新的 tensor.py 文件。再次运行就不会报错。

当然,也可以直接切换到 tensor.py 所在目录下。把下面我修改好的代码复制到一个单元格中,运行单元格写入修改过的 tensor.py 文件。跳过上面的步骤 2-5 。

%%writefile tensor.py
import sys
import torch
import torch._C as _C
from collections import OrderedDict
import torch.utils.hooks as hooks
import warnings
import weakref
from torch._six import imap
from torch._C import _add_docstr
from numbers import Number


# NB: If you subclass Tensor, and want to share the subclassed class
# across processes, you must also update torch/multiprocessing/reductions.py
# to define a ForkingPickler serialization mode for the class.
#
# NB: If you add a new method to Tensor, you must update
# torch/__init__.py.in to add a type annotation for your method;
# otherwise, it will not show up in autocomplete.
class Tensor(torch._C._TensorBase):
    def __deepcopy__(self, memo):
        if not self.is_leaf:
            raise RuntimeError("Only Tensors created explicitly by the user "
                               "(graph leaves) support the deepcopy protocol at the moment")
        if id(self) in memo:
            return memo[id(self)]
        with torch.no_grad():
            if self.is_sparse:
                new_tensor = self.clone()
            else:
                new_storage = self.storage().__deepcopy__(memo)
                new_tensor = self.new()
                new_tensor.set_(new_storage, self.storage_offset(), self.size(), self.stride())
            memo[id(self)] = new_tensor
            new_tensor.requires_grad = self.requires_grad
            return new_tensor

    def __reduce_ex__(self, proto):
        # See Note [Don't serialize hooks]
        torch.utils.hooks.warn_if_has_hooks(self)
        args = (self.storage(),
                self.storage_offset(),
                tuple(self.size(
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值