class_docstr: A block applying a custom callable. It processes a tensor or sequence of tensors and returns a tensor or sequence
  of tensors. If the callable has more than one argument the names of the arguments of the function declaration have
  to match the in_keys of the tensors.
  
  :param in_keys: One key identifying the input tensors.
  :param out_keys: One key identifying the output tensors.
  :param in_shapes: List of input shapes.
  :param func: A simple callable taking a tensor or a sequence of tensors and returning a tensor or a sequence of
      tensors.
class_docstr_tok: ["A","block","applying","a","custom","callable",".","It","processes","a","tensor","or","sequence","of","tensors","and","returns","a","tensor","or","sequence","of","tensors",".","If","the","callable","has","more","than","one","argument","the","names","of","the","arguments","of","the","function","declaration","have","to","match","the","in_keys","of","the","tensors",".",":","param","in_keys",":","One","key","identifying","the","input","tensors",".",":","param","out_keys",":","One","key","identifying","the","output","tensors",".",":","param","in_shapes",":","List","of","input","shapes",".",":","param","func",":","A","simple","callable","taking","a","tensor","or","a","sequence","of","tensors","and","returning","a","tensor","or","a","sequence","of","tensors","."]
docstr: Forward pass through the block, applying the callable to the input.
  
  :param block_input: The block's input dictionary.
  :return: The block's output dictionary.
docstr_tok: ["Forward","pass","through","the","block",",","applying","the","callable","to","the","input",".",":","param","block_input",":","The","block","'s","input","dictionary",".",":","return",":","The","block","'s","output","dictionary","."]
code: def forward(
      self, block_input: Dict[str, torch.Tensor]
  ) -> Dict[str, torch.Tensor]:
      """Forward pass through the block, applying the callable to the input.
  
      :param block_input: The block's input dictionary.
      :return: The block's output dictionary.
      """
  
      # check input tensor
      input_tensors = {key: block_input[key] for key in self.in_keys}
      if len(input_tensors) > 1:
          output_tensors = self.func(**input_tensors)
      else:
          output_tensors = self.func(list(input_tensors.values())[0])
  
      out = dict()
      if len(self.out_keys) > 1:
          for key, value in zip(self.out_keys, output_tensors):
              out[key] = value
      else:
          out[self.out_keys[0]] = output_tensors
  
      return out
  
file_path: maze/maze/perception/blocks/general/functional.py
imports: import inspect
  import types
  from typing import Union, List, Sequence, Dict, Callable
  import torch
  from maze.core.annotations import override
  from maze.perception.blocks.base import PerceptionBlock
label_desc: Use image node_id 2 for calling the FunctionalBlock obj's underlying member method code with example usage: obj.forward(block_input) and returns: out