class_docstr: A TFPolicy that auto-defines placeholders dynamically at runtime.
  
  Do not sub-class this class directly (neither should you sub-class
  TFPolicy), but rather use rllib.policy.tf_policy_template.build_tf_policy
  to generate your custom tf (graph-mode or eager) Policy classes.
code: def _initialize_loss_from_dummy_batch(
      self, auto_remove_unneeded_view_reqs: bool = True, stats_fn=None
  ) -> None:
      # Create the optimizer/exploration optimizer here. Some initialization
      # steps (e.g. exploration postprocessing) may need this.
      if not self._optimizers:
          self._optimizers = force_list(self.optimizer())
          # Backward compatibility.
          self._optimizer = self._optimizers[0]
  
      # Test calls depend on variable init, so initialize model first.
      self.get_session().run(tf1.global_variables_initializer())
  
      # Fields that have not been accessed are not needed for action
      # computations -> Tag them as `used_for_compute_actions=False`.
      for key, view_req in self.view_requirements.items():
          if (
              not key.startswith("state_in_")
              and key not in self._input_dict.accessed_keys
          ):
              view_req.used_for_compute_actions = False
      for key, value in self._extra_action_fetches.items():
          self._dummy_batch[key] = get_dummy_batch_for_space(
              gym.spaces.Box(
                  -1.0,
                  1.0,
                  shape=value.shape.as_list()[1:],
                  dtype=value.dtype.name,
              ),
              batch_size=len(self._dummy_batch),
          )
          self._input_dict[key] = get_placeholder(value=value, name=key)
          if key not in self.view_requirements:
              logger.info(
                  "Adding extra-action-fetch `{}` to view-reqs.".format(
                      key
                  )
              )
              self.view_requirements[key] = ViewRequirement(
                  space=gym.spaces.Box(
                      -1.0,
                      1.0,
                      shape=value.shape.as_list()[1:],
                      dtype=value.dtype.name,
                  ),
                  used_for_compute_actions=False,
              )
      dummy_batch = self._dummy_batch
  
      logger.info("Testing `postprocess_trajectory` w/ dummy batch.")
      self.exploration.postprocess_trajectory(
          self, dummy_batch, self.get_session()
      )
      _ = self.postprocess_trajectory(dummy_batch)
      # Add new columns automatically to (loss) input_dict.
      for key in dummy_batch.added_keys:
          if key not in self._input_dict:
              self._input_dict[key] = get_placeholder(
                  value=dummy_batch[key], name=key
              )
          if key not in self.view_requirements:
              self.view_requirements[key] = ViewRequirement(
                  space=gym.spaces.Box(
                      -1.0,
                      1.0,
                      shape=dummy_batch[key].shape[1:],
                      dtype=dummy_batch[key].dtype,
                  ),
                  used_for_compute_actions=False,
              )
  
      train_batch = SampleBatch(
          dict(self._input_dict, **self._loss_input_dict),
          _is_training=True,
      )
  
      if self._state_inputs:
          train_batch[SampleBatch.SEQ_LENS] = self._seq_lens
          self._loss_input_dict.update(
              {SampleBatch.SEQ_LENS: train_batch[SampleBatch.SEQ_LENS]}
          )
  
      self._loss_input_dict.update(
          {k: v for k, v in train_batch.items()}
      )
  
      if log_once("loss_init"):
          logger.debug(
              "Initializing loss function with dummy input:\n\n{}\n".format(
                  summarize(train_batch)
              )
          )
  
      losses = self._do_loss_init(train_batch)
  
      all_accessed_keys = (
          train_batch.accessed_keys
          | dummy_batch.accessed_keys
          | dummy_batch.added_keys
          | set(self.model.view_requirements.keys())
      )
  
      TFPolicy._initialize_loss(
          self,
          losses,
          [
              (k, v)
              for k, v in train_batch.items()
              if k in all_accessed_keys
          ]
          + (
              [
                  (
                      SampleBatch.SEQ_LENS,
                      train_batch[SampleBatch.SEQ_LENS],
                  )
              ]
              if SampleBatch.SEQ_LENS in train_batch
              else []
          ),
      )
  
      if "is_training" in self._loss_input_dict:
          del self._loss_input_dict["is_training"]
  
      # Call the grads stats fn.
      # TODO: (sven) rename to simply stats_fn to match eager and torch.
      if self._grad_stats_fn:
          self._stats_fetches.update(
              self._grad_stats_fn(self, train_batch, self._grads)
          )
  
      # Add new columns automatically to view-reqs.
      if auto_remove_unneeded_view_reqs:
          # Add those needed for postprocessing and training.
          all_accessed_keys = (
              train_batch.accessed_keys | dummy_batch.accessed_keys
          )
          # Tag those only needed for post-processing (with some exceptions).
          for key in dummy_batch.accessed_keys:
              if (
                  key not in train_batch.accessed_keys
                  and key not in self.model.view_requirements
                  and key
                  not in [
                      SampleBatch.EPS_ID,
                      SampleBatch.AGENT_INDEX,
                      SampleBatch.UNROLL_ID,
                      SampleBatch.TERMINATEDS,
                      SampleBatch.TRUNCATEDS,
                      SampleBatch.REWARDS,
                      SampleBatch.INFOS,
                      SampleBatch.T,
                      SampleBatch.OBS_EMBEDS,
                  ]
              ):
                  if key in self.view_requirements:
                      self.view_requirements[
                          key
                      ].used_for_training = False
                  if key in self._loss_input_dict:
                      del self._loss_input_dict[key]
          # Remove those not needed at all (leave those that are needed
          # by Sampler to properly execute sample collection).
          # Also always leave TERMINATEDS, TRUNCATEDS, REWARDS, and INFOS,
          # no matter what.
          for key in list(self.view_requirements.keys()):
              if (
                  key not in all_accessed_keys
                  and key
                  not in [
                      SampleBatch.EPS_ID,
                      SampleBatch.AGENT_INDEX,
                      SampleBatch.UNROLL_ID,
                      SampleBatch.TERMINATEDS,
                      SampleBatch.TRUNCATEDS,
                      SampleBatch.REWARDS,
                      SampleBatch.INFOS,
                      SampleBatch.T,
                  ]
                  and key not in self.model.view_requirements
              ):
                  # If user deleted this key manually in postprocessing
                  # fn, warn about it and do not remove from
                  # view-requirements.
                  if key in dummy_batch.deleted_keys:
                      logger.warning(
                          "SampleBatch key '{}' was deleted manually in "
                          "postprocessing function! RLlib will "
                          "automatically remove non-used items from the "
                          "data stream. Remove the `del` from your "
                          "postprocessing function.".format(key)
                      )
                  # If we are not writing output to disk, safe to erase
                  # this key to save space in the sample batch.
                  elif self.config["output"] is None:
                      del self.view_requirements[key]
  
                  if key in self._loss_input_dict:
                      del self._loss_input_dict[key]
          # Add those data_cols (again) that are missing and have
          # dependencies by view_cols.
          for key in list(self.view_requirements.keys()):
              vr = self.view_requirements[key]
              if (
                  vr.data_col is not None
                  and vr.data_col not in self.view_requirements
              ):
                  used_for_training = (
                      vr.data_col in train_batch.accessed_keys
                  )
                  self.view_requirements[vr.data_col] = ViewRequirement(
                      space=vr.space,
                      used_for_training=used_for_training,
                  )
  
      self._loss_input_dict_no_rnn = {
          k: v
          for k, v in self._loss_input_dict.items()
          if (v not in self._state_inputs and v != self._seq_lens)
      }
  
