class_docstr: A NestedDict containing `TensorSpec` and `Types`.
  
  It can be used to validate an incoming data against a nested dictionary of specs.
  
  Examples:
  
      Basic validation:
      -----------------
  
      .. testcode::
          :skipif: True
  
          spec_dict = SpecDict({
              "obs": {
                  "arm":      TensorSpec("b, dim_arm", dim_arm=64),
                  "gripper":  TensorSpec("b, dim_grip", dim_grip=12)
              },
              "action": TensorSpec("b, dim_action", dim_action=12),
              "action_dist": torch.distributions.Categorical
  
          spec_dict.validate({
              "obs": {
                  "arm":      torch.randn(32, 64),
                  "gripper":  torch.randn(32, 12)
              },
              "action": torch.randn(32, 12),
              "action_dist": torch.distributions.Categorical(torch.randn(32, 12))
          }) # No er
          spec_dict.validate({
              "obs": {
                  "arm":      torch.randn(32, 32), # Wrong shape
                  "gripper":  torch.randn(32, 12)
              },
              "action": torch.randn(32, 12),
              "action_dist": torch.distributions.Categorical(torch.randn(32, 12))
          }) # raises ValueError
  
      Filtering input data:
      ---------------------
  
      .. testcode::
          :skipif: True
  
          input_data = {
              "obs": {
                  "arm":      torch.randn(32, 64),
                  "gripper":  torch.randn(32, 12),
                  "unused":   torch.randn(32, 12)
              },
              "action": torch.randn(32, 12),
              "action_dist": torch.distributions.Categorical(torch.randn(32, 12)),
              "unused": torch.randn(32, 12)
          }
          input_data.filter(spec_dict) # returns a dict with only the keys in the spec
  
      .. testoutput::
  
          {
              "obs": {
                  "arm":      input_data["obs"]["arm"],
                  "gripper":  input_data["obs"]["gripper"]
              },
              "action": input_data["action"],
              "action_dist": input_data["action_dist"]
          }
  
  Raises:
      ValueError: If the data doesn't match the spec.
code: def __init__(self, *args, **kwargs):
      super().__init__(*args, **kwargs)
      self._keys_set = set(self.keys())
  
file_path: ray/python/ray/rllib/core/models/specs/specs_dict.py
imports: from typing import Union, Mapping, Any
  from ray.rllib.utils.annotations import ExperimentalAPI, override
  from ray.rllib.utils.nested_dict import NestedDict
  from ray.rllib.core.models.specs.specs_base import Spec
label_desc: Use image node_id 1 to create a new SpecDict object from inherited base classes: NestedDict, Spec with example: obj = SpecDict()