在Pytorch评估过程中耗尽内存

use*_*533 9 pytorch

我在pytorch训练模型.每10个时代,我正在评估整列火车和测试数据集的列车和测试误差.由于某种原因,评估功能导致我的GPU内存不足.这很奇怪,因为我有相同的批量大小用于培训和评估.我相信这是由于net.forward()方法被重复调用并将所有隐藏值存储在内存中但我不知道如何解决这个问题?

def evaluate(self, data):
    correct = 0
    total = 0
    loader = self.train_loader if data == "train" else self.test_loader
    for step, (story, question, answer) in enumerate(loader):
        story = Variable(story)
        question = Variable(question)
        answer = Variable(answer)
        _, answer = torch.max(answer, 1)

        if self.config.cuda:
            story = story.cuda()
            question = question.cuda()
            answer = answer.cuda()

        pred_prob = self.mem_n2n(story, question)[0]
        _, output_max_index = torch.max(pred_prob, 1)
        toadd = (answer == output_max_index).float().sum().data[0]
        correct = correct + toadd
        total = total + captions.size(0)

    acc = correct / total
    return acc
Run Code Online (Sandbox Code Playgroud)

Mon*_*lto 15

我认为它在验证期间失败,因为您不使用optimizer.zero_grad().zero_grad执行detach,使张量成为叶子.它通常用于训练部分的每个时期.

已删除在PyTorch 0.4.0的Variable中使用volatile标志.参考 - migration_guide_to_0.4.0

从0.4.0开始,为避免在验证期间计算梯度,请使用torch.no_grad()

迁移指南中的代码示例.

# evaluate
with torch.no_grad():                   # operations inside don't track history
  for input, target in test_loader:
      ...
Run Code Online (Sandbox Code Playgroud)

对于0.3.X,使用volatile应该可行.


Ego*_*kin 11

我建议对评估期间使用的所有变量使用volatile flag设置为True,

    story = Variable(story, volatile=True)
    question = Variable(question, volatile=True)
    answer = Variable(answer, volatile=True)
Run Code Online (Sandbox Code Playgroud)

因此,不存储渐变和操作历史记录,您将节省大量内存.此外,您可以在批处理结束时删除对这些变量的引用:

del story, question, answer, pred_prob
Run Code Online (Sandbox Code Playgroud)

不要忘记将模型设置为评估模式(并在完成评估后返回到列车模式).例如,像这样

model.eval()
Run Code Online (Sandbox Code Playgroud)