class_docstr: Given an input shaped like `(batch_size, time_steps, [rest])` and a `Module` that takes
  inputs like `(batch_size, [rest])`, `TimeDistributed` reshapes the input to be
  `(batch_size * time_steps, [rest])`, applies the contained `Module`, then reshapes it back.
  
  Note that while the above gives shapes with `batch_size` first, this `Module` also works if
  `batch_size` is second - we always just combine the first two dimensions, then split them.
  
  It also reshapes keyword arguments unless they are not tensors or their name is specified in
  the optional `pass_through` iterable.
class_docstr_tok: ["Given","an","input","shaped","like","`","(","batch_size",",","time_steps",",","[","rest","]",")","`","and","a","`","Module","`","that","takes","inputs","like","`","(","batch_size",",","[","rest","]",")","`",",","`","TimeDistributed","`","reshapes","the","input","to","be","`","(","batch_size","*","time_steps",",","[","rest","]",")","`",",","applies","the","contained","`","Module","`",",","then","reshapes","it","back",".","Note","that","while","the","above","gives","shapes","with","`","batch_size","`","first",",","this","`","Module","`","also","works","if","`","batch_size","`","is","second","-","we","always","just","combine","the","first","two","dimensions",",","then","split","them",".","It","also","reshapes","keyword","arguments","unless","they","are","not","tensors","or","their","name","is","specified","in","the","optional","`","pass_through","`","iterable","."]
code: def forward(self, *inputs, pass_through: List[str] = None, **kwargs):
      pass_through = pass_through or []
  
      reshaped_inputs = [
          self._reshape_tensor(input_tensor) for input_tensor in inputs
      ]
  
      # Need some input to then get the batch_size and time_steps.
      some_input = None
      if inputs:
          some_input = inputs[-1]
  
      reshaped_kwargs = {}
      for key, value in kwargs.items():
          if (
              isinstance(value, torch.Tensor)
              and key not in pass_through
          ):
              if some_input is None:
                  some_input = value
  
              value = self._reshape_tensor(value)
  
          reshaped_kwargs[key] = value
  
      reshaped_outputs = self._module(
          *reshaped_inputs, **reshaped_kwargs
      )
  
      if some_input is None:
          raise RuntimeError("No input tensor to time-distribute")
  
      # Now get the output back into the right shape.
      # (batch_size, time_steps, **output_size)
      tuple_output = True
      if not isinstance(reshaped_outputs, tuple):
          tuple_output = False
          reshaped_outputs = (reshaped_outputs,)
  
      outputs = []
      for reshaped_output in reshaped_outputs:
          new_size = some_input.size()[:2] + reshaped_output.size()[1:]
          outputs.append(reshaped_output.contiguous().view(new_size))
  
      if not tuple_output:
          outputs = outputs[0]
  
      return outputs
  
imports: from typing import List
  import torch
label_desc: Use image node_id 2 for calling the TimeDistributed obj's underlying member method code with example usage: obj.forward() and returns: outputs