Pytorch - 运行时错误:尝试再次向后浏览图形,但缓冲区已被释放

问题描述 投票:0回答:3

我一直遇到这个错误:

运行时错误:尝试再次向后浏览图形,但缓冲区已被释放。第一次向后调用时指定retain_graph=True。

我在 Pytorch 论坛中搜索过,但仍然找不到我在自定义损失函数中做错了什么。我的模型是 nn.GRU,这是我的自定义损失函数:

def _loss(outputs, session, items):  # `items` is a dict() contains embedding of all items
    def f(output, target):
        pos = torch.from_numpy(np.array([items[target["click"]]])).float()
        neg = torch.from_numpy(np.array([items[idx] for idx in target["suggest_list"] if idx != target["click"]])).float()
        if USE_CUDA:
            pos, neg = pos.cuda(), neg.cuda()
        pos, neg = Variable(pos), Variable(neg)

        pos = F.cosine_similarity(output, pos)
        if neg.size()[0] == 0:
            return torch.mean(F.logsigmoid(pos))
        neg = F.cosine_similarity(output.expand_as(neg), neg)

        return torch.mean(F.logsigmoid(pos - neg))

    loss = map(f, outputs, session)
    return -torch.mean(torch.cat(loss))

训练代码:

    # zero the parameter gradients
    model.zero_grad()

    # forward + backward + optimize
    outputs, hidden = model(inputs, hidden)
    loss = _loss(outputs, session, items)
    acc_loss += loss.data[0]

    loss.backward()
    # Add parameters' gradients to their values, multiplied by learning rate
    for p in model.parameters():
        p.data.add_(-learning_rate, p.grad.data)
python deep-learning pytorch recurrent-neural-network autograd
3个回答
62
投票

问题来自我的训练循环:它不会在批次之间分离或重新打包隐藏状态?如果是这样,那么

loss.backward()
会尝试一直反向传播到时间开始,这适用于第一批,但不适用于第二批,因为第一批的图形已被丢弃。

有两种可能的解决方案。

  1. 在批次之间分离/重新打包隐藏状态。有(在 至少)三种方法可以做到这一点(我选择了这个解决方案):

    隐藏.detach_()

    (或等效隐藏 = hide.detach())。

  2. loss.backward(retain_graph=True)
    替换loss.backward(),但要知道每个连续的批次将比前一个批次花费更多的时间,因为它必须一直反向传播到第一个批次的开始。

示例


2
投票

我也有这个错误。有时我在模型中输入与输入相同的张量。通过在该张量上调用“.detach()”,它消除了错误。

那个张量不是我训练的内容,我不想在它上毕业。调用 detach 会将其从图表中删除,因此 pytorch 'backward()' 不会考虑它。


0
投票

一个原因可能是

input
hidden
具有
requires_grad = True
,如果是这种情况,您需要将其设为 false,并且可以将其设置为
input.detach_()
hidden.detach_()

就地做

© www.soinside.com 2019 - 2024. All rights reserved.