pytorch实例张量未移动到GPU,即使明确调用了cuda()

我在进行一个项目,模型需要访问在类构造函数中声明的张量(我继承了torch.nn.Module类),然后我需要在forward()方法中通过简单的matmul()使用这个张量,模型通过cuda()调用被发送到GPU上:

model = Model()
model.cuda()

然而,当我通过以下方式对简单输入X进行前向传播时:

model(X) # 或 model.forward(X)

我得到了以下错误:

RuntimeError: Expected object of type torch.cuda.FloatTensor but found type torch.FloatTensor for argument #2 ‘mat2’

这表明matmul的第二个参数(我声明的实例张量)在CPU上,而预期它在GPU上(与模型和数据的其余部分一样)。

在matmul中,张量通过matrix.t()进行转置。

我甚至尝试通过以下方式重写cuda()方法:

def cuda(self):
    super().cuda()
    self.matrix.cuda()

数据已经在GPU上,这意味着以下代码行已经执行:

X = X.cuda()

此外,错误明确指出matmul的第二个参数是张量(称为matrix),而不是X。


回答:

我们假设以下几点:

  1. X正确地移动到了GPU上

  2. Model类中声明的张量是一个简单的属性。

    即类似于以下内容:

class Model(nn.Module):
    def __init__(self):
        super().__init__()
        self.matrix = torch.randn(784, 10)

    def forward(self, x):
        return torch.matmul(x, self.matrix)

如果是这样的话,你的第一次尝试不会成功,因为nn.Module.cuda()方法只会将所有的ParametersBuffers移动到GPU上。

你需要将Model.matrix变成一个Parameter,而不是普通的属性。将其包装在参数类中。类似于这样:

self.matrix = nn.Parameter(torch.randn(784, 10))

现在,你没有像上面那样自动转换到GPU,而是尝试在重写中手动对Model.matrix调用.cuda()方法。

这也不起作用,因为nn.Module.cuda()方法和torch.Tensor.cuda()方法之间存在细微的区别。

虽然nn.Module.cuda()Module的所有ParametersBuffers移动到GPU并返回自身,但torch.Tensor.cuda()只返回GPU上的张量的副本

原始张量不受影响。


总结来说,可以采取以下两种方法之一:

  1. 将你的matrix属性包装为Parameter,或者
  2. 通过以下方式将GPU副本重新赋值给matrix:
self.matrix = self.matrix.cuda()

在你的重写中。

我建议采用第一种方法。

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注