SinGAN
SinGAN copied to clipboard
Why does z_opt change for every epoch
Hello, Thanks for the interesting paper and codes.
I have a question.
https://github.com/tamarott/SinGAN/blob/master/SinGAN/training.py#L97 Here, it seems that 'z_opt' of the 1st level changes for every epoch. However, as I understood, it should be fixed. if i am wrong please correct me
Thanks
Hello
I have opened issue #43 for the same reason https://github.com/tamarott/SinGAN/issues/43
Hey guys, What does z_opt mean?
Just looked at the code again. I was off on my previous comment. It does look like 'z_opt' remains fixed, but only after the coarsest scale is trained. Again this is based on various conditions, and what is written in the paper and what happens in code can easily be misconstrued.
I have the same concern. Actually this practice reminds me of how people train VAE. Maybe the author fear the Discriminator is too weak at this moment, so better use VAE loss to give more comprehensive training signal? Usually, the image reconstruction in the coarsest level looks pretty blurry... I'm not sure if it's because they used this kind of VAE loss?
Not sure I follow the VAE loss argument. There is no learnable distribution, just random draws of a standard normal.
Just to add more to this topic, I implemented it in TF 2.x and trained with both a fixed and continuous sampling (as is done here) in the coarsest scale and noticed no perceptual (human) difference. Perhaps there are use cases where this is not true, but I didn't find it in my quick and dirty experiments.
z_opt is the anchor noise at the current scale generator-discriminator pair.
For the upper scales, z_opt is zero as reported in the paper.
However, I think there is a mistake for the coarse layer there is an implementation error at this part:
fixed_noise = functions.generate_noise([opt.nc_z,opt.nzx,opt.nzy],device=opt.device)
z_opt = torch.full(fixed_noise.shape, 0, device=opt.device)
z_opt = m_noise(z_opt)
# setup optimizer
........
for epoch in range(opt.niter):
if (Gs == []) & (opt.mode != 'SR_train'):
z_opt = functions.generate_noise([1,opt.nzx,opt.nzy], device=opt.device) # this shall be =fixed_noise
z_opt = m_noise(z_opt.expand(1,3,opt.nzx,opt.nzy))
noise_ = functions.generate_noise([1,opt.nzx,opt.nzy], device=opt.device)
noise_ = m_noise(noise_.expand(1,3,opt.nzx,opt.nzy))
else:
noise_ = functions.generate_noise([opt.nc_z,opt.nzx,opt.nzy], device=opt.device)
noise_ = m_noise(noise_)
It shall be:
fixed_noise = functions.generate_noise([opt.nc_z,opt.nzx,opt.nzy],device=opt.device)
if (Gs == []) & (opt.mode != 'SR_train'):
z_opt = fixed_noise
else:
z_opt = torch.full(fixed_noise.shape, 0, device=opt.device)
z_opt = m_noise(z_opt)
# setup optimizer
........
for epoch in range(opt.niter):
noise_ = functions.generate_noise([opt.nc_z,opt.nzx,opt.nzy], device=opt.device)
noise_ = m_noise(noise_)