Torch RUNTIMERROR:释放保存的变量后,直接访问这些变量。(第二次使用.backward)

2024-10-01 19:26:50 发布

您现在位置:Python中文网/ 问答频道 /正文

编辑:问题解决了,只需使用W数据“转换”输入W

大家好

在我的代码中,我试图训练一个模型,以便它将给定的样本移动到给定的目标分布。下一步是引入中间分布并使用循环,以便粒子(样本)以迭代方式从一个分布移动到另一个分布。不幸的是,在第二次迭代中,我在运行代码时收到以下错误消息: “尝试第二次反向遍历图形(或在已释放的变量后直接访问这些变量)。调用.backward()或autograd.grad()时,将释放图形的已保存中间值。”。如果您需要再次反向浏览图形,或者如果您需要在调用backward后访问保存的变量,请指定retain_graph=True“

我认为retain_graph=True不适合我的问题,因为我宁愿在每次迭代后清除模型,也不愿保留它。但是,我试了一下,结果是以下错误:

梯度计算所需的一个变量已通过就地操作进行了修改:[torch.FloatTensor[1,2]]版本为2251;预期版本为2250。提示:使用torch.autograd.set_detect_normal(True),启用异常检测以查找无法计算其梯度的操作

以下是我的代码的相关部分:

    for k in range(1, K_intermediate+1):

           flow = BasicFlow(dim=d, n_flows=n_flows, flow_layer=flow_layer)
           ldj = train_flow(
                 flow, x, W, f_intermediate(x,k-1), lambda x: 
                      f_intermediate(x,k), epochs=2500
    )
           x, xtransp = flow(x)
           x = xtransp.data

以及列车流量功能:

def train_flow(flow, sample, weights, f0, f1, epochs=1000):
    optim = torch.optim.Adam(flow.parameters(), lr=1e-2)

    for i in range(epochs):
        x0, xtransp = flow(sample)
        ldj = accumulate_kl_div(flow).reshape(sample.size(0))
    
        loss = det_loss(
            x_0 = x0, 
            x_transp = xtransp, 
            weights = weights, 
            ldj = ldj, 
            f0 = f0, 
            f1 = f1
        )
        loss.backward(retain_graph = True)
        optim.step()
        optim.zero_grad()
        reset_kl_div(flow)
        if i % 250 == 0:
            if i > 0 and previous_loss - loss.item() < 1e-06:
                break                
            print(loss.item())
            previous_loss = loss.item()
            if torch.isnan(loss) == True:
                break
    return ldj

请注意,问题只是在我开始捕获ldj值(行列式雅可比矩阵的对数,对于那些想知道的人来说)之后才出现的。因为这个值对于进一步的计算至关重要,所以我不能删除它


Tags: sample代码true图形torchflowoptimgraph

热门问题