我将此作为问题提交给cycleGAN pytorch implementation,但由于那里没有人回复我,我会在这里再次询问。
我主要对在一次向后传递之前调用多次向前传递这一事实感到困惑,请参见代码cycle_gan_model中的以下内容
# GAN loss
# D_A(G_A(A))
self.fake_B = self.netG_A.forward(self.real_A)
pred_fake = self.netD_A.forward(self.fake_B)
self.loss_G_A = self.criterionGAN(pred_fake, True)
# D_B(G_B(B))
self.fake_A = self.netG_B.forward(self.real_B)
pred_fake = self.netD_B.forward(self.fake_A)
self.loss_G_B = self.criterionGAN(pred_fake, True)
# Forward cycle loss G_B(G_A(A))
self.rec_A = self.netG_B.forward(self.fake_B)
self.loss_cycle_A = self.criterionCycle(self.rec_A, self.real_A) * lambda_A
# Backward cycle loss G_A(G_B(B))
self.rec_B = self.netG_A.forward(self.fake_A)
self.loss_cycle_B = self.criterionCycle(self.rec_B, self.real_B) * lambda_B
# combined loss
self.loss_G = self.loss_G_A + self.loss_G_B + self.loss_cycle_A + self.loss_cycle_B + self.loss_idt_A + self.loss_idt_B
self.loss_G.backward()
在我看来,G_A 和 G_B 每个都有三个前向传递,两次接受真实数据(real_A
或real_B
),两次接受假数据(fake_B
或fake_A
)。
在张量流(我认为)中,向后传递总是根据最后一个输入数据计算。在这种情况下, 的反向传播loss_G
将是错误的。相反,应该做三次向后传球,每次都紧跟在他们涉及的向前传球之后。
具体来说,netG_A
的梯度来自loss_G_A
wrtreal_A
但其梯度来自loss_cycle_B
wrt fake_A
。
我认为这在 pytorch 中以某种方式得到了解决。但是模型如何知道它应该计算梯度的输入数据呢?