class_docstr: TrainLoop contains the core training loop logic.
class_docstr_tok: ["TrainLoop","contains","the","core","training","loop","logic","."]
docstr: Perform a training run.
  
  :return: tuple of reports (validation_report, test_report)
docstr_tok: ["Perform","a","training","run",".",":","return",":","tuple","of","reports","(","validation_report",",","test_report",")"]
code: def train(self):
      """
      Perform a training run.
  
      :return: tuple of reports (validation_report, test_report)
      """
      opt = self.opt
      for _train_log in self.train_steps():
          # we've already done what we need in these
          pass
  
      # perform final validation/testing
      valid_worlds = load_eval_worlds(self.agent, opt, "valid")
      max_exs = (
          opt["validation_max_exs"]
          if opt.get("short_final_eval")
          else -1
      )
      self.final_valid_report = self._run_eval(
          valid_worlds, opt, "valid", max_exs, write_log=True
      )
      test_worlds = load_eval_worlds(self.agent, opt, "test")
      self.final_test_report = self._run_eval(
          test_worlds, opt, "test", max_exs, write_log=True
      )
  
      if opt["wandb_log"] and is_primary_worker():
          self.wb_logger.log_final("valid", self.final_valid_report)
          self.wb_logger.log_final("test", self.final_test_report)
          self.wb_logger.finish()
      if opt["clearml_log"] and is_primary_worker():
          self.clearml_logger.log_final(
              "Validation Report", self.final_valid_report
          )
          self.clearml_logger.log_final(
              "Test Report", self.final_test_report
          )
  
      if valid_worlds:
          for valid_world in valid_worlds:
              valid_world.shutdown()
      if test_worlds:
          for test_world in test_worlds:
              test_world.shutdown()
  
      print_announcements(opt)
  
      if opt["final_extra_opt"] != "":
          self.final_extra_valid_report = self._run_final_extra_eval(
              opt
          )
  
      if opt["wandb_log"] and is_primary_worker():
          self.wb_logger.finish()
  
      if opt["clearml_log"] and is_primary_worker():
          self.clearml_logger.upload_artifact(
              "dictionary", opt["dict_file"]
          )
          self.clearml_logger.close()
  
      self._save_train_stats()
  
      return self.final_valid_report, self.final_test_report
  
imports: import copy
  import random
  import torch
  import json
  import os
  import signal
  from typing import Tuple
  import numpy
  import parlai.utils.logging
  from parlai.core.agents import create_agent, create_agent_from_shared
  from parlai.core.exceptions import StopTrainException
  from parlai.core.logs import TensorboardLogger, WandbLogger, ClearMLLogger
  from parlai.core.metrics import Metric
  from parlai.core.metrics import aggregate_named_reports, aggregate_unnamed_reports, dict_report
  from parlai.core.opt import Opt
  from parlai.core.params import ParlaiParser, print_announcements
  from parlai.core.script import ParlaiScript, register_script
  from parlai.core.worlds import create_task, World
  from parlai.scripts.build_dict import build_dict, setup_args
  from parlai.scripts.eval_model import get_task_world_logs
  from parlai.utils.distributed import sync_object, is_primary_worker, all_gather_list, is_distributed, get_rank, num_workers
  from parlai.utils.io import PathManager
  from parlai.utils.misc import Timer, nice_report
  from parlai.utils.world_logging import WorldLogger
label_desc: Use image node_id 13 for calling the TrainLoop obj's underlying member method code with example usage: obj.train() and returns: self,  self