一行代码解决one of the variables needed for gradient computation has been modified by an inplace operation

网上的没用的解决方法太多,不是降版本就是改inplace。
代码报错如下,原因:在不止一次loss反传中,某个loss已经改变某个变量的inplace,之后的loss再用这个变量时就会报错。

RuntimeError: one of the variables needed for gradient computation has been modified by an inplace operation: [torch.FloatTensor [512, 4]], which is output 0 of AsStridedBackward0, is at version 2; expected version 1 instead. Hint: enable anomaly detection to find the operation that failed to compute its gradient, with torch.autograd.set_detect_anomaly(True).

如果是在对抗中,“因为算G的loss的计算图是包含D的,但是你在G的backward之前更新了D的值,这时候再去计算就不是和forward时候对应的梯度了”(出自虎扑),解释一下就是算D_loss时候已经改变了fake的inplace了,再去算G_loss时候再用fake这个变量就会报错了,解决方案就是在算G_loss前,clone一下这个fake变量就可以,或者再通过网络输出一遍。

修改前:

loss = torch.nn.CrossEntropyLoss()
D_loss = loss(real, 1) + loss(fake, 0)
G_loss = loss(fake, 1)
# 问题出现在fake这个变量被用了两次,而在算D_loss时已经被修改inplace

 修改后:

loss = torch.nn.CrossEntropyLoss()
D_loss = loss(real, 1) + loss(fake, 0)
# 解决办法
fake_clone = fake.detach().clone()
# 或者 fake 可以再经过一遍网络输出
# fake_clone = Net(input)
G_loss = loss(fake_clone, 1)

对抗都是先训练D,再训练G,其他解答居然有调换顺序,能跑了但是也训练不出东西了。

  • 9
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值