imports: from collections import namedtuple, OrderedDict
  import gymnasium
  import logging
  import re
  import tree
  from typing import Callable, Dict, List, Optional, Tuple, Type, Union
  from ray.util.debug import log_once
  from ray.rllib.models.tf.tf_action_dist import TFActionDistribution
  from ray.rllib.models.modelv2 import ModelV2
  from ray.rllib.policy.policy import Policy
  from ray.rllib.policy.sample_batch import SampleBatch
  from ray.rllib.policy.tf_policy import TFPolicy
  from ray.rllib.policy.view_requirement import ViewRequirement
  from ray.rllib.models.catalog import ModelCatalog
  from ray.rllib.utils import force_list
  from ray.rllib.utils.annotations import override, DeveloperAPI
  from ray.rllib.utils.debug import summarize
  from ray.rllib.utils.deprecation import deprecation_warning, DEPRECATED_VALUE
  from ray.rllib.utils.framework import try_import_tf
  from ray.rllib.utils.metrics import DIFF_NUM_GRAD_UPDATES_VS_SAMPLER_POLICY, NUM_GRAD_UPDATES_LIFETIME
  from ray.rllib.utils.spaces.space_utils import get_dummy_batch_for_space
  from ray.rllib.utils.tf_utils import get_placeholder
  from ray.rllib.utils.typing import LocalOptimizer, ModelGradients, TensorType, AlgorithmConfigDict
label_desc: Use image node_id 8 for calling the DynamicTFPolicy obj's underlying member method code with example usage: obj._initialize_loss_from_dummy_batch(auto_remove_unneeded_view_reqs, stats_fn) without return types