class_docstr: ### Description
  Generic Generative Adversarial Network
  
  ### Diagram
  
  RANDOM NOISE --> [GENERATOR] --> [DISCRIMINATOR] --> fake logits
  TRAINING SET ------------------> [DISCRIMINATOR] --> real logits
  
  ### Constraints
class_docstr_tok: ["#","#","#","Description","Generic","Generative","Adversarial","Network","#","#","#","Diagram","RANDOM","NOISE","--",">","[","GENERATOR","]","--",">","[","DISCRIMINATOR","]","--",">","fake","logits","TRAINING","SET","--","--","--","--","--","--","--","--","--",">","[","DISCRIMINATOR","]","--",">","real","logits","#","#","#","Constraints"]
code: def layer_op(self, random_source, population, is_training):
      image = self._generator(
          random_source, population.shape.as_list()[1:], is_training
      )
      fake_logits = self._discriminator(image, is_training)
      real_logits = self._discriminator(population / 2, is_training)
      diff = image - population / 2
      # logging.image3_axial('fake',(image+1)*127,1,[logging.LOG])
      # logging.image3_axial('real',tf.maximum(0.,tf.minimum(255.,(population/2+1)*127)),1,[logging.LOG])
      return image, real_logits, fake_logits, diff
  
file_path: NiftyNet/niftynet/network/simple_gan.py
imports: from __future__ import absolute_import, print_function
  import tensorflow
  import numpy
  from niftynet.layer.base_layer import TrainableLayer
label_desc: Use image node_id 2 for calling the GenericGAN obj's underlying member method code with example usage: obj.layer_op(random_source, population, is_training) and returns: image,  real_logits,  fake_logits,  diff