gpt4 book ai didi

python - RuntimeError : Trying to backward through the graph a second time, 但缓冲区已被释放。指定 retain_graph=True

转载 作者:行者123 更新时间:2023-12-01 21:43:12 25 4
gpt4 key购买 nike

我是 Python 和 PyTorch 的学生和初学者。我有一个非常基本的神经网络,我遇到了上面提到的 RunTimeError。重现错误的代码是这样的:

import torch 
from torch import nn
from torch import optim
import torch.nn.functional as F
import matplotlib.pyplot as plt

# Ensure Reproducibility
torch.manual_seed(0)

# Data Generation
x = torch.randn((100,1), requires_grad = True)
y = 1 + 2 * x + 0.3 * torch.randn(100,1)
# Shuffles the indices
idx = np.arange(100)
np.random.shuffle(idx)

# Uses first 80 random indices for train
train_idx = idx[:70]
# Uses the remaining indices for validation
val_idx = idx[70:]

# Generates train and validation sets
x_train, y_train = x[train_idx], y[train_idx]
x_val, y_val = x[val_idx], y[val_idx]

class OurFirstNeuralNetwork(nn.Module):
def __init__(self):
super(OurFirstNeuralNetwork, self).__init__()
# Here we "define" our Neural Network Architecture
self.fc1 = nn.Linear(1, 5)
self.non_linearity_fc1 = nn.ReLU()
self.fc2 = nn.Linear(5,1)
#self.non_linearity_fc2 = nn.ReLU()

def forward(self, x):
# The forward pass
# Here we define how activations "flow" between neurons. We've already discussed the "Sum" and "Transformation" steps of the forward pass.
sum_fc1 = self.fc1(x)
transformation_fc1 = self.non_linearity_fc1(sum_fc1)
sum_fc2 = self.fc2(transformation_fc1)
#transformation_fc2 = self.non_linearity_fc2(sum_fc2)
# The transformation_fc2 is also the output of our model which symbolises the end of our forward pass.
return sum_fc2

# Instantiate the model and train

model = OurFirstNeuralNetwork()
print(model)
print(model.state_dict())
n_epochs = 1000
loss_fn = nn.MSELoss(reduction='mean')
optimizer = optim.Adam(model.parameters())

for epoch in range(n_epochs):


model.train()
optimizer.zero_grad()
prediction = model(x_train)
loss = loss_fn(y_train, prediction)
print(epoch, loss)
loss.backward(retain_graph=True)
optimizer.step()


print(model.state_dict())

一切都是基本和标准的,这很好用。

但是,当我取出“retain_graph=True”参数时,它会抛出 RunTimeError。通过阅读各种论坛,我了解到这与图表在第一次迭代后被丢弃有关,但我看过许多教程和博客,其中 loss.backward() 是必经之路,尤其是因为它节省了内存。但是我无法从概念上理解为什么它对我不起作用。

如果我提出问题的方式不符合预期格式,我们将不胜感激,我深表歉意。我乐于接受反馈,并将有义务包含更多细节或改写问题,以便每个人都更容易。提前致谢!

最佳答案

您需要在 optimizer.step() 之后添加 optimizer.zero_grad() 以将梯度归零。

为什么需要这样做?

当您执行 loss.backward() 时,torch 将计算参数的梯度并更新参数的 .grad 属性。当您执行 optimizer.step() 时,将使用 .grad 属性更新参数,即 `parameter = parameter - lr*parameter.grad。

由于您没有清除梯度并第二次向后调用,它将计算 dl/d(updated param) 这将需要通过 paramter.grad 进行反向传播第一关的。向后执行时,不会存储此梯度的计算图,因此您必须传递 retain_graph= True 来消除错误。但是,我们不想为更新参数而这样做。相反,我们想要清除梯度,并重新启动一个新的计算图,因此,您需要使用 .zero_grad 调用将梯度归零。

另见 Why do we need to call zero_grad() in PyTorch?

关于python - RuntimeError : Trying to backward through the graph a second time, 但缓冲区已被释放。指定 retain_graph=True,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61015728/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com