dkv*_*dkv 5 backpropagation autodiff pytorch tensor autograd
假设我有一个简单的单隐藏层网络,我正在以典型的方式训练它:
for x,y in trainData:
optimizer.zero_grad()
out = self(x)
loss = self.lossfn(out, y)
loss.backward()
optimizer.step()
Run Code Online (Sandbox Code Playgroud)
这按预期工作,但如果我预先分配并更新输出数组,则会收到错误:
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()
Run Code Online (Sandbox Code Playgroud)
运行时错误:尝试再次向后浏览图形,但缓冲区已被释放。第一次向后调用时指定retain_graph=True。
在第二个版本中,Pytorch 尝试再次向后遍历图表,这里发生了什么?为什么这在第一个版本中不是问题?(请注意,即使我不这样做也会发生此错误zero_grad())
该错误意味着程序正在尝试第二次反向传播一组操作。第一次反向传播一组操作时,pytorch 会删除计算图以释放内存。因此,第二次尝试反向传播时会失败,因为图形已被删除。
这是相同的详细解释。
使用loss.backward(retain_graph=True)。这不会删除计算图。
在第一个版本中,在每次循环迭代中,每次out = self(x)运行都会生成一个新的计算图。
Every loop's graph
out = self(x) -> loss = self.lossfn(out, y)
Run Code Online (Sandbox Code Playgroud)
在第二个版本中,由于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)
Run Code Online (Sandbox Code Playgroud)
因此,这是所发生事件的时间表。
| 归档时间: |
|
| 查看次数: |
1835 次 |
| 最近记录: |