PyTorch -尝试最小化对称矩阵的函数时出错



我想最小化对称矩阵的损失函数,其中一些值是固定的。为此,我定义了张量A_nan,并将torch.nn.Parameter类型的对象放在要估计的值中。

然而,当我尝试运行代码时,我得到以下异常:

RuntimeError: Trying to backward through the graph a second time (or directly access saved tensors after they have already been freed). Saved intermediate values of the graph are freed when you call .backward() or autograd.grad(). Specify retain_graph=True if you need to backward through the graph a second time or if you need to access saved tensors after calling backward.

我发现这个问题似乎有同样的问题,但那里提出的解决方案并不适用于我的情况(据我所知)。或者至少我不知道如何应用它。

下面是我正在尝试做的一个独立的例子:

import torch
A_nan = torch.tensor([[1.0, 2.0, torch.nan], [2.0, torch.nan, 5.0], [torch.nan, 5.0, 6.0]])
nan_idxs = torch.where(torch.isnan(torch.triu(A_nan)))
A_est = torch.clone(A_nan)
weights = torch.nn.ParameterList([])
for i, j in zip(*nan_idxs):
w = torch.nn.Parameter(torch.distributions.Normal(3, 0.5).sample())
A_est[i, j] = w
A_est[j, i] = w
weights.append(w)
optimizer = torch.optim.Adam(weights, lr=0.01)
for _ in range(10):
optimizer.zero_grad()
loss = torch.sum(A_est ** 2)
loss.backward()
optimizer.step()

调用loss.backward()后计算图被销毁。注意,A_est不是一个叶子,因此在循环的第二次循环中没有创建任何图。

一个可能的解决方案是:

for _ in range(2):
optimizer.zero_grad()
A_est = A_est.detach()
for idx, (i, j) in enumerate(zip(*nan_idxs)):
w = weights[idx]
A_est[i, j] = w
A_est[j, i] = w
loss = torch.sum(A_est**2)
loss.backward()
optimizer.step()
print(loss)
# tensor(110.3664, grad_fn=<SumBackward0>)
# tensor(109.0410, grad_fn=<SumBackward0>)

最新更新