class_docstr: An inference block combining multiple perception blocks into one prediction module.
          Conditions on using the InferenceBlock object:
              1. All keys of the perception_blocks dictionary have to be unique
              2. All out_keys used when creating the blocks have to be unique
              3. All block keys in the perception_blocks dict have to sub-strings of all their corresponding out_keys
              4. The given in_keys should be a subset of the inputs of the computational graph
              5. The given out_keys should be a subset of the outputs of the computational graph
  
  :param in_keys: Keys identifying the input tensors.
  :param out_keys: Keys identifying the output tensors.
  :param in_shapes: List of input shapes.
  :param perception_blocks: Dictionary of perception blocks.
class_docstr_tok: ["An","inference","block","combining","multiple","perception","blocks","into","one","prediction","module",".","Conditions","on","using","the","InferenceBlock","object",":","1",".","All","keys","of","the","perception_blocks","dictionary","have","to","be","unique","2",".","All","out_keys","used","when","creating","the","blocks","have","to","be","unique","3",".","All","block","keys","in","the","perception_blocks","dict","have","to","sub-strings","of","all","their","corresponding","out_keys","4",".","The","given","in_keys","should","be","a","subset","of","the","inputs","of","the","computational","graph","5",".","The","given","out_keys","should","be","a","subset","of","the","outputs","of","the","computational","graph",":","param","in_keys",":","Keys","identifying","the","input","tensors",".",":","param","out_keys",":","Keys","identifying","the","output","tensors",".",":","param","in_shapes",":","List","of","input","shapes",".",":","param","perception_blocks",":","Dictionary","of","perception","blocks","."]
docstr: implementation of :class:`~maze.perception.blocks.base.PerceptionBlock` interface
          
docstr_tok: ["implementation","of",":","class",":","`","~maze.perception.blocks.base.PerceptionBlock","`","interface"]
code: def forward(
      self, block_input: Dict[str, torch.Tensor]
  ) -> Dict[str, torch.Tensor]:
      """implementation of :class:`~maze.perception.blocks.base.PerceptionBlock` interface"""
      assert all(
          [key in block_input.keys() for key in self.in_keys]
      ), f"The specified in_keys {self.in_keys} should be a subset of the observations: {block_input.keys()}"
  
      tmp_dict: Dict[str, torch.Tensor] = dict()
  
      for step_idx in range(len(self.execution_plan.keys())):
          argument_dict = {**tmp_dict, **block_input}
          step_block_keys = self.execution_plan[step_idx]
  
          for block_key in step_block_keys:
              block_output = self.perception_blocks[block_key](
                  argument_dict
              )
  
              # update tensor dictionary
              tmp_dict.update(block_output)
  
      assert all(
          [key in tmp_dict for key in self.out_keys]
      ), "All out_keys should be computed at this point"
      # compile output dictionary
      out_dict = dict()
      for out_key in self.out_keys:
          out_dict[out_key] = tmp_dict[out_key]
  
      return out_dict
  
imports: import os
  import pickle
  from typing import Union, List, Dict, Optional, Sequence, Tuple
  import networkx
  import torch
  from matplotlib import pyplot
  from torch import nn
  from maze.core.annotations import override
  from maze.perception.blocks.base import PerceptionBlock
label_desc: Use image node_id 3 for calling the InferenceBlock obj's underlying member method code with example usage: obj.forward(block_input) and returns: out_dict