Wasserstein GAN在pytorch中的实现。如何实现损失?

我目前正在pytorch中做一个关于Wasserstein GAN的项目(https:/arxiv.orgpdf1701.07875.pdf).

在Wasserstain GAN中,使用waserstein距离定义了一个新的目标函数为 。enter image description here

这就导致了以下训练GAN的算法。

enter image description here

我的问题是:

当在pytorch中实现算法的第5行和第6行时,我应该乘以损失-1吗?就像我的代码一样(我使用RMSprop作为生成器和批判器的优化器)。

############################
  # (1) Update D network: maximize (D(x)) + (D(G(x)))
  ###########################
  for n in range(n_critic):


    D.zero_grad()

    real_cpu = data[0].to(device)
    b_size = real_cpu.size(0)


    output = D(real_cpu)

    #errD_real = -criterion(output, label) #DCGAN
    errD_real = torch.mean(output)

    # Calculate gradients for D in backward pass
    errD_real.backward()
    D_x = output.mean().item()

    ## Train with all-fake batch
    # Generate batch of latent vectors
    noise = torch.randn(b_size, 100, device=device) #Careful here we changed shape of input (original : torch.randn(4, 100, 1, 1, device=device))

    # Generate fake image batch with G
    fake = G(noise)

    # Classify all fake batch with D
    output = D(fake.detach())


    # Calculate D's loss on the all-fake batch
    errD_fake = torch.mean(output)

    # Calculate the gradients for this batch
    errD_fake.backward()
    D_G_z1 = output.mean().item()

    # Add the gradients from the all-real and all-fake batches
    errD = -(errD_real - errD_fake)

    # Update D
    optimizerD.step()

    #Clipping weights
    for p in D.parameters():
      p.data.clamp_(-0.01, 0.01)

如你所见,我的操作是errD = -(errD_real – errD_fake),errD_real和errD_fake分别是批判者对真实样本和假样本预测的平均值。

根据我的理解,RMSprop应该按照以下方式优化批判者的权重。

w <- w – alpha*gradient(w)

(α为学习率除以平方梯度的加权移动平均数的平方根)

由于优化问题要求与梯度 “走 “的方向一致,所以应该要求在优化权重之前将梯度(w)乘以-1。

你认为我的推理正确吗?

程序可以运行,但结果很差。

我按照同样的逻辑对生成器的权重进行优化,但这次是为了与梯度的方向相反。

      ############################
  # (2) Update G network: minimize -D(G(x))
  ###########################
  G.zero_grad()

  noise = torch.randn(b_size, 100, device=device)
  fake = G(noise)

  #label.fill_(fake_label)  # fake labels are real for generator cost

  # Since we just updated D, perform another forward pass of all-fake batch through D
  output = D(fake).view(-1)

  # Calculate G's loss based on this output

  #errG = criterion(output, label) #DCGAN
  errG = -torch.mean(output)

  # Calculate gradients for G
  errG.backward()
  D_G_z2 = output.mean().item()

  # Update G
  optimizerG.step()

对不起,问题太长了,我已经尽量把我的疑问解释清楚了。谢谢大家。

解决方案:

我注意到你的判别器训练协议的实现中存在一些错误。你调用了两次你的后向函数,真实值和假值损失都在不同的时间步长进行了后向传播。

从技术上讲,使用这种方案的实现是可能的,但非常不可读。你的 errD_real 在这种情况下,你的输出将是正的而不是负的,因为这是一个最佳的选择。D(G(z))>0 所以你惩罚它的正确性。总的来说,你的模型收敛,只是通过预测 D(x)<0 的所有输入。

要解决这个问题,不要调用你的 errD_readl.backward() 或您的 errD_fake.backward(). 只需使用 errD.backward() 在您定义 errD 会完全正常工作。否则,你的发电机似乎是正确的。

给TA打赏
共{{data.count}}人
人已打赏
未分类

翩翩飞舞的SliverAppBar,折叠背景填充前导空间。

2022-9-8 11:11:34

未分类

PyMC3在PyCharm中的plots.traceplot。

2022-9-8 11:11:36

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索