class_docstr: Implements Generative Adversarial Networks.
  
  A Generative Adversarial Network (GAN) is a type of generative model.  It
  consists of two parts called the "generator" and the "discriminator".  The
  generator takes random noise as input and transforms it into an output that
  (hopefully) resembles the training data.  The discriminator takes a set of
  samples as input and tries to distinguish the real training samples from the
  ones created by the generator.  Both of them are trained together.  The
  discriminator tries to get better and better at telling real from false data,
  while the generator tries to get better and better at fooling the discriminator.
  
  In many cases there also are additional inputs to the generator and
  discriminator.  In that case it is known as a Conditional GAN (CGAN), since it
  learns a distribution that is conditional on the values of those inputs.  They
  are referred to as "conditional inputs".
  
  Many variations on this idea have been proposed, and new varieties of GANs are
  constantly being proposed.  This class tries to make it very easy to implement
  straightforward GANs of the most conventional types.  At the same time, it
  tries to be flexible enough that it can be used to implement many (but
  certainly not all) variations on the concept.
  
  To define a GAN, you must create a subclass that provides implementations of
  the following methods:
  
  get_noise_input_shape()
  get_data_input_shapes()
  create_generator()
  create_discriminator()
  
  If you want your GAN to have any conditional inputs you must also implement:
  
  get_conditional_input_shapes()
  
  The following methods have default implementations that are suitable for most
  conventional GANs.  You can override them if you want to customize their
  behavior:
  
  create_generator_loss()
  create_discriminator_loss()
  get_noise_batch()
  
  This class allows a GAN to have multiple generators and discriminators, a model
  known as MIX+GAN.  It is described in Arora et al., "Generalization and
  Equilibrium in Generative Adversarial Nets (GANs)" (https://arxiv.org/abs/1703.00573).
  This can lead to better models, and is especially useful for reducing mode
  collapse, since different generators can learn different parts of the
  distribution.  To use this technique, simply specify the number of generators
  and discriminators when calling the constructor.  You can then tell
  predict_gan_generator() which generator to use for predicting samples.
class_docstr_tok: ["Implements","Generative","Adversarial","Networks",".","A","Generative","Adversarial","Network","(","GAN",")","is","a","type","of","generative","model",".","It","consists","of","two","parts","called","the","``","generator","''","and","the","``","discriminator","''",".","The","generator","takes","random","noise","as","input","and","transforms","it","into","an","output","that","(","hopefully",")","resembles","the","training","data",".","The","discriminator","takes","a","set","of","samples","as","input","and","tries","to","distinguish","the","real","training","samples","from","the","ones","created","by","the","generator",".","Both","of","them","are","trained","together",".","The","discriminator","tries","to","get","better","and","better","at","telling","real","from","false","data",",","while","the","generator","tries","to","get","better","and","better","at","fooling","the","discriminator",".","In","many","cases","there","also","are","additional","inputs","to","the","generator","and","discriminator",".","In","that","case","it","is","known","as","a","Conditional","GAN","(","CGAN",")",",","since","it","learns","a","distribution","that","is","conditional","on","the","values","of","those","inputs",".","They","are","referred","to","as","``","conditional","inputs","''",".","Many","variations","on","this","idea","have","been","proposed",",","and","new","varieties","of","GANs","are","constantly","being","proposed",".","This","class","tries","to","make","it","very","easy","to","implement","straightforward","GANs","of","the","most","conventional","types",".","At","the","same","time",",","it","tries","to","be","flexible","enough","that","it","can","be","used","to","implement","many","(","but","certainly","not","all",")","variations","on","the","concept",".","To","define","a","GAN",",","you","must","create","a","subclass","that","provides","implementations","of","the","following","methods",":","get_noise_input_shape","(",")","get_data_input_shapes","(",")","create_generator","(",")","create_discriminator","(",")","If","you","want","your","GAN","to","have","any","conditional","inputs","you","must","also","implement",":","get_conditional_input_shapes","(",")","The","following","methods","have","default","implementations","that","are","suitable","for","most","conventional","GANs",".","You","can","override","them","if","you","want","to","customize","their","behavior",":","create_generator_loss","(",")","create_discriminator_loss","(",")","get_noise_batch","(",")","This","class","allows","a","GAN","to","have","multiple","generators","and","discriminators",",","a","model","known","as","MIX+GAN",".","It","is","described","in","Arora","et","al.",",","``","Generalization","and","Equilibrium","in","Generative","Adversarial","Nets","(","GANs",")","''","(","https",":","\/\/arxiv.org\/abs\/1703.00573",")",".","This","can","lead","to","better","models",",","and","is","especially","useful","for","reducing","mode","collapse",",","since","different","generators","can","learn","different","parts","of","the","distribution",".","To","use","this","technique",",","simply","specify","the","number","of","generators","and","discriminators","when","calling","the","constructor",".","You","can","then","tell","predict_gan_generator","(",")","which","generator","to","use","for","predicting","samples","."]
docstr: Create and return a generator.
  
  Subclasses must override this to construct the generator.  The returned
  value should be a tf.keras.Model whose inputs are a batch of noise, followed
  by any conditional inputs.  The number and shapes of its outputs must match
  the return value from get_data_input_shapes(), since generated data must
  have the same form as training data.
docstr_tok: ["Create","and","return","a","generator",".","Subclasses","must","override","this","to","construct","the","generator",".","The","returned","value","should","be","a","tf.keras.Model","whose","inputs","are","a","batch","of","noise",",","followed","by","any","conditional","inputs",".","The","number","and","shapes","of","its","outputs","must","match","the","return","value","from","get_data_input_shapes","(",")",",","since","generated","data","must","have","the","same","form","as","training","data","."]
code: def create_generator(self):
      """Create and return a generator.
  
      Subclasses must override this to construct the generator.  The returned
      value should be a tf.keras.Model whose inputs are a batch of noise, followed
      by any conditional inputs.  The number and shapes of its outputs must match
      the return value from get_data_input_shapes(), since generated data must
      have the same form as training data.
      """
      raise NotImplementedError("Subclasses must implement this.")
  
imports: from deepchem.models import KerasModel, layers
  from tensorflow.keras.layers import Input, Lambda, Layer, Softmax, Reshape, Multiply
  import numpy
  import tensorflow
  import time
label_desc: Use image node_id 7 for calling the GAN obj's underlying member method code with example usage: obj.create_generator() without return types