code: def train_model(
      params,
      serialization_dir,
      file_friendly_logging=False,
      recover=False,
  ):
      """
      Trains the model specified in the given :class:`Params` object, using the data and training
      parameters also specified in that object, and saves the results in ``serialization_dir``.
  
      Parameters
      ----------
      params : ``Params``
          A parameter object specifying an AllenNLP Experiment.
      serialization_dir : ``str``
          The directory in which to save results and logs.
      file_friendly_logging : ``bool``, optional (default=False)
          If ``True``, we add newlines to tqdm output, even on an interactive terminal, and we slow
          down tqdm's output to only once every 10 seconds.
      recover : ``bool``, optional (default=False)
          If ``True``, we will try to recover a training run from an existing serialization
          directory.  This is only intended for use when something actually crashed during the middle
          of a run.  For continuing training a model on new data, see the ``fine-tune`` command.
  
      Returns
      -------
      best_model: ``Model``
          The model with the best epoch weights.
      """
      prepare_environment(params)
  
      create_serialization_dir(params, serialization_dir, recover)
      prepare_global_logging(serialization_dir, file_friendly_logging)
  
      check_for_gpu(params.get("trainer").get("cuda_device", -1))
  
      params.to_file(os.path.join(serialization_dir, CONFIG_NAME))
  
      all_datasets = datasets_from_params(params)
      datasets_for_vocab_creation = set(
          params.pop("datasets_for_vocab_creation", all_datasets)
      )
  
      for dataset in datasets_for_vocab_creation:
          if dataset not in all_datasets:
              raise ConfigurationError(
                  "invalid 'dataset_for_vocab_creation' {dataset}"
              )
  
      logger.info(
          "From dataset instances, %s will be considered for vocabulary creation.",
          ", ".join(datasets_for_vocab_creation),
      )
      vocab = Vocabulary.from_params(
          params.pop("vocabulary", {}),
          (
              instance
              for key, dataset in list(all_datasets.items())
              for instance in dataset
              if key in datasets_for_vocab_creation
          ),
      )
  
      vocab.save_to_files(os.path.join(serialization_dir, "vocabulary"))
  
      model = Model.from_params(vocab=vocab, params=params.pop("model"))
      iterator = DataIterator.from_params(params.pop("iterator"))
      iterator.index_with(vocab)
      validation_iterator_params = params.pop(
          "validation_iterator", None
      )
      if validation_iterator_params:
          validation_iterator = DataIterator.from_params(
              validation_iterator_params
          )
          validation_iterator.index_with(vocab)
      else:
          validation_iterator = None
  
      train_data = all_datasets["train"]
      validation_data = all_datasets.get("validation")
      test_data = all_datasets.get("test")
  
      trainer_params = params.pop("trainer")
      no_grad_regexes = trainer_params.pop("no_grad", ())
      for name, parameter in model.named_parameters():
          if any(re.search(regex, name) for regex in no_grad_regexes):
              parameter.requires_grad_(False)
  
      (
          frozen_parameter_names,
          tunable_parameter_names,
      ) = get_frozen_and_tunable_parameter_names(model)
      logger.info(
          "Following parameters are Frozen  (without gradient):"
      )
      for name in frozen_parameter_names:
          logger.info(name)
      logger.info("Following parameters are Tunable (with gradient):")
      for name in tunable_parameter_names:
          logger.info(name)
  
      trainer = Trainer.from_params(
          model,
          serialization_dir,
          iterator,
          train_data,
          validation_data,
          trainer_params,
          validation_iterator=validation_iterator,
      )
  
      evaluate_on_test = params.pop_bool("evaluate_on_test", False)
      params.assert_empty("base train command")
  
      try:
          metrics = trainer.train()
      except KeyboardInterrupt:
          # if we have completed an epoch, try to create a model archive.
          if os.path.exists(
              os.path.join(serialization_dir, _DEFAULT_WEIGHTS)
          ):
              logging.info(
                  "Training interrupted by the user. Attempting to create "
                  "a model archive using the current best epoch weights."
              )
              archive_model(
                  serialization_dir,
                  files_to_archive=params.files_to_archive,
              )
          raise
  
      # Now tar up results
      archive_model(
          serialization_dir, files_to_archive=params.files_to_archive
      )
  
      logger.info("Loading the best epoch weights.")
      best_model_state_path = os.path.join(serialization_dir, "best.th")
      best_model_state = torch.load(best_model_state_path)
      best_model = model
      best_model.load_state_dict(best_model_state)
  
      if test_data and evaluate_on_test:
          logger.info(
              "The model will be evaluated using the best epoch weights."
          )
          test_metrics = evaluate(
              best_model,
              test_data,
              validation_iterator or iterator,
              cuda_device=trainer._cuda_devices[
                  0
              ],  # pylint: disable=protected-access
          )
          for key, value in list(test_metrics.items()):
              metrics["test_" + key] = value
  
      elif test_data:
          logger.info(
              "To evaluate on the test set after training, pass the "
              "'evaluate_on_test' flag, or use the 'allennlp evaluate' command."
          )
  
      metrics_json = json.dumps(metrics, indent=2)
      with open(
          os.path.join(serialization_dir, "metrics.json"), "w"
      ) as metrics_file:
          metrics_file.write(metrics_json)
      logger.info("Metrics: %s", metrics_json)
  
      return best_model
  
imports: from __future__ import with_statement
  from __future__ import absolute_import
  import argparse
  import json
  import logging
  import os
  import re
  import torch
  from allennlp.commands.evaluate import evaluate
  from allennlp.commands.subcommand import Subcommand
  from allennlp.common.checks import ConfigurationError, check_for_gpu
  from allennlp.common import Params
  from allennlp.common.util import prepare_environment, prepare_global_logging, get_frozen_and_tunable_parameter_names
  from allennlp.data import Vocabulary
  from allennlp.data.instance import Instance
  from allennlp.data.dataset_readers.dataset_reader import DatasetReader
  from allennlp.data.iterators.data_iterator import DataIterator
  from allennlp.models.archival import archive_model, CONFIG_NAME
  from allennlp.models.model import Model, _DEFAULT_WEIGHTS
  from allennlp.training.trainer import Trainer
  from io import open
label_desc: Use image node_id 5 for calling a global function with example usage: train_model(params, serialization_dir, file_friendly_logging, recover) and returns: best_model