class_docstr: Deep Tensor Neural Networks
  
  DTNN is based on the many-body Hamiltonian concept, which is a fundamental principle in quantum mechanics.
  The DTNN recieves a molecule's distance matrix and membership of its atom from its Coulomb Matrix representation.
  Then, it iteratively refines the representation of each atom by considering its interactions with neighboring atoms.
  Finally, it predicts the energy of the molecule by summing up the energies of the individual atoms.
  
  In this class, we establish a sequential model for the Deep Tensor Neural Network (DTNN) [1]_.
  
  Examples
  --------
  >>> import os
  >>> import torch
  >>> from deepchem.models.torch_models import DTNN
  >>> from deepchem.data import SDFLoader
  >>> from deepchem.feat import CoulombMatrix
  >>> from deepchem.utils import batch_coulomb_matrix_features
  >>> # Get Data
  >>> model_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
  >>> dataset_file = os.path.join(model_dir, 'tests/assets/qm9_mini.sdf')
  >>> TASKS = ["alpha", "homo"]
  >>> loader = SDFLoader(tasks=TASKS, featurizer=CoulombMatrix(29), sanitize=True)
  >>> data = loader.create_dataset(dataset_file, shard_size=100)
  >>> inputs = batch_coulomb_matrix_features(data.X)
  >>> atom_number, distance, atom_membership, distance_membership_i, distance_membership_j = inputs
  >>> inputs = [torch.tensor(atom_number).to(torch.int64),
  ...           torch.tensor(distance).to(torch.float32),
  ...           torch.tensor(atom_membership).to(torch.int64),
  ...           torch.tensor(distance_membership_i).to(torch.int64),
  ...           torch.tensor(distance_membership_j).to(torch.int64)]
  >>> n_tasks = data.y.shape[0]
  >>> model = DTNN(n_tasks)
  >>> pred = model(inputs)
  
  References
  ----------
  .. [1] Schütt, Kristof T., et al. "Quantum-chemical insights from deep
      tensor neural networks." Nature communications 8.1 (2017): 1-8.
docstr: Parameters
  ----------
  inputs: List
      A list of tensors containing atom_number, distance,
      atom_membership, distance_membership_i, and distance_membership_j.
  
  Returns
  -------
  output: torch.Tensor
      Predictions of the Molecular Energy.
docstr_tok: ["Parameters","--","--","--","--","--","inputs",":","List","A","list","of","tensors","containing","atom_number",",","distance",",","atom_membership",",","distance_membership_i",",","and","distance_membership_j",".","Returns","--","--","--","-","output",":","torch.Tensor","Predictions","of","the","Molecular","Energy","."]
code: def forward(self, inputs: List[torch.Tensor]):
      """
      Parameters
      ----------
      inputs: List
          A list of tensors containing atom_number, distance,
          atom_membership, distance_membership_i, and distance_membership_j.
  
      Returns
      -------
      output: torch.Tensor
          Predictions of the Molecular Energy.
  
      """
      dtnn_embedding = self.dtnn_embedding(inputs[0])
  
      for i in range(self.n_steps):
          dtnn_embedding = nn.Dropout(self.dropout)(dtnn_embedding)
          dtnn_embedding = self.dtnn_step[i](
              [dtnn_embedding, inputs[1], inputs[3], inputs[4]]
          )
  
      dtnn_step = nn.Dropout(self.dropout)(dtnn_embedding)
      dtnn_gather = self.dtnn_gather([dtnn_step, inputs[2]])
  
      dtnn_gather = nn.Dropout(self.dropout)(dtnn_gather)
      output = self.linear(dtnn_gather)
      return output
  
file_path: deepchem/deepchem/models/torch_models/dtnn.py
imports: from typing import List
  import torch.nn
  import torch
  from deepchem.models.losses import L2Loss
  from deepchem.models.torch_models import layers
  from deepchem.models.torch_models import TorchModel
  from deepchem.data.datasets import Dataset
  from deepchem.utils import batch_coulomb_matrix_features
label_desc: Use image node_id 2 for calling the DTNN obj's underlying member method code with example usage: obj.forward(inputs) and returns: output