问题描述
在GAN的训练过程中,训练G(生成器)时需要将D(判别器)固定。训练D时需要将G固定。在网上找的训练程序中有detach函数。网上查阅,detach函数可以切断反向梯度传播。
先放代码
if ii % opt.d_every == 0:
# 训练判别器
optimizer_d.zero_grad()
## 尽可能的把真图片判别为正确
output = netd(real_img)
error_d_real = criterion(output, true_labels)
error_d_real.backward()
## 尽可能把假图片判别为错误
noises.data.copy_(t.randn(opt.batch_size, opt.nz, 1, 1))
fake_img = netg(noises).detach() # 根据噪声生成假图
output = netd(fake_img)
error_d_fake = criterion(output, fake_labels)
error_d_fake.backward()
optimizer_d.step()
error_d = error_d_fake + error_d_real
errord_meter.add(error_d.item())
if ii % opt.g_every == 0:
# 训练生成器
optimizer_g.zero_grad()
noises.data.copy_(t.randn(opt.batch_size, opt.nz, 1, 1))
fake_img = netg(noises)
output = netd(fake_img)
error_g = criterion(output, true_labels)
error_g.backward()
optimizer_g.step()
errorg_meter.add(error_g.item())
我们可以观察到,在训练D的时候使用了detach,在训练G的时候没有使用detach。
解释
真正更新梯度是在optmizer,所以两个部分训练是互不影响的,不用detach也可以。使用detach可以节约一些计算。