PyTorch自动求导是如何工作的?

3
我已经将此问题提交给cycleGAN的pytorch实现,但由于那里没有人回复我,所以我会在这里再次提问。
我主要困惑的是,在一个单独的反向传递之前,多个正向传递被调用了,可以在代码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)。
在tensorflow中(我认为),反向传播总是针对最后一个输入数据计算的。在这种情况下,loss_G的反向传播将是错误的。相反,应该进行三次反向传递,每次立即跟随其涉及的前向传递。
具体而言,netG_A从loss_G_A的梯度是关于real_A的,但从loss_cycle_B的梯度是关于fake_A的。
我假设这在pytorch中已经得到了解决。但是模型如何知道应该计算哪个输入数据的梯度?
1个回答

4
Pytorch使用基于记录的系统进行自动微分。这意味着它将从它执行的最后一个操作开始反向传播。我认为理解的最好方法是通过流程制作图表。我附上了一个我手工制作的enter image description here
现在你会看到一些模块是“重复”的。我想到的方式与我想到RNN的方式相同;这样,梯度将被添加。

所以通过网络输入的数据被“缓存”了?这确实非常类似于RNN,我从未意识到。 - yfi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接