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 [2]
  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.
  
  Examples
  --------
  Importing necessary modules
  
  >>> import deepchem as dc
  >>> from deepchem.models.torch_models.gan import GAN
  >>> import torch
  >>> import torch.nn as nn
  >>> import torch.nn.functional as F
  
  Creating a Generator
  
  >>> class Generator(nn.Module):
  ...     def __init__(self, noise_input_shape, conditional_input_shape):
  ...         super(Generator, self).__init__()
  ...         self.noise_input_shape = noise_input_shape
  ...         self.conditional_input_shape = conditional_input_shape
  ...         self.noise_dim = noise_input_shape[1:]
  ...         self.conditional_dim = conditional_input_shape[1:]
  ...         input_dim = sum(self.noise_dim) + sum(self.conditional_dim)
  ...         self.output = nn.Linear(input_dim, 1)
  ...     def forward(self, input):
  ...         noise_input, conditional_input = input
  ...         inputs = torch.cat((noise_input, conditional_input), dim=1)
  ...         output = self.output(inputs)
  ...         return output
  
  Creating a Discriminator
  
  >>> class Discriminator(nn.Module):
  ...     def __init__(self, data_input_shape, conditional_input_shape):
  ...         super(Discriminator, self).__init__()
  ...         self.data_input_shape = data_input_shape
  ...         self.conditional_input_shape = conditional_input_shape
  ...         # Extracting the actual data dimension
  ...         data_dim = data_input_shape[1:]
  ...         # Extracting the actual conditional dimension
  ...         conditional_dim = conditional_input_shape[1:]
  ...         input_dim = sum(data_dim) + sum(conditional_dim)
  ...         # Define the dense layers
  ...         self.dense1 = nn.Linear(input_dim, 10)
  ...         self.dense2 = nn.Linear(10, 1)
  ...     def forward(self, input):
  ...         data_input, conditional_input = input
  ...         # Concatenate data_input and conditional_input along the second dimension
  ...         discrim_in = torch.cat((data_input, conditional_input), dim=1)
  ...         # Pass the concatenated input through the dense layers
  ...         x = F.relu(self.dense1(discrim_in))
  ...         output = torch.sigmoid(self.dense2(x))
  ...         return output
  
  Defining an Example GAN class
  
  >>> class ExampleGANModel(dc.models.torch_models.GANModel):
  ...    def get_noise_input_shape(self):
  ...        return (100,2,)
  ...    def get_data_input_shapes(self):
  ...        return [(100,1,)]
  ...    def get_conditional_input_shapes(self):
  ...        return [(100,1,)]
  ...    def create_generator(self):
  ...        noise_dim = self.get_noise_input_shape()
  ...        conditional_dim = self.get_conditional_input_shapes()[0]
  ...        return nn.Sequential(Generator(noise_dim, conditional_dim))
  ...    def create_discriminator(self):
  ...        data_input_shape = self.get_data_input_shapes()[0]
  ...        conditional_input_shape = self.get_conditional_input_shapes()[0]
  ...        return nn.Sequential(
  ...            Discriminator(data_input_shape, conditional_input_shape))
  
  Defining a function to generate data
  
  >>> def generate_batch(batch_size):
  ...     means = 10 * np.random.random([batch_size, 1])
  ...     values = np.random.normal(means, scale=2.0)
  ...     return means, values
  
  >>> def generate_data(gan, batches, batch_size):
  ...     for _ in range(batches):
  ...         means, values = generate_batch(batch_size)
  ...         batch = {
  ...             gan.data_input_names[0]: values,
  ...             gan.conditional_input_names[0]: means
  ...         }
  ...         yield batch
  
  Defining the GANModel
  
  >>> batch_size = 100
  >>> noise_shape = (batch_size, 2,)
  >>> data_shape = [(batch_size, 1,)]
  >>> conditional_shape = [(batch_size, 1,)]
  >>> gan = ExampleGANModel(learning_rate=0.01)
  >>> data = generate_data(gan, 500, 100)
  >>> gan.fit_gan(data, generator_steps=0.5, checkpoint_interval=0)
  >>> means = 10 * np.random.random([1000, 1])
  >>> values = gan.predict_gan_generator(conditional_inputs=[means])
  
  References
  ----------
  .. [1] Goodfellow, Ian, et al. "Generative adversarial nets." Advances in
       neural information processing systems. 2014.
  
  .. [2] Arora et al., “Generalization and Equilibrium in Generative
       Adversarial Nets (GANs)” (https://arxiv.org/abs/1703.00573)
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","[","2","]","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",".","Examples","--","--","--","--","Importing","necessary","modules",">",">",">","import","deepchem","as","dc",">",">",">","from","deepchem.models.torch_models.gan","import","GAN",">",">",">","import","torch",">",">",">","import","torch.nn","as","nn",">",">",">","import","torch.nn.functional","as","F","Creating","a","Generator",">",">",">","class","Generator","(","nn.Module",")",":","...","def","__init__","(","self",",","noise_input_shape",",","conditional_input_shape",")",":","...","super","(","Generator",",","self",")",".__init__","(",")","...","self.noise_input_shape","=","noise_input_shape","...","self.conditional_input_shape","=","conditional_input_shape","...","self.noise_dim","=","noise_input_shape","[","1",":","]","...","self.conditional_dim","=","conditional_input_shape","[","1",":","]","...","input_dim","=","sum","(","self.noise_dim",")","+","sum","(","self.conditional_dim",")","...","self.output","=","nn.Linear","(","input_dim",",","1",")","...","def","forward","(","self",",","input",")",":","...","noise_input",",","conditional_input","=","input","...","inputs","=","torch.cat","(","(","noise_input",",","conditional_input",")",",","dim=1",")","...","output","=","self.output","(","inputs",")","...","return","output","Creating","a","Discriminator",">",">",">","class","Discriminator","(","nn.Module",")",":","...","def","__init__","(","self",",","data_input_shape",",","conditional_input_shape",")",":","...","super","(","Discriminator",",","self",")",".__init__","(",")","...","self.data_input_shape","=","data_input_shape","...","self.conditional_input_shape","=","conditional_input_shape","...","#","Extracting","the","actual","data","dimension","...","data_dim","=","data_input_shape","[","1",":","]","...","#","Extracting","the","actual","conditional","dimension","...","conditional_dim","=","conditional_input_shape","[","1",":","]","...","input_dim","=","sum","(","data_dim",")","+","sum","(","conditional_dim",")","...","#","Define","the","dense","layers","...","self.dense1","=","nn.Linear","(","input_dim",",","10",")","...","self.dense2","=","nn.Linear","(","10",",","1",")","...","def","forward","(","self",",","input",")",":","...","data_input",",","conditional_input","=","input","...","#","Concatenate","data_input","and","conditional_input","along","the","second","dimension","...","discrim_in","=","torch.cat","(","(","data_input",",","conditional_input",")",",","dim=1",")","...","#","Pass","the","concatenated","input","through","the","dense","layers","...","x","=","F.relu","(","self.dense1","(","discrim_in",")",")","...","output","=","torch.sigmoid","(","self.dense2","(","x",")",")","...","return","output","Defining","an","Example","GAN","class",">",">",">","class","ExampleGANModel","(","dc.models.torch_models.GANModel",")",":","...","def","get_noise_input_shape","(","self",")",":","...","return","(","100,2",",",")","...","def","get_data_input_shapes","(","self",")",":","...","return","[","(","100,1",",",")","]","...","def","get_conditional_input_shapes","(","self",")",":","...","return","[","(","100,1",",",")","]","...","def","create_generator","(","self",")",":","...","noise_dim","=","self.get_noise_input_shape","(",")","...","conditional_dim","=","self.get_conditional_input_shapes","(",")","[","0","]","...","return","nn.Sequential","(","Generator","(","noise_dim",",","conditional_dim",")",")","...","def","create_discriminator","(","self",")",":","...","data_input_shape","=","self.get_data_input_shapes","(",")","[","0","]","...","conditional_input_shape","=","self.get_conditional_input_shapes","(",")","[","0","]","...","return","nn.Sequential","(","...","Discriminator","(","data_input_shape",",","conditional_input_shape",")",")","Defining","a","function","to","generate","data",">",">",">","def","generate_batch","(","batch_size",")",":","...","means","=","10","*","np.random.random","(","[","batch_size",",","1","]",")","...","values","=","np.random.normal","(","means",",","scale=2.0",")","...","return","means",",","values",">",">",">","def","generate_data","(","gan",",","batches",",","batch_size",")",":","...","for","_","in","range","(","batches",")",":","...","means",",","values","=","generate_batch","(","batch_size",")","...","batch","=","{","...","gan.data_input_names","[","0","]",":","values",",","...","gan.conditional_input_names","[","0","]",":","means","...","}","...","yield","batch","Defining","the","GANModel",">",">",">","batch_size","=","100",">",">",">","noise_shape","=","(","batch_size",",","2",",",")",">",">",">","data_shape","=","[","(","batch_size",",","1",",",")","]",">",">",">","conditional_shape","=","[","(","batch_size",",","1",",",")","]",">",">",">","gan","=","ExampleGANModel","(","learning_rate=0.01",")",">",">",">","data","=","generate_data","(","gan",",","500",",","100",")",">",">",">","gan.fit_gan","(","data",",","generator_steps=0.5",",","checkpoint_interval=0",")",">",">",">","means","=","10","*","np.random.random","(","[","1000",",","1","]",")",">",">",">","values","=","gan.predict_gan_generator","(","conditional_inputs=","[","means","]",")","References","--","--","--","--","--","..","[","1","]","Goodfellow",",","Ian",",","et","al",".","``","Generative","adversarial","nets",".","''","Advances","in","neural","information","processing","systems",".","2014",".","..","[","2","]","Arora","et","al.",",","\u201c","Generalization","and","Equilibrium","in","Generative","Adversarial","Nets","(","GANs",")","\u201d","(","https",":","\/\/arxiv.org\/abs\/1703.00573",")"]
docstr: Train this model on data.
  
  Parameters
  ----------
  batches: iterable
      batches of data to train the discriminator on, each represented as a dict
      that maps Inputs to values.  It should specify values for all members of
      data_inputs and conditional_inputs.
  generator_steps: float
      the number of training steps to perform for the generator for each batch.
      This can be used to adjust the ratio of training steps for the generator
      and discriminator.  For example, 2.0 will perform two training steps for
      every batch, while 0.5 will only perform one training step for every two
      batches.
  max_checkpoints_to_keep: int
      the maximum number of checkpoints to keep.  Older checkpoints are discarded.
  checkpoint_interval: int
      the frequency at which to write checkpoints, measured in batches.  Set
      this to 0 to disable automatic checkpointing.
  restore: bool
      if True, restore the model from the most recent checkpoint before training
      it.
docstr_tok: ["Train","this","model","on","data",".","Parameters","--","--","--","--","--","batches",":","iterable","batches","of","data","to","train","the","discriminator","on",",","each","represented","as","a","dict","that","maps","Inputs","to","values",".","It","should","specify","values","for","all","members","of","data_inputs","and","conditional_inputs",".","generator_steps",":","float","the","number","of","training","steps","to","perform","for","the","generator","for","each","batch",".","This","can","be","used","to","adjust","the","ratio","of","training","steps","for","the","generator","and","discriminator",".","For","example",",","2.0","will","perform","two","training","steps","for","every","batch",",","while","0.5","will","only","perform","one","training","step","for","every","two","batches",".","max_checkpoints_to_keep",":","int","the","maximum","number","of","checkpoints","to","keep",".","Older","checkpoints","are","discarded",".","checkpoint_interval",":","int","the","frequency","at","which","to","write","checkpoints",",","measured","in","batches",".","Set","this","to","0","to","disable","automatic","checkpointing",".","restore",":","bool","if","True",",","restore","the","model","from","the","most","recent","checkpoint","before","training","it","."]
code: def fit_gan(
      self,
      batches,
      generator_steps=1,
      max_checkpoints_to_keep=5,
      checkpoint_interval=1000,
      restore=False,
  ) -> None:
      """Train this model on data.
  
      Parameters
      ----------
      batches: iterable
          batches of data to train the discriminator on, each represented as a dict
          that maps Inputs to values.  It should specify values for all members of
          data_inputs and conditional_inputs.
      generator_steps: float
          the number of training steps to perform for the generator for each batch.
          This can be used to adjust the ratio of training steps for the generator
          and discriminator.  For example, 2.0 will perform two training steps for
          every batch, while 0.5 will only perform one training step for every two
          batches.
      max_checkpoints_to_keep: int
          the maximum number of checkpoints to keep.  Older checkpoints are discarded.
      checkpoint_interval: int
          the frequency at which to write checkpoints, measured in batches.  Set
          this to 0 to disable automatic checkpointing.
      restore: bool
          if True, restore the model from the most recent checkpoint before training
          it.
      """
      self._ensure_built()
  
      gen_train_fraction = 0.0
      discrim_error = 0.0
      gen_error = 0.0
      discrim_average_steps = 0
      gen_average_steps = 0
      time1 = time.time()
  
      for feed_dict in batches:
          # Every call to fit_generator() will increment global_step, but we only
          # want it to get incremented once for the entire batch, so record the
          # value and keep resetting it.
  
          global_step = self.get_global_step()
  
          # Train the discriminator.
  
          inputs = [self.get_noise_batch(self.batch_size)]
  
          for input in self.data_input_names:
              inputs.append(feed_dict[input])
          for input in self.conditional_input_names:
              inputs.append(feed_dict[input])
          discrim_error += self.fit_generator(
              [(inputs, [], [])],
              variables=self.discrim_variables,
              loss=self.discrim_loss_fn_wrapper,
              checkpoint_interval=0,
              restore=restore,
          )
          restore = False
          discrim_average_steps += 1
  
          # Train the generator.
  
          if generator_steps > 0.0:
              gen_train_fraction += generator_steps
              while gen_train_fraction >= 1.0:
                  inputs = [
                      self.get_noise_batch(self.batch_size)
                  ] + inputs[1:]
  
                  gen_error += self.fit_generator(
                      [(inputs, [], [])],
                      variables=self.gen_variables,
                      loss=self.gen_loss_fn_wrapper,
                      checkpoint_interval=0,
                  )
                  gen_average_steps += 1
                  gen_train_fraction -= 1.0
          self._global_step = global_step + 1
  
          # Write checkpoints and report progress.
  
          if discrim_average_steps == checkpoint_interval:
              self.save_checkpoint(max_checkpoints_to_keep)
              discrim_loss = discrim_error / max(
                  1, discrim_average_steps
              )
              gen_loss = gen_error / max(1, gen_average_steps)
              print(
                  "Ending global_step %d: generator average loss %g, discriminator average loss %g"
                  % (global_step, gen_loss, discrim_loss)
              )
              discrim_error = 0.0
              gen_error = 0.0
              discrim_average_steps = 0
              gen_average_steps = 0
  
      # Write out final results.
  
      if checkpoint_interval > 0:
          if discrim_average_steps > 0 and gen_average_steps > 0:
              discrim_loss = discrim_error / discrim_average_steps
              gen_loss = gen_error / gen_average_steps
              print(
                  "Ending global_step %d: generator average loss %g, discriminator average loss %g"
                  % (global_step, gen_loss, discrim_loss)
              )
          self.save_checkpoint(max_checkpoints_to_keep)
          time2 = time.time()
          print("TIMING: model fitting took %0.3f s" % (time2 - time1))
  
imports: import numpy
  import time
  from typing import Callable, Any, List, Tuple, Union
  from deepchem.models.torch_models.torch_model import TorchModel
label_desc: Use image node_id 7 for calling the GANModel obj's underlying member method code with example usage: obj.fit_gan(batches, generator_steps, max_checkpoints_to_keep, checkpoint_interval, restore) without return types