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: Invoke the discriminator on a set of inputs.
  
  This is a separate method so WGAN can override it and also return the
  gradient penalty.
  
  Parameters
  ----------
  discriminator: nn.Module
      the discriminator to invoke
  inputs: list of Tensor
      the inputs to the discriminator.  The first element must be a batch of
      data, followed by any conditional inputs.
  train: bool
      if True, the discriminator should be invoked in training mode. If False,
      it should be invoked in inference mode.
  
  Returns
  -------
  the output from the discriminator
docstr_tok: ["Invoke","the","discriminator","on","a","set","of","inputs",".","This","is","a","separate","method","so","WGAN","can","override","it","and","also","return","the","gradient","penalty",".","Parameters","--","--","--","--","--","discriminator",":","nn.Module","the","discriminator","to","invoke","inputs",":","list","of","Tensor","the","inputs","to","the","discriminator",".","The","first","element","must","be","a","batch","of","data",",","followed","by","any","conditional","inputs",".","train",":","bool","if","True",",","the","discriminator","should","be","invoked","in","training","mode",".","If","False",",","it","should","be","invoked","in","inference","mode",".","Returns","--","--","--","-","the","output","from","the","discriminator"]
code: def _call_discriminator(
      self, discriminator: nn.Module, inputs: List, train: bool
  ):
      """Invoke the discriminator on a set of inputs.
  
      This is a separate method so WGAN can override it and also return the
      gradient penalty.
  
      Parameters
      ----------
      discriminator: nn.Module
          the discriminator to invoke
      inputs: list of Tensor
          the inputs to the discriminator.  The first element must be a batch of
          data, followed by any conditional inputs.
      train: bool
          if True, the discriminator should be invoked in training mode. If False,
          it should be invoked in inference mode.
  
      Returns
      -------
      the output from the discriminator
      """
      return discriminator(
          _list_or_tensor(inputs + self.conditional_input_layers)
      )
  
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 3 for calling the GAN obj's underlying member method code with example usage: obj._call_discriminator(discriminator, inputs, train) and returns: discriminator