Recently I have learned about Generative Adversarial Networks.

For training the Generator, I am somehow confused how it learns. Here is an implemenation of GANs:

`# train generator
            z = Variable(xp.random.uniform(-1, 1, (batchsize, nz), dtype=np.float32))

        x = gen(z)
        yl = dis(x)
        L_gen = F.softmax_cross_entropy(yl, Variable(xp.zeros(batchsize, dtype=np.int32)))
        L_dis = F.softmax_cross_entropy(yl, Variable(xp.ones(batchsize, dtype=np.int32)))

    # train discriminator

    x2 = Variable(cuda.to_gpu(x2))
    yl2 = dis(x2)
    L_dis += F.softmax_cross_entropy(yl2, Variable(xp.zeros(batchsize, dtype=np.int32)))

    #print "forward done"



So it computes a loss for the Generator as it is mentioned in the paper. However, it calls the Generator backward function based on the Discriminator output. The discriminator output is just a number (not an array).

But we know that in general, for training a network, we compute a loss function in the last layer (a loss between the last layers output and the real output) and then we compute the gradients. So for example, if the output is 64*64, then we compare it with a 64*64 image and then compute the loss and do the back propagation.

However, in the codes that I see in Generative Adversarial Networks, I see they compute a loss for the Generator from the discriminator output (which is just a number) and then they call the back propagation for Generator. The Generators last layers is for example 64*64 pixels but the discriminator loss is 1*1 (which is different from the usual networks) So I do not understand how it cause the Generator to be learned and trained?

I thought if we attach the two networks (attaching the Generator and Discriminator) and then call the back propagation but just update the Generators parameters, it makes sense and it should work. But what I see in the codes are totally different.

So I am asking how it is possible?



In the generative adversarial networks, Generator is used for generating 'fake' samples that look very likely to 'real' samples, and Discriminator is to distinguish the differences between 'fake' and 'real' samples. The training process is to train Generator and Discriminator iteratively.

  • Discriminator finds differences between 'fake' and 'real' samples;

  • Generator tries to fool Discriminator by generating most similar samples.

When Discriminator cannot find the differences, Generator can successfully generate 'real' samples.

So in your problem, when training Generator, the Discriminator is fixed and then plays a role as loss function for Generator. This loss function is called adversarial loss.

Formally, I use the notation in the original paper of GAN, the loss function of GAN is given as follows: $$ \min_{G} \max_{D} V(D,G)=\mathbb{E}_{x\sim p_{data}}[\log D(x)] + \mathbb{E}_{z\sim p_{z}(z)}[\log(1-D(G(z)))] $$

  1. Training Discriminator when Generator is fixed, $$ \max_{D} V(D,G^*)=\mathbb{E}_{x\sim p_{data}}[\log D(x)] + \mathbb{E}_{z\sim p_{z}(z)}[\log(1-D(G^*(z)))] $$ where $G^*$ means $G$ is fixed. We can see that optimizing $D$ is to maximzing the difference between 'real' sample $x$ and 'fake' sample $G^*(z)$.

  2. Training Generator when Discriminator is fixed, $$ \min_{G} V(D^*,G)=\mathbb{E}_{x\sim p_{data}}[\log D^*(x)] + \mathbb{E}_{z\sim p_{z}(z)}[\log(1-D^*(G(z)))] $$ where the first term on right hand can be ignored because of constant term for $G$. Above is the loss function for training Generator. The loss function value is computed from fixed Discriminator with 'real' samples $x$ and 'fake' samples $G(z)$.

Hope that's clear to you.

  • $\begingroup$ Thank you very much for your explanation. Now I understand more about the GANs. yet, I am confused on something. I understand how the loss function of G should be obtained. However, my problem is that when discriminators output (so the loss function for generator) is just a number, how the generator calculates the gradients to update its parameters based on just a number? so for example, if the D's output is 0.4, and generator outputs 64*64 images, how do the parameters of 64*64 layer of the generator are updated based on the number 0.4? I hope I have explained my question clearly. tnx :) $\endgroup$ – Kadaj13 Jun 25 '17 at 19:28
  • $\begingroup$ For example, in ususal networks, the output layer is for example 2*2 and the image to compare to obtain the loss is also 2*2. So they obtain a loss for each pixel and then they do the backpropagation. However, here the sizes of loss and last layer of generator is different. So I cannot understand how it will backpropagate ? $\endgroup$ – Kadaj13 Jun 25 '17 at 19:36
  • $\begingroup$ I understand what you want to know. Look at the loss function of updating $G$ (second term on right hand), $D(G(z))$ is actually an entire network including Generator and Discriminator. You can figure out that the input is $z$ and output is $D(G(z))$ in the entire network. When updating Generator, the parameters in Discriminator are fixed, and we are only updating parameters in Generator. In other words, we only update first several layers in the network and don't change the parameters in later layers. $\endgroup$ – Marks Jun 25 '17 at 23:39
  • $\begingroup$ To the backpropogation, it is same to usual networks, propagating loss from Discriminator to Generator. The difference is that Discriminator is only used to calculate gradient, but do not change its parameters. $\endgroup$ – Marks Jun 25 '17 at 23:55
  • $\begingroup$ But by the way, I still do not see in which part of the code they are propagating the loss from Discriminator to Generator? What I see in the code is that they are directly passing the loss to Generator, without using the discriminator between them? $\endgroup$ – Kadaj13 Jun 28 '17 at 6:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.