本文主要讨论
pytorch
在训练时出现错误:Runtime Error:one of the variables needed for gradient computation has been modified by an inplace operation 的不同情况。
inplace操作类似于
a+=5
即使用变量参与了运算,又修改了变量的值。
这类问题在
这里
讲解的比较清楚。
比如一个张量a用于计算张量b,随后又对a重新赋值,但是使用b求解loss并反向传播,会导致这一问题。
使用1.5以上版本的pytorch训练GAN的时候也会出现这样的问题,但这个时候检查代码会发现模型结构可能并没有inplace的操作。这是由于版本更新了多个模型优化器step()方法。
这一问题在
这里
可找到比较详细的解释。
在1.4及以前的pytorch,我们训练GAN通常遵循以下步骤:
fake = G(input)
outFake = D(fake)
outReal = D(real)
lossD = - torch.mean(torch.log(outReal ) + torch.log(1. - outFake))
lossG = torch.mean(torch.log(1. - outFake))
optD.zero_grad()
lossD.backward(retain_graph=True)
optD.step()
optG.zero_grad()
lossG.backward()
optG.step()
也就是先通过生成器G生成假的输出fake,分别输入判别器D得到结果,计算G和D的loss,分别反向传播。由于backward两次,且两个网络是“连通的”(通过fake张量)所以第一次backward时加上retain_graph=True
即可。
这个过程在1.4以及之前的版本是没有问题的。
但是换到1.5以上,就会出现本文所描述的错误,通常还会在此之前先报例如“cudnnConvBackward”或其他网络层的反向传播错误,随后traceback到这个错误。
原因在于,D的优化器在第一次lossD反向传播时 inplace的修改了discriminator的参数,而优化G有需要用到D,导致了这一错误。
解决方案是,我们需要人为分开D和G使用的两个loss,例如
fake = G(input)
outFake = D(fake)
lossG = torch.mean(torch.log(1. - outFake))
optG.zero_grad()
lossG.backward()
optG.step()
outReal = D(real)
outFake = D(fake.detach())
lossD = - torch.mean(torch.log(outReal ) + torch.log(1. - outFake))
optD.zero_grad()
lossD.backward()
optD.step()
先生成fake,通过D判别并计算G的loss,反向传播修改G的参数。
接下来再次将fake和real传入D中,此时fake加上detach,将已经修改过的G分离开,并计算D的loss从而优化D。
这一问题是1.5以后才出现的,主要是由于GAN的两部分网络通过生成的张量连接了起来,两个网络分别优化反向传播时,有一个会先被inplace的修改掉,从而产生错误。而我们知道,GAN本身两个网络是要分别修改交替优化的。所以在适当的位置detach分离可以让两个网络在一次迭代中正常的优化。
上述的解答是官方在对应issue中提到的解决方案,个人测试后发现确实可以避免这样的错误。
one of the variables needed for gradient computation has been modified by an inplace operation
本文主要讨论pytorch在训练时出现错误:Runtime Error:one of the variables needed for gradient computation has been modified by an inplace operation 的不同情况。对需要求导的Tensor使用了 inplace 操作inplace操作类似于a+=5即使用变量参与了运算,又修改了变量的值。这类问题在这里降解的比较清楚。比如一个张量a用于计算张量b,随后又对a重新赋值,但是使用b求解loss并反
【完美解决】RuntimeError: one of the variables needed for gradient computation has been modified by an inp
今天跑网络在进行loss.backward()的时候,出现了如下错误:
one of the variables needed for gradient computation has been modified by an inplace operation: [torch.FloatTensor [2, 64]], which is output 0 of ViewBackward, is at version 21;
expected version 20 instead. Hint: enabl
写完了训练的代码,运行了以后发现了这么一个错:
RuntimeError: one of the variables needed for gradient computation has been modified by an inplace operation: [torch.FloatTensor [544, 768]], which is output 0 of ViewBackward, is at version 1; expected version 0 instead.
Hint: en
使用一个pytorch写的模型时,训练到45epoch时,报错:RuntimeError:one of the
variables needed for
gradient computat
ion has been
modified by an
inplace operation
But this error just appears in some pl
aces. Why it occurs?
首先说明,按照我目前的查询,这可能是全网唯一公开的正确解决方法,所以一定要看下去
1、错误发生情景
在github和百度上搜索gan示例代码的时候,通常会得到下面这种代码:先更新辨别器,再更新生成器。
netD.zero_grad()
#optimizerD.step()
real_out = netD(real_img).mean()
fake_out = netD(fake_img).mean()
runtimeerror: one of the variables needed for gradient computation has been modified by an inplace operation
很抱歉,我不知道回答这个问题。
我不明白你的意思。
我们不得不把梯度计算中所需要的变量中的某一个改变了,这就造成了运行时错误。这个错误通常表示您在计算梯度时修改了一个需要进行梯度计算的变量,这违反了PyTorch计算图的要求。这通常发生在使用
inplace操作(如`tensor.add_()`)时,这些操作会直接修改原始张量而不返回一个新的张量。
解决此问题的方法之一是避免使用
inplace操作。您可以使用类似于`tensor = tensor.add(1)`的操作来代替`tensor.add_(1)`,这将返回一个新的张量,而不是直接修改原始张量。
另一种解决方法是使用`.detach()`将张量从计算图中分离出来,从而避免梯度传播到该张量。例如,您可以使用`tensor.detach().add_(1)`来修改张量,而不会影响梯度计算。
最后,您还可以使用`.clone()`复制一个张量来避免原地修改。例如,`tensor.clone().add_(1)`将复制张量并对副本进行
inplace操作,而不会影响原始张量或梯度计算。
解决PyTorch 出现RuntimeError: Function AddBackward0 returned an invalid gradient at index 1 问题
训练过程中Loss突然变为NaN的可能原因与解决
我是一个对称矩阵:
训练过程中Loss突然变为NaN的可能原因与解决
qq_48395445:
训练过程中Loss突然变为NaN的可能原因与解决
我是一个对称矩阵:
训练过程中Loss突然变为NaN的可能原因与解决
Ludicrouers: