code: def discriminator(self, x, is_training, reuse=False):
      
      hparams = self.hparams
      with tf.variable_scope(
          "discriminator", reuse=reuse,
          initializer=tf.random_normal_initializer(stddev=0.02)):
        batch_size, height, width = common_layers.shape_list(x)[:3]
        # Mapping x from [bs, h, w, c] to [bs, 1]
        net = tf.layers.conv2d(x, 64, (4, 4), strides=(2, 2),
                               padding="SAME", name="d_conv1")
        # [bs, h/2, w/2, 64]
        net = lrelu(net)
        net = tf.layers.conv2d(net, 128, (4, 4), strides=(2, 2),
                               padding="SAME", name="d_conv2")
        # [bs, h/4, w/4, 128]
        if hparams.discriminator_batchnorm:
          net = tf.layers.batch_normalization(net, training=is_training,
                                              momentum=0.999, name="d_bn2")
        net = lrelu(net)
        size = height * width
        net = tf.reshape(net, [batch_size, size * 8])  # [bs, h * w * 8]
        net = tf.layers.dense(net, 1024, name="d_fc3")  # [bs, 1024]
        if hparams.discriminator_batchnorm:
          net = tf.layers.batch_normalization(net, training=is_training,
                                              momentum=0.999, name="d_bn3")
        net = lrelu(net)
        return net
docs: Discriminator architecture based on InfoGAN.
  
      Args:
        x: input images, shape [bs, h, w, channels]
        is_training: boolean, are we in train or eval model.
        reuse: boolean, should params be re-used.
  
      Returns:
        out_logit: the output logits (before sigmoid).