code: def train_evaluate_model_from_config(
      config: Union[str, Path, dict],
      iterator: Union[DataLearningIterator, DataFittingIterator] = None,
      *,
      to_train: bool = True,
      evaluation_targets: Optional[Iterable[str]] = None,
      install: bool = False,
      download: bool = False,
      start_epoch_num: Optional[int] = None,
      recursive: bool = False,
  ) -> Dict[str, Dict[str, float]]:
      """Make training and evaluation of the model described in corresponding configuration file."""
      config = parse_config(config)
  
      if install:
          install_from_config(config)
      if download:
          deep_download(config)
  
      if to_train and recursive:
          for subconfig in get_all_elems_from_json(
              config["chainer"], "config_path"
          ):
              log.info(f'Training "{subconfig}"')
              train_evaluate_model_from_config(
                  subconfig, download=False, recursive=True
              )
  
      import_packages(config.get("metadata", {}).get("imports", []))
  
      if iterator is None:
          try:
              data = read_data_by_config(config)
              # TODO: check class objects, not strings
              is_mtl = (
                  config["dataset_reader"]["class_name"]
                  == "multitask_reader"
              )
              if (
                  config.get("train", {}).get("val_every_n_epochs")
                  and not data.get("valid")
                  and not is_mtl
              ):
                  error_message = 'The value "val_every_n_epochs" is set in the config but no validation data is provided'
                  raise AttributeError(error_message)
          except ConfigError as e:
              to_train = False
              log.warning(f"Skipping training. {e.message}")
          else:
              iterator = get_iterator_from_config(config, data)
  
      if "train" not in config:
          log.warning(
              "Train config is missing. Populating with default values"
          )
      train_config = config.get("train", {})
  
      if start_epoch_num is not None:
          train_config["start_epoch_num"] = start_epoch_num
  
      trainer_class = get_model(
          train_config.pop("class_name", "torch_trainer")
      )
  
      trainer = trainer_class(config["chainer"], **train_config)
  
      if to_train:
          trainer.train(iterator)
  
      res = {}
  
      if iterator is not None:
          res = trainer.evaluate(iterator, evaluation_targets)
          trainer.get_chainer().destroy()
  
      res = {k: v["metrics"] for k, v in res.items()}
  
      return res
  
file_path: DeepPavlov/deeppavlov/core/commands/train.py
imports: from logging import getLogger
  from pathlib import Path
  from typing import Dict, Union, Optional, Iterable
  from deeppavlov.core.commands.utils import expand_path, import_packages, parse_config
  from deeppavlov.core.common.errors import ConfigError
  from deeppavlov.core.common.params import resolve
  from deeppavlov.core.common.registry import get_model
  from deeppavlov.core.data.data_fitting_iterator import DataFittingIterator
  from deeppavlov.core.data.data_learning_iterator import DataLearningIterator
  from deeppavlov.core.data.utils import get_all_elems_from_json
  from deeppavlov.download import deep_download
  from deeppavlov.utils.pip_wrapper import install_from_config
label_desc: Use image node_id 3 for calling a global function with example usage: train_evaluate_model_from_config(config, iterator) and returns: res