Lui*_*eal 3 python artificial-intelligence machine-learning pytorch
我正在开发一个项目,其中模型需要访问我在类的构造函数init中声明的张量(我对 torch.nn.Module 类进行了子类),然后我需要在 forward() 中使用这个张量通过简单的 matmul() 方法,模型通过 cuda() 调用发送到 GPU:
model = Model()
model.cuda()
Run Code Online (Sandbox Code Playgroud)
但是,当我通过以下方式对简单输入 X 进行前向传播时:
model(X) # or model.forward(X)
Run Code Online (Sandbox Code Playgroud)
我得到
RuntimeError: 类型为 torch.cuda.FloatTensor 的预期对象,但为参数 #2 'mat2' 找到类型 torch.FloatTensor
表示 matmul 的第二个参数(我声明的实例张量)在 CPU 上,并且在 GPU 上是预期的(作为模型和数据的其余部分)。
在 matmul 中,张量通过 matrix.t() 转置
我什至尝试通过覆盖 cuda() 方法:
def cuda(self):
super().cuda()
self.matrix.cuda()
Run Code Online (Sandbox Code Playgroud)
数据已经在 GPU 中,这意味着已经执行了以下代码行:
X = X.cuda()
Run Code Online (Sandbox Code Playgroud)
错误还明确指出 matmul 的参数 2,在这种情况下,它是张量(称为矩阵)而不是 X。
我想从@Vaisakh 的回答中强调这一点:
nn.Module.cuda() 将模块的所有参数和缓冲区移动到 GPU 并返回自身,而 torch.Tensor.cuda()只返回GPU 上张量的副本。
换句话说,正如@Umang_Gupta 在他的评论中所说:
# if m is a Module, you do:
m.cuda()
# if t is a Tensor, you do:
t = t.cuda()
Run Code Online (Sandbox Code Playgroud)
小智 7
让我们假设以下情况:
X 正确移动到 GPU
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)
Run Code Online (Sandbox Code Playgroud)
如果是这样,您的第一次尝试将不起作用,因为该nn.Module.cuda()方法仅将所有Parameters和移动Buffers到 GPU。
您需要创建Model.matrix一个Parameter而不是常规属性。将其包装在参数类中。就像是:
self.matrix = nn.Parameter(torch.randn(784, 10))
Run Code Online (Sandbox Code Playgroud)
现在,您尝试在覆盖中手动调用.cuda()方法,而不是像上面那样自动转换到 GPU Model.matrix。
由于nn.Module.cuda()方法和torch.Tensor.cuda()方法之间的细微差别,这也不起作用。
虽然nn.Module.cuda()移动所有的Parameters和Buffers的Module对GPU和回报本身,torch.Tensor.cuda()只返回一个副本的张量在GPU上。
原始张量不受影响。
总之,要么:
matrix属性包装为Parameter或self.matrix = self.matrix.cuda()
Run Code Online (Sandbox Code Playgroud)
在您的覆盖中。
我会建议第一个。
| 归档时间: |
|
| 查看次数: |
3797 次 |
| 最近记录: |