A generator is the neural network G in a generative adversarial network (GAN). It maps a latent input z to a synthetic example, such as an image or a point in a toy distribution. Its practical goal is to produce outputs that the discriminator cannot distinguish from real data. GANs use generators for realistic synthetic data, image manipulation, augmentation, and one-to-many problems with multiple valid outputs. section 9.0 section 9.1.2
A generator is trained and shaped through several linked choices:
- Samples a latent vector z, commonly with latent_d dimensions, and transforms it through fully connected layers into the required output shape. section 9.1.3
- Improves from discriminator feedback: the discriminator is trained on real and fake data, while the generator is trained on fake data with the real label. section 9.1.2 section 9.1.3
- Uses a final sigmoid when outputs must match data constrained to [0,1], such as MNIST pixels; otherwise, it can return unbounded activations. section 9.1.3
- Can use WGAN-GP training, whose generator loss is -D(G(z)); the gradient penalty is applied while training the discriminator. section 9.3.2 section 9.3.3
- May suffer mode collapse, producing too few kinds of outputs; WGAN-GP reduces this risk by limiting vanishing gradients and preventing the discriminator from becoming too dominant. section 9.3.3 section 9.9
Minimal PyTorch generator
With latent_d = 128, a fully connected generator can stack three helper layers, project to the product of the target dimensions, reshape with View, and optionally append nn.Sigmoid(). During the discriminator update, pass G(z).detach() so that discriminator gradients do not update G. During the generator update, reuse G(z), compare D(G(z)) with the real label, backpropagate, and call optimizerG.step(). section 9.1.3
Convolutional generator
For 28×28 images, reshape the latent vector into a smaller tensor with 16 latent channels and 7×7 spatial dimensions. Apply convolutional layers, expand spatial size twice with ConvTranspose2d, refine with more convolutions, and finish with a one-channel convolution and sigmoid. section 9.4.1
def simpleGAN(latent_d, neurons, out_shape, sigmoidG=False, leak=0.2):
"""
This function will create a simple GAN for us to train. It will return
a tuple (G, D), holding the generator and discriminator network
respectively.
latent_d: the number of latent variables we will use as input to the
generator G.
neurons: how many hidden neurons to use in each hidden layer
out_shape: the shape of the output of the discriminator D. This should
be the same shape as the real data.
sigmoidG: true if the generator G should end with a sigmoid activation,
or False if it should just return unbounded activations
"""
G = nn.Sequential( fcLayer(latent_d, neurons, leak),
fcLayer(neurons, neurons, leak),
fcLayer(neurons, neurons, leak),
nn.Linear(neurons, abs(np.prod(out_shape)) ), #1
View(out_shape) #2
)
if sigmoidG: #3
G = nn.Sequential(G,
nn.Sigmoid())
D = nn.Sequential( nn.Flatten(),
fcLayer(abs(np.prod(out_shape)), neurons, leak),
fcLayer(neurons, neurons, leak),
fcLayer(neurons, neurons, leak),
nn.Linear(neurons, 1 ) #4
)
return G, D
#1 np.prod multiplies each value in the shape, giving us the total number of needed outputs. abs removes the impact of “–1" for the batch dimension.
#2 Reshapes the output to whatever D expects
#3 Sometimes we do or don’t want G to return a sigmoid value (i.e., [0,1]), so we rap it in a conditional.
#4 D has one output for a binary classification problem.
Inspect the compact simpleGAN definition showing latent input size, hidden layers, output projection, reshaping, and optional sigmoid behavior. section 9.1.3











