在这个例子中为什么需要在变量上调用detach?

Was*_*mad 11 pytorch

我正在通过这个例子 - https://github.com/pytorch/examples/blob/master/dcgan/main.py我有一个基本的问题.

fake = netG(noise)
label = Variable(label.fill_(fake_label))
output = netD(fake.detach()) # detach to avoid training G on these labels
errD_fake = criterion(output, label)
errD_fake.backward()
D_G_z1 = output.data.mean()
errD = errD_real + errD_fake
optimizerD.step()
Run Code Online (Sandbox Code Playgroud)

我理解为什么我们调用detach()变量fake,因此不会为Generator参数计算梯度.我的问题是,它是否重要,因为它optimizerD.step()只会更新与Discriminator相关的参数?

OptimizerD定义为: optimizerD = optim.Adam(netD.parameters(), lr=opt.lr, betas=(opt.beta1, 0.999))

此外,在下一步我们将更新Generator的参数时,在此之前我们将调用netG.zero_grad()最终删除所有先前计算的梯度.而且,当我们更新G网络的参数时,我们这样做 - output = netD(fake).在这里,我们没有使用分离.为什么?

那么,为什么在上面的代码中需要分离变量(第3行)?

Jen*_*sen 9

你是对的,optimizerD只有在调用之前不会使用更新netD和渐变,所以不需要分离,它只是节省时间,因为你不计算生成器的渐变.netGnetG.zero_grad()

你基本上也在回答你的另一个问题,你没有fake在第二个区块中分离,因为你特别想要计算渐变,netG以便能够更新它的参数.

注意在第二个块中real_label如何使用相应的标签fake,因此如果鉴别器发现假输入是真实的,则最终损失很小,反之亦然,这正是您想要的生成器.不确定这是否让你感到困惑,但与在假输入上训练鉴别器相比,它确实是唯一的区别.