Pytorch: retain_graph=True错误信息

(Pytorch:RuntimeError: Trying to backward through the graph a second time, but the buffers have already been freed. Specify retain_graph=True when calling backward the first time)

1. 具有多个loss值

retain_graph设置True,一般多用于两次backward

# 假如有两个Loss,先执行第一个的backward,再执行第二个backward
loss1.backward(retain_graph=True) # 这样计算图就不会立即释放
loss2.backward() # 执行完这个后,所有中间变量都会被释放,以便下一次的循环
optimizer.step() # 更新参数

retain_graph设置True后一定要知道释放,否则显卡会占用越来越多,代码速度也会跑的越来越慢。

2. 但是,有的时候我明明仅有一个模型的也会出现这种错误

第一种是输入的原因。

// Example
x = torch.randn((100,1), requires_grad = True)
y = 1 + 2 * x + 0.3 * torch.randn(100,1)
x_train, y_train = x[:70], y[:70]
x_val, y_val = x[70:], y[70:]

for epoch in range(n_epochs):
	...
	prediction = model(x_train)
	loss.backward()
	...

在多次循环的过程中,input的梯度没有清除,而且我们也不需要计算输入的梯度,因此将x的require_grad设置为False就可以解决问题。

第二种是我在训练LSTM时候发现的。

class LSTMpred(nn.Module):
    def __init__(self, input_size, hidden_dim):
    	self.hidden = self.init_hidden()
       ...
    def init_hidden(self):	#这里我们是需要个隐层参数的
        return (torch.zeros(1, 1, self.hidden_dim, requires_grad=True),
                torch.zeros(1, 1, self.hidden_dim, requires_grad=True))
    def forward(self, seq):
        ...

这里面的self.hidden我们在每一次训练的时候都要重新初始化隐层参数:

for epoch in range(Epoch):
	...
	model.hidden = model.init_hidden()
	modout = model(seq)
    ...
3. 总结

其实,想想这几种情况都是一回事,都是网络在反向传播中不允许多个backward(),也就是梯度下降反馈的时候,有多个循环过程中共用了同一个需要计算梯度的变量,在前一个循环清除梯度后,后面一个循环过程就会在这个变量上栽跟头(个人想法)。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值