class_docstr: Builder class for 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.
  
  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 ExampleGAN(dc.models.torch_models.GAN):
  ...    def get_noise_input_shape(self):
  ...        return (16,2,)
  ...    def get_data_input_shapes(self):
  ...        return [(16,1,)]
  ...    def get_conditional_input_shapes(self):
  ...        return [(16,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 the GAN
  
  >>> batch_size = 16
  >>> noise_shape = (batch_size, 2,)
  >>> data_shape = [(batch_size, 1,)]
  >>> conditional_shape = [(batch_size, 1,)]
  >>> def create_generator(noise_dim, conditional_dim):
  ...     noise_dim = noise_dim
  ...     conditional_dim = conditional_dim[0]
  ...     return nn.Sequential(Generator(noise_dim, conditional_dim))
  >>> def create_discriminator(data_input_shape, conditional_input_shape):
  ...     data_input_shape = data_input_shape[0]
  ...     conditional_input_shape = conditional_input_shape[0]
  ...     return nn.Sequential(
  ...         Discriminator(data_input_shape, conditional_input_shape))
  >>> gan = ExampleGAN(noise_shape, data_shape, conditional_shape,
  ...                  create_generator(noise_shape, conditional_shape),
  ...                  create_discriminator(data_shape, conditional_shape))
  >>> noise = torch.rand(*gan.noise_input_shape)
  >>> real_data = torch.rand(*gan.data_input_shape[0])
  >>> conditional = torch.rand(*gan.conditional_input_shape[0])
  >>> gen_loss, disc_loss = gan([noise, real_data, conditional])
  
  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)
  
  Notes
  -----
  This class is a subclass of TorchModel.  It accepts all the keyword arguments
  from TorchModel.
class_docstr_tok: ["Builder","class","for","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",".","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","ExampleGAN","(","dc.models.torch_models.GAN",")",":","...","def","get_noise_input_shape","(","self",")",":","...","return","(","16,2",",",")","...","def","get_data_input_shapes","(","self",")",":","...","return","[","(","16,1",",",")","]","...","def","get_conditional_input_shapes","(","self",")",":","...","return","[","(","16,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","the","GAN",">",">",">","batch_size","=","16",">",">",">","noise_shape","=","(","batch_size",",","2",",",")",">",">",">","data_shape","=","[","(","batch_size",",","1",",",")","]",">",">",">","conditional_shape","=","[","(","batch_size",",","1",",",")","]",">",">",">","def","create_generator","(","noise_dim",",","conditional_dim",")",":","...","noise_dim","=","noise_dim","...","conditional_dim","=","conditional_dim","[","0","]","...","return","nn.Sequential","(","Generator","(","noise_dim",",","conditional_dim",")",")",">",">",">","def","create_discriminator","(","data_input_shape",",","conditional_input_shape",")",":","...","data_input_shape","=","data_input_shape","[","0","]","...","conditional_input_shape","=","conditional_input_shape","[","0","]","...","return","nn.Sequential","(","...","Discriminator","(","data_input_shape",",","conditional_input_shape",")",")",">",">",">","gan","=","ExampleGAN","(","noise_shape",",","data_shape",",","conditional_shape",",","...","create_generator","(","noise_shape",",","conditional_shape",")",",","...","create_discriminator","(","data_shape",",","conditional_shape",")",")",">",">",">","noise","=","torch.rand","(","*","gan.noise_input_shape",")",">",">",">","real_data","=","torch.rand","(","*","gan.data_input_shape","[","0","]",")",">",">",">","conditional","=","torch.rand","(","*","gan.conditional_input_shape","[","0","]",")",">",">",">","gen_loss",",","disc_loss","=","gan","(","[","noise",",","real_data",",","conditional","]",")","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",")","Notes","--","--","-","This","class","is","a","subclass","of","TorchModel",".","It","accepts","all","the","keyword","arguments","from","TorchModel","."]
docstr: Construct a GAN.
  
  In addition to the parameters listed below, this class accepts all the
  keyword arguments from KerasModel.
  
  Parameters
  ----------
  noise_input_shape: tuple
      the shape of the noise input to the generator.  The first dimension
      (corresponding to the batch size) should be omitted.
  data_input_shape: list of tuple
      the shapes of the inputs to the discriminator.  The first dimension
      (corresponding to the batch size) should be omitted.
  conditional_input_shape: list of tuple
      the shapes of the conditional inputs to the generator and discriminator.
      The first dimension (corresponding to the batch size) should be omitted.
      If there are no conditional inputs, this should be an empty list.
  generator_fn: Callable
      a function that returns a generator.  It will be called with no arguments.
      The returned value should be a nn.Module whose input is a list
      containing 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.
  discriminator_fn: Callable
      a function that returns a discriminator.  It will be called with no
      arguments.  The returned value should be a nn.Module whose input is a
      list containing a batch of data, followed by any conditional inputs.  Its
      output should be a one dimensional tensor containing the probability of
      each sample being a training sample.
  n_generators: int
      the number of generators to include
  n_discriminators: int
      the number of discriminators to include
docstr_tok: ["Construct","a","GAN",".","In","addition","to","the","parameters","listed","below",",","this","class","accepts","all","the","keyword","arguments","from","KerasModel",".","Parameters","--","--","--","--","--","noise_input_shape",":","tuple","the","shape","of","the","noise","input","to","the","generator",".","The","first","dimension","(","corresponding","to","the","batch","size",")","should","be","omitted",".","data_input_shape",":","list","of","tuple","the","shapes","of","the","inputs","to","the","discriminator",".","The","first","dimension","(","corresponding","to","the","batch","size",")","should","be","omitted",".","conditional_input_shape",":","list","of","tuple","the","shapes","of","the","conditional","inputs","to","the","generator","and","discriminator",".","The","first","dimension","(","corresponding","to","the","batch","size",")","should","be","omitted",".","If","there","are","no","conditional","inputs",",","this","should","be","an","empty","list",".","generator_fn",":","Callable","a","function","that","returns","a","generator",".","It","will","be","called","with","no","arguments",".","The","returned","value","should","be","a","nn.Module","whose","input","is","a","list","containing","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",".","discriminator_fn",":","Callable","a","function","that","returns","a","discriminator",".","It","will","be","called","with","no","arguments",".","The","returned","value","should","be","a","nn.Module","whose","input","is","a","list","containing","a","batch","of","data",",","followed","by","any","conditional","inputs",".","Its","output","should","be","a","one","dimensional","tensor","containing","the","probability","of","each","sample","being","a","training","sample",".","n_generators",":","int","the","number","of","generators","to","include","n_discriminators",":","int","the","number","of","discriminators","to","include"]
code: def __init__(
      self,
      noise_input_shape: tuple,
      data_input_shape: list,
      conditional_input_shape: list,
      generator_fn: Callable,
      discriminator_fn: Callable,
      n_generators: int = 1,
      n_discriminators: int = 1,
  ):
      """Construct a GAN.
  
      In addition to the parameters listed below, this class accepts all the
      keyword arguments from KerasModel.
  
      Parameters
      ----------
      noise_input_shape: tuple
          the shape of the noise input to the generator.  The first dimension
          (corresponding to the batch size) should be omitted.
      data_input_shape: list of tuple
          the shapes of the inputs to the discriminator.  The first dimension
          (corresponding to the batch size) should be omitted.
      conditional_input_shape: list of tuple
          the shapes of the conditional inputs to the generator and discriminator.
          The first dimension (corresponding to the batch size) should be omitted.
          If there are no conditional inputs, this should be an empty list.
      generator_fn: Callable
          a function that returns a generator.  It will be called with no arguments.
          The returned value should be a nn.Module whose input is a list
          containing 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.
      discriminator_fn: Callable
          a function that returns a discriminator.  It will be called with no
          arguments.  The returned value should be a nn.Module whose input is a
          list containing a batch of data, followed by any conditional inputs.  Its
          output should be a one dimensional tensor containing the probability of
          each sample being a training sample.
      n_generators: int
          the number of generators to include
      n_discriminators: int
          the number of discriminators to include
      """
      super(GAN, self).__init__()
      self.n_generators = n_generators
      self.n_discriminators = n_discriminators
      self.noise_input_shape = noise_input_shape
      self.data_input_shape = data_input_shape
      self.conditional_input_shape = conditional_input_shape
      self.create_generator = generator_fn
      self.create_discriminator = discriminator_fn
  
      # Inputs
      # Noise Input
      self.noise_input = nn.Parameter(
          torch.empty(self.noise_input_shape)
      )
      # Data Input
      self.data_inputs = [
          nn.Parameter(torch.ones(s)) for s in self.data_input_shape
      ]
      # Data Input Name
      self.data_input_names = [
          "data_input_%d" % i for i in range(len(self.data_inputs))
      ]
  
      # Conditional Input
      self.conditional_inputs = [
          nn.Parameter(torch.empty(s))
          for s in self.conditional_input_shape
      ]
      # Conditional Input Name
      self.conditional_input_names = [
          "conditional_input_%d" % i
          for i in range(len(self.conditional_inputs))
      ]
  
      self.data_input_layers = []
      for idx, shape in enumerate(self.data_input_shape):
          self.data_input_layers.append(
              nn.Parameter(torch.empty(shape))
          )
      self.conditional_input_layers = []
      for idx, shape in enumerate(self.conditional_input_shape):
          self.conditional_input_layers.append(
              nn.Parameter(torch.empty(shape))
          )
  
      # Generators
      self.generators = nn.ModuleList()
      self.gen_variables = nn.ParameterList()
      for i in range(n_generators):
          generator = self.create_generator()
          self.generators.append(generator)
          self.gen_variables += list(generator.parameters())
  
      # Discriminators
      self.discriminators = nn.ModuleList()
      self.discrim_variables = nn.ParameterList()
  
      for i in range(n_discriminators):
          discriminator = self.create_discriminator()
          self.discriminators.append(discriminator)
          self.discrim_variables += list(discriminator.parameters())
  
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 1 to create a new GAN object from inherited base classes: nn with example: obj = GAN(noise_input_shape, data_input_shape, conditional_input_shape, generator_fn, discriminator_fn, n_generators, n_discriminators)