class_docstr: The `NestMap` network processes nested inputs via nested layers.
  
  It is a TF-Agents network that can be used to process nested inputs.
  
  Stateful Keras layers (e.g. LSTMCell, RNN, LSTM, TF-Agents DynamicUnroll)
  are all supported.  The `state_spec` of `NestMap` has a structure matching
  that of `nested_layers`.
  
  `NestMap` can be used in conjunction with `NestFlatten` and a combiner
  (e.g. `tf.keras.layers.Add` or `tf.keras.layers.Concatenate`) to process
  and aggregate in a preprocessing step.
  
  Usage:
  ```python
  net = NestMap({"inp1": layer1, "inp2": layer2})
  outputs, next_state = net({"inp1": inp1, "inp2": inp2}, state)
  ```
class_docstr_tok: ["The","`","NestMap","`","network","processes","nested","inputs","via","nested","layers",".","It","is","a","TF-Agents","network","that","can","be","used","to","process","nested","inputs",".","Stateful","Keras","layers","(","e.g",".","LSTMCell",",","RNN",",","LSTM",",","TF-Agents","DynamicUnroll",")","are","all","supported",".","The","`","state_spec","`","of","`","NestMap","`","has","a","structure","matching","that","of","`","nested_layers","`",".","`","NestMap","`","can","be","used","in","conjunction","with","`","NestFlatten","`","and","a","combiner","(","e.g",".","`","tf.keras.layers.Add","`","or","`","tf.keras.layers.Concatenate","`",")","to","process","and","aggregate","in","a","preprocessing","step",".","Usage",":","``","`","python","net","=","NestMap","(","{","``","inp1","''",":","layer1",",","``","inp2","''",":","layer2","}",")","outputs",",","next_state","=","net","(","{","``","inp1","''",":","inp1",",","``","inp2","''",":","inp2","}",",","state",")","``","`"]
docstr: Create a Sequential Network.
  
  Args:
    nested_layers: A nest of layers and/or networks.  These will be used to
      process the inputs (input nest structure will have to match this
      structure).  Any layers that are subclasses of
      `tf.keras.layers.{RNN,LSTM,GRU,...}` are wrapped in
      `tf_agents.keras_layers.RNNWrapper`.
    input_spec: (Optional.)  A nest of `tf.TypeSpec` representing the input
      observations.  The structure of `input_spec` must match that of
      `nested_layers`.
    name: (Optional.) Network name.
  
  Raises:
    TypeError: If any of the layers are not instances of keras `Layer`.
    ValueError: If `input_spec` is provided but its nest structure does
      not match that of `nested_layers`.
    RuntimeError: If not `tf.executing_eagerly()`; as this is required to
      be able to create deep copies of layers in `layers`.
docstr_tok: ["Create","a","Sequential","Network",".","Args",":","nested_layers",":","A","nest","of","layers","and\/or","networks",".","These","will","be","used","to","process","the","inputs","(","input","nest","structure","will","have","to","match","this","structure",")",".","Any","layers","that","are","subclasses","of","`","tf.keras.layers.","{","RNN",",","LSTM",",","GRU",",","...","}","`","are","wrapped","in","`","tf_agents.keras_layers.RNNWrapper","`",".","input_spec",":","(","Optional",".",")","A","nest","of","`","tf.TypeSpec","`","representing","the","input","observations",".","The","structure","of","`","input_spec","`","must","match","that","of","`","nested_layers","`",".","name",":","(","Optional",".",")","Network","name",".","Raises",":","TypeError",":","If","any","of","the","layers","are","not","instances","of","keras","`","Layer","`",".","ValueError",":","If","`","input_spec","`","is","provided","but","its","nest","structure","does","not","match","that","of","`","nested_layers","`",".","RuntimeError",":","If","not","`","tf.executing_eagerly","(",")","`",";","as","this","is","required","to","be","able","to","create","deep","copies","of","layers","in","`","layers","`","."]
code: def __init__(
      self,
      nested_layers: types.NestedLayer,
      input_spec: typing.Optional[types.NestedTensorSpec] = None,
      name: typing.Optional[typing.Text] = None,
  ):
      """Create a Sequential Network.
  
      Args:
        nested_layers: A nest of layers and/or networks.  These will be used to
          process the inputs (input nest structure will have to match this
          structure).  Any layers that are subclasses of
          `tf.keras.layers.{RNN,LSTM,GRU,...}` are wrapped in
          `tf_agents.keras_layers.RNNWrapper`.
        input_spec: (Optional.)  A nest of `tf.TypeSpec` representing the input
          observations.  The structure of `input_spec` must match that of
          `nested_layers`.
        name: (Optional.) Network name.
  
      Raises:
        TypeError: If any of the layers are not instances of keras `Layer`.
        ValueError: If `input_spec` is provided but its nest structure does
          not match that of `nested_layers`.
        RuntimeError: If not `tf.executing_eagerly()`; as this is required to
          be able to create deep copies of layers in `layers`.
      """
      if not tf.executing_eagerly():
          raise RuntimeError(
              "Not executing eagerly - cannot make deep copies of `nested_layers`."
          )
  
      flat_nested_layers = tf.nest.flatten(nested_layers)
      for layer in flat_nested_layers:
          if not isinstance(layer, tf.keras.layers.Layer):
              raise TypeError(
                  "Expected all layers to be instances of keras Layer, but saw"
                  ": '{}'".format(layer)
              )
  
      if input_spec is not None:
          nest_utils.assert_same_structure(
              nested_layers,
              input_spec,
              message=(
                  "`nested_layers` and `input_spec` do not have matching structures"
              ),
          )
          flat_input_spec = tf.nest.flatten(input_spec)
      else:
          flat_input_spec = [None] * len(flat_nested_layers)
  
      # Wrap in Sequential if necessary.
      flat_nested_layers = [
          sequential.Sequential([m], s)
          if not isinstance(m, network.Network)
          else m
          for (s, m) in zip(flat_input_spec, flat_nested_layers)
      ]
  
      flat_nested_layers_state_specs = [
          m.state_spec for m in flat_nested_layers
      ]
      nested_layers = tf.nest.pack_sequence_as(
          nested_layers, flat_nested_layers
      )
      # We use flattened layers and states here instead of tf.nest.map_structure
      # for several reason.  One is that we perform several operations against
      # the layers and we want to avoid calling into tf.nest.map* multiple times.
      # But the main reason is that network states have a different *structure*
      # than the layers; e.g., `nested_layers` may just be tf.keras.layers.LSTM,
      # but the states would then have structure `[.,.]`.  Passing these in
      # as args to tf.nest.map_structure causes it to fail.  Instead we would
      # have to use nest.map_structure_up_to -- but that function is not part
      # of the public TF API.  However, if we do everything in flatland and then
      # use pack_sequence_as, we bypass the more rigid structure tests.
      state_spec = tf.nest.pack_sequence_as(
          nested_layers, flat_nested_layers_state_specs
      )
  
      super(NestMap, self).__init__(
          input_tensor_spec=input_spec, state_spec=state_spec, name=name
      )
      self._nested_layers = nested_layers
  
file_path: agents/tf_agents/networks/nest_map.py
imports: from __future__ import absolute_import
  from __future__ import division
  from __future__ import print_function
  import copy
  import typing
  import tensorflow.compat.v2
  from tf_agents.networks import network
  from tf_agents.networks import sequential
  from tf_agents.typing import types
  from tf_agents.utils import nest_utils
label_desc: Use image node_id 1 to create a new NestMap object from inherited base classes: network with example: obj = NestMap(nested_layers, input_spec, name)