Performs the discriminator step in computing the GAN loss.

    Applies stop-gradient to the generated frames while computing the
    discriminator loss to make sure that the gradients are not back-propagated
    to the generator. This makes sure that only the discriminator is updated.

    Args:
      true_frames: True outputs
      gen_frames: Generated frames.
    Returns:
      d_loss: Loss component due to the discriminator.

def d_step(self, true_frames, gen_frames):
    """Performs the discriminator step in computing the GAN loss.

    Applies stop-gradient to the generated frames while computing the
    discriminator loss to make sure that the gradients are not back-propagated
    to the generator. This makes sure that only the discriminator is updated.

    Args:
      true_frames: True outputs
      gen_frames: Generated frames.
    Returns:
      d_loss: Loss component due to the discriminator.
    """
    hparam_to_disc_loss = {
        "least_squares": gan_losses.least_squares_discriminator_loss,
        "cross_entropy": gan_losses.modified_discriminator_loss,
        "wasserstein": gan_losses.wasserstein_discriminator_loss}

    # Concat across batch-axis.
    _, batch_size, _, _, _ = common_layers.shape_list(true_frames)
    all_frames = tf.concat(
        [true_frames, tf.stop_gradient(gen_frames)], axis=1)

    all_logits = self.discriminator(all_frames)
    true_logits, fake_logits_stop = \
      all_logits[:batch_size], all_logits[batch_size:]
    mean_true_logits = tf.reduce_mean(true_logits)
    tf.summary.scalar("mean_true_logits", mean_true_logits)

    mean_fake_logits_stop = tf.reduce_mean(fake_logits_stop)
    tf.summary.scalar("mean_fake_logits_stop", mean_fake_logits_stop)

    discriminator_loss_func = hparam_to_disc_loss[self.hparams.gan_loss]
    gan_d_loss = discriminator_loss_func(
        discriminator_real_outputs=true_logits,
        discriminator_gen_outputs=fake_logits_stop,
        add_summaries=True)
    return gan_d_loss, true_logits, fake_logits_stop