【CGRGAN复现】

一、 CartoonGAN

成功运行

二、CGRGAN

1. 超参数设置

  1. 预训练去掉
  2. 优化器参数由CartoonGAN的0.0002变为0.00005。

2. 更换损失函数

1.D_real_loss = BCE_loss(D_real, real) 变成 D_real_loss = torch.mean(D_real)
2.D_fake_loss = BCE_loss(D_fake, fake) 变成 D_fake_loss = torch.mean(D_fake)(有两个地方要改,生成器和判别器都有D_fake_loss)
3.D_edge_loss = BCE_loss(D_fake, fake) 变成 D_edge_loss = torch.mean(D_edge)

3. 更换网络结构

  1. 原来的5个堆叠的下-上采用,先变为5个上下采样u-net
    1) 报错,result值大于1.
  File "CartoonGAN123.py", line 300, in <module>
    plt.imsave(path, (result.cpu().numpy().transpose(1, 2, 0) + 1) / 2)
  File "/root/anaconda3/lib/python3.8/site-packages/matplotlib/pyplot.py", line 2412, in imsave
    return matplotlib.image.imsave(fname, arr, **kwargs)
  File "/root/anaconda3/lib/python3.8/site-packages/matplotlib/image.py", line 1582, in imsave
    rgba = sm.to_rgba(arr, bytes=True)
  File "/root/anaconda3/lib/python3.8/site-packages/matplotlib/cm.py", line 341, in to_rgba
    raise ValueError("Floating point image RGB values "
ValueError: Floating point image RGB values must be in the 0..1 range.

找一下是哪里出错了,print出最后几行的结果,看一下几个结果的最大rgb值,:

x = x.to(device)
G_recon = G(x)
print('x123.shape: ', x.shape)      # torch.Size([8, 3, 256, 256])
print('x.type: ', type(x))      # <class 'torch.Tensor'>
print('x: ', x)      # x很多都是负数,[-1,1]之间
print('G123.shape: ', G_recon.shape)     # torch.Size([8, 3, 256, 256])
print('G_recon.type: ', type(G_recon))      # <class 'torch.Tensor'>
print('G: ', G_recon)      # G_recon很多都是正数,[-1,1]之间
result = torch.cat((x[0], G_recon[0]), 2)
print('result123.shape: ', result.shape)     # torch.Size([3, 256, 512])
print('result123.type: ', type(result))      # <class 'torch.Tensor'>
print('result123: ', result)      # result值的正负都差不多,[-1,1]之间
print('result456: ', (result.cpu().numpy().transpose(1, 2, 0) + 1) / 2)      # result值的正负都差不多,[-1,1]之间
result2 = (result.cpu().numpy().transpose(1, 2, 0) + 1) / 2
print('x.numpy()max: ', np.max(x.cpu().numpy()))    # x.numpy()max:  1.0
print('G_recon.numpy()max: ', np.max(G_recon.cpu().numpy()))    # G_recon.numpy()max:  7.8504043
print('result2max: ', np.max(result2))    # result2max:  2.7570002

发现原来是生成器的输出G_recon = G(x)的值RGB最大值超过1了。应该是networks里面生成器的输出有问题,不知道怎么解决,先简单粗暴归一化吧。
解决:G_recon = torch.nn.functional.normalize(G_recon, dim=2),可以运行了。
3. 优化器把原来的Adam改了,改为WGAN中的RMSprop训练。没有报错。

4.继续改损失函数

  1. 把D_edge_loss变成D_inter_loss。ok没有报错。
  2. 开始改G的loss。L = L_part + 10L_con
    1)L_con不用变。
    2)L_part = 10
    L_sty + 1L_adv + 0.0000001L_tv,要变三个,先变第一个。
    1.1 让L_part = 1L_adv。ok没有报错。
    1.2 让L_part = 10
    L_sty + 1*L_adv。报错:
RuntimeError: Trying to backward through the graph a second time (or directly access saved variables after they have already been freed). Saved intermediate values of the graph are freed when you call .backward() or autograd.grad(). Specify retain_graph=True if you need to backward through the graph a second time or if you need to access saved variables after calling backward.

应该是重复用了某一个参数。
这里,因为sty和con都用到了G_feature,所以把G_feature输到了两个损失里,估计是这个问题。试着把sty用的G_feature换成来自另外一个VGG网络的输出。果然就 不报错了。
1.3 让L_part = 10L_sty + 1L_adv + 0.0000001*L_tv。报错:

TypeError: unsupported operand type(s) for *: 'float' and 'TVLoss'

应该是三个损失的类型不一样,分别print出来。

adv_loss.type:  <class 'torch.Tensor'>
sty_loss.type:  <class 'torch.Tensor'>
tv_loss.type:  <class 'utils.TVLoss'>

网络上找的TVLoss的代码不行,输出的数据类型不对。换一个代码。ok,没有报错了。
3. 把原本print出G的两个损失函数,改为现在新的三个损失函数。

5.结束

  1. 到此,基本复现完成。
    还存在以下问题:1)网络结构原文中是8个上下采样,现在只用了5个上下采样。
    2)D的loss,x的插值损失中原文公式里有一个求和符号,现在的代码没有体现出来。
    3)G的loss,L_sty原文是第1-1、2-1、3-1、4-1、5-1的输出融合起来,现在的代码只用了第2-1的。
  2. 从结果来看,有以下几个问题:1)判别器D的Loss非常小,-50、-60这样;2)生成器G的Loss不收敛,一直都是12、13。

猜你喜欢

转载自blog.csdn.net/everyxing1007/article/details/123895840