Runs evaluation for the given number of steps. This method calls `self.evaluator.evaluate(steps)`, then writes the returned summaries (if any). Args: steps: The number of evaluation steps to run. The value `-1` is reserved as a special sentinel to indicate a "complete" ev
(self, steps: int = -1)
| 289 | self._sync_on_async_checkpointing() |
| 290 | |
| 291 | def evaluate(self, steps: int = -1) -> Optional[runner.Output]: |
| 292 | """Runs evaluation for the given number of steps. |
| 293 | |
| 294 | This method calls `self.evaluator.evaluate(steps)`, then writes the returned |
| 295 | summaries (if any). |
| 296 | |
| 297 | Args: |
| 298 | steps: The number of evaluation steps to run. The value `-1` is reserved |
| 299 | as a special sentinel to indicate a "complete" evaluation that runs |
| 300 | until the underlying dataset is exhausted. Support for this is dependent |
| 301 | on the specific `evaluator` being used. |
| 302 | |
| 303 | Returns: |
| 304 | The evaluation results as a dictionary mapping names to NumPy values. |
| 305 | |
| 306 | Raises: |
| 307 | ValueError: If `evaluator` was not provided to `Controller.__init__`. |
| 308 | ValueError: If no checkpoint is present in `checkpoint_manager.directory`. |
| 309 | ValueError: If `steps` is not a positive value or -1. |
| 310 | """ |
| 311 | self._require("evaluator", for_method="evaluate") |
| 312 | |
| 313 | if steps > 0: |
| 314 | steps_msg = f"running {steps} steps of evaluation..." |
| 315 | elif steps == -1: |
| 316 | steps_msg = "running complete evaluation..." |
| 317 | else: |
| 318 | raise ValueError(f"`steps` ({steps}) should be > 0, or == -1.") |
| 319 | |
| 320 | current_step = self.global_step.numpy() |
| 321 | _log(f" eval | step: {current_step: 6d} | {steps_msg}") |
| 322 | |
| 323 | start = time.time() |
| 324 | assert isinstance(self.evaluator, runner.AbstractEvaluator) |
| 325 | with self.eval_summary_manager.summary_writer().as_default(): |
| 326 | steps_tensor = tf.convert_to_tensor(steps, dtype=tf.int32) |
| 327 | eval_output = self.evaluator.evaluate(steps_tensor) |
| 328 | elapsed = time.time() - start |
| 329 | |
| 330 | eval_output = eval_output or {} |
| 331 | for action in self.eval_actions: |
| 332 | action(eval_output) |
| 333 | eval_output = tf.nest.map_structure(utils.get_value, eval_output) |
| 334 | |
| 335 | if steps > 0: |
| 336 | # Only log if steps has been specified. |
| 337 | steps_per_second = steps / elapsed |
| 338 | eval_output["steps_per_second"] = steps_per_second |
| 339 | steps_per_second_log = f"steps/sec: {steps_per_second: 6.1f} | " |
| 340 | else: |
| 341 | steps_per_second_log = "" |
| 342 | |
| 343 | _log(f" eval | step: {current_step: 6d} | " |
| 344 | f"{steps_per_second_log}" |
| 345 | f"eval time: {elapsed: 6.1f} sec | " |
| 346 | f"output: {_format_output(eval_output)}") |
| 347 | |
| 348 | self.eval_summary_manager.write_summaries(eval_output) |