PyTorch - RuntimeError:后端 CPU 的预期对象,但为参数 #2 'weight' 获得了后端 CUDA

Posted

技术标签:

【中文标题】PyTorch - RuntimeError:后端 CPU 的预期对象,但为参数 #2 \'weight\' 获得了后端 CUDA【英文标题】:PyTorch - RuntimeError: Expected object of backend CPU but got backend CUDA for argument #2 'weight'PyTorch - RuntimeError:后端 CPU 的预期对象,但为参数 #2 'weight' 获得了后端 CUDA 【发布时间】:2019-09-22 18:52:10 【问题描述】:

我加载了我之前训练的模型,并希望通过此模型对磁盘中的单个(测试)图像进行分类。我的模型中的所有操作都是在我的 GPU 上进行的。因此,我通过调用cuda() 函数将测试图像的numpy array 移动到GPU。当我用测试图像的numpy array 调用模型的forward() 函数时,我得到RuntimeError: Expected object of backend CPU but got backend CUDA for argument #2 'weight'

这是我用来从磁盘加载图像并调用forward() 函数的代码:

test_img = imageio.imread('C:\\Users\\talha\\Desktop\\dog.png')
test_img = imresize(test_img, (28, 28))
test_tensor = torch.from_numpy(test_img)
test_tensor = test_tensor.cuda()
test_tensor = test_tensor.type(torch.FloatTensor)
log_results = model.forward(test_tensor)

软件环境:

火炬:1.0.1

GPU:Nvidia GeForce GTX 1070

操作系统:Windows 10 64-bit

Python:3.7.1

【问题讨论】:

Domodel.cuda() 确保模型在 GPU 上。看来模型没有GPU 不,它不起作用。 @UmangGupta 【参考方案1】:

在通过 GPU 发送之前转换为 FloatTensor

所以,操作的顺序是:

test_tensor = torch.from_numpy(test_img)

# Convert to FloatTensor first
test_tensor = test_tensor.type(torch.FloatTensor)

# Then call cuda() on test_tensor
test_tensor = test_tensor.cuda()

log_results = model.forward(test_tensor)

【讨论】:

感谢您的解决方案。你能解释一下为什么这个顺序很关键吗? 我不太确定,但我怀疑这是因为所有类型转换操作(在这种情况下为FloatTensor)都发生在 CPU 上。因此,张量被带回 CPU 进行转换。 好的。我现在对张量类型有了更好的理解。您的数据需要是 torch.cuda.FloatTensor 的实例,才能在 GPU 上进行训练。当您编写 test_tensor.type(torch.FloatTensor) 时,张量将转换为 torch.FloatTensor,这与 GPU 上的模型不兼容。所以,除了上面的方法,你也可以把test_tensor.type(torch.FloatTensor)改成test_tensor.type(torch.cuda.FloatTensor)

以上是关于PyTorch - RuntimeError:后端 CPU 的预期对象,但为参数 #2 'weight' 获得了后端 CUDA的主要内容,如果未能解决你的问题,请参考以下文章

PyTorch:DecoderRNN:RuntimeError:输入必须有 3 维,得到 2

如何修复 RuntimeError:dlpack 不支持 Bool 类型

PyTorch:RuntimeError:输入、输出和索引必须在当前设备上

RuntimeError:cuDNN 错误:CUDNN_STATUS_NOT_INITIALIZED 使用 pytorch

PyTorch 模型训练:RuntimeError:cuDNN 错误:CUDNN_STATUS_INTERNAL_ERROR

Pytorch - RuntimeError:尝试第二次向后退,但缓冲区已被释放