SinGAN icon indicating copy to clipboard operation
SinGAN copied to clipboard

Why does z_opt change for every epoch

Open shimazing opened this issue 5 years ago • 6 comments

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

shimazing avatar Dec 15 '19 11:12 shimazing

Hello

I have opened issue #43 for the same reason https://github.com/tamarott/SinGAN/issues/43

paulobond avatar Dec 20 '19 11:12 paulobond

Hey guys, What does z_opt mean?

alaeddine-abbagh avatar Jan 04 '20 11:01 alaeddine-abbagh

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.

jacobwjs avatar Apr 07 '20 06:04 jacobwjs

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?

Animadversio avatar Apr 26 '20 04:04 Animadversio

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.

jacobwjs avatar Apr 26 '20 08:04 jacobwjs

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_)

Miaowshroom avatar Nov 03 '20 05:11 Miaowshroom