class_docstr: Runner for evaluating using a fixed number of episodes rather than steps.
  
  Also restricts data collection to a strict cap,
  following conventions in data-efficient RL research.
class_docstr_tok: ["Runner","for","evaluating","using","a","fixed","number","of","episodes","rather","than","steps",".","Also","restricts","data","collection","to","a","strict","cap",",","following","conventions","in","data-efficient","RL","research","."]
docstr: Run evaluation phase.
  
  Args:
      statistics: `IterationStatistics` object which records the experimental
        results. Note - This object is modified by this method.
  
  Returns:
      num_episodes: int, The number of episodes run in this phase.
      average_reward: float, The average reward generated in this phase.
docstr_tok: ["Run","evaluation","phase",".","Args",":","statistics",":","`","IterationStatistics","`","object","which","records","the","experimental","results",".","Note","-","This","object","is","modified","by","this","method",".","Returns",":","num_episodes",":","int",",","The","number","of","episodes","run","in","this","phase",".","average_reward",":","float",",","The","average","reward","generated","in","this","phase","."]
code: def _run_eval_phase(self, statistics):
      """Run evaluation phase.
  
      Args:
          statistics: `IterationStatistics` object which records the experimental
            results. Note - This object is modified by this method.
  
      Returns:
          num_episodes: int, The number of episodes run in this phase.
          average_reward: float, The average reward generated in this phase.
      """
      # Perform the evaluation phase -- no learning.
      self._agent.eval_mode = True
      eval_envs = [
          self.create_environment_fn()
          for i in range(self.num_eval_envs)
      ]
      _, sum_returns, num_episodes, _, _ = self._run_one_phase(
          eval_envs,
          steps=None,
          max_episodes=self._num_eval_episodes,
          statistics=statistics,
          needs_reset=True,
          resume_state=None,
          one_to_one=self.eval_one_to_one,
          run_mode_str="eval",
      )
      average_return = (
          sum_returns / num_episodes if num_episodes > 0 else 0.0
      )
      logging.info(
          "Average undiscounted return per evaluation episode: %.2f",
          average_return,
      )
      statistics.append({"eval_average_return": average_return})
      if self.log_normalized_scores:
          normalized_return = normalization_utils.normalize_score(
              average_return, self.game_name
          )
          statistics.append(
              {"train_average_normalized_score": normalized_return}
          )
          logging.info(
              "Average normalized return per evaluation episode: %.2f",
              normalized_return,
          )
      else:
          normalized_return = None
      return num_episodes, average_return, normalized_return
  
imports: import functools
  import os
  import sys
  import time
  from absl import logging
  from dopamine.discrete_domains import atari_lib
  from dopamine.discrete_domains import iteration_statistics
  from dopamine.discrete_domains import run_experiment
  from dopamine.labs.atari_100k import normalization_utils
  from dopamine.metrics import collector_dispatcher
  from dopamine.metrics import statistics_instance
  import gin
  import jax
  import numpy
  import tensorflow
label_desc: Use image node_id 6 for calling the DataEfficientAtariRunner obj's underlying member method code with example usage: obj._run_eval_phase(statistics) and returns: num_episodes,  average_return,  normalized_return