Pytorch-为什么预分配内存会导致;第二次尝试在图表中倒转“;
假设我有一个简单的单隐层网络,我正在以典型的方式进行训练:Pytorch-为什么预分配内存会导致;第二次尝试在图表中倒转“;,pytorch,backpropagation,tensor,autograd,autodiff,Pytorch,Backpropagation,Tensor,Autograd,Autodiff,假设我有一个简单的单隐层网络,我正在以典型的方式进行训练: for x,y in trainData: optimizer.zero_grad() out = self(x) loss = self.lossfn(out, y) loss.backward() optimizer.step() 这可以按预期工作,但如果我改为预分配并更新输出数组,则会出现错误: out = torch.empty_
for x,y in trainData:
optimizer.zero_grad()
out = self(x)
loss = self.lossfn(out, y)
loss.backward()
optimizer.step()
这可以按预期工作,但如果我改为预分配并更新输出数组,则会出现错误:
out = torch.empty_like(trainData.tensors[1])
for i,(x,y) in enumerate(trainData):
optimizer.zero_grad()
out[i] = self(x)
loss = self.lossfn(out[i], y)
loss.backward()
optimizer.step()
RuntimeError:第二次尝试向后遍历图形,但是
缓冲区已被释放。在以下情况下指定retain_graph=True
第一次向后呼叫
这里发生了什么,在第二个版本中,Pytorch再次尝试通过图形反向?为什么这在第一个版本中不是一个问题?(请注意,即使我没有
zero\u grad()
),也会发生此错误)此错误表示程序正试图再次通过一组操作进行反向传播。第一次通过一组操作进行反向传播时,pytorch会删除计算图以释放内存。因此,第二次尝试反向传播时失败,因为图形已被删除
对此的详细解释
简短回答
使用loss.backward(retain\u graph=True)
。这不会删除计算图
详细答案
在第一个版本中,在每个循环迭代中,每次运行out=self(x)
时都会生成一个新的计算图
Every loop's graph
out = self(x) -> loss = self.lossfn(out, y)
在第二个版本中,由于out
是在循环外声明的,因此每个循环中的计算图都有一个父节点在循环外
- out[i] = self(x) -> loss = self.lossfn(out[i], y)
out[i] - | - out[i] = self(x) -> loss = self.lossfn(out[i], y)
- out[i] = self(x) -> loss = self.lossfn(out[i], y)
因此,这里有一个发生的时间线