我试图优化一个PyTorch张量,我也使用它作为网络的输入。让我们把这个张量称为“形状”。我的优化器如下:
optimizer = torch.optim.Adam(
[shape],
lr=0.0001
)我还使用这个“形状”张量来获取顶点值:
vertices = model(shape)我的损失函数计算损失,就像推导的顶点和地面真相顶点的差异一样:
loss = torch.sqrt(((gt_vertices - vertices) ** 2).sum(2)).mean(1).mean()所以我所做的实际上是估计形状值。我只对形状价值感兴趣。当一切都在CPU上时,这是非常好的工作方式。然而,当我通过调用to("cuda")将我的形状和模型放在GPU上时,我得到的是经典的非叶张量错误:
ValueError: can't optimize a non-leaf Tensor在优化器中对shape调用.detach().cpu()解决了这个问题,但是梯度不能按其应有的方式流动,而且我的值也没有更新。我怎么才能把这事做好?
发布于 2021-08-18 11:11:02
当.to('cuda') (例如,调用shape_p = shape.to('cuda') )时,您正在复制shape。虽然shape仍然是叶张量,但shape_p不是,因为它的“父”张量是shape。因此,shape_p不是一个叶,在试图优化它时返回错误。
在设置了优化器之后将其发送到CUDA设备,可以解决这个问题(https://discuss.pytorch.org/t/effect-of-calling-model-cuda-after-constructing-an-optimizer/15165/4,在某些情况下,这是不可能的)。
>>> optimizer = torch.optim.Adam([shape], lr=0.0001)
>>> shape = shape.cuda()不过,在我看来,最好的办法是将它直接发送到init上:
>>> shape = torch.rand(1, requires_grad=True, device='cuda')
>>> optimizer = torch.optim.Adam([shape], lr=0.0001)这样,它仍然是一个叶张量。
https://stackoverflow.com/questions/68830818
复制相似问题