code: def fine_tune_model(
      model,
      params,
      serialization_dir,
      extend_vocab=False,
      file_friendly_logging=False,
  ):
      """
      Fine tunes the given model, using a set of parameters that is largely identical to those used
      for :func:`~allennlp.commands.train.train_model`, except that the ``model`` section is ignored,
      if it is present (as we are already given a ``Model`` here).
  
      The main difference between the logic done here and the logic done in ``train_model`` is that
      here we do not worry about vocabulary construction or creating the model object.  Everything
      else is the same.
  
      Parameters
      ----------
      archive : ``Archive``
          A saved model archive that is the result of running the ``train`` command.
      train_data_path : ``str``
          Path to the training data to use for fine-tuning.
      serialization_dir : ``str``
          The directory in which to save results and logs.
      validation_data_path : ``str``, optional
          Path to the validation data to use while fine-tuning.
      extend_vocab: ``bool``, optional (default=False)
          If ``True``, we use the new instances to extend your vocabulary.
      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.
      """
      prepare_environment(params)
      if os.path.exists(serialization_dir) and os.listdir(
          serialization_dir
      ):
          raise ConfigurationError(
              "Serialization directory ({serialization_dir}) "
              "already exists and is not empty."
          )
  
      os.makedirs(serialization_dir, exist_ok=True)
      prepare_global_logging(serialization_dir, file_friendly_logging)
  
      serialization_params = deepcopy(params).as_dict(quiet=True)
      with open(
          os.path.join(serialization_dir, CONFIG_NAME), "w"
      ) as param_file:
          json.dump(serialization_params, param_file, indent=4)
  
      if params.pop("model", None):
          logger.warning(
              "You passed parameters for the model in your configuration file, but we "
              "are ignoring them, using instead the model parameters in the archive."
          )
  
      vocabulary_params = params.pop("vocabulary", {})
      if vocabulary_params.get("directory_path", None):
          logger.warning(
              "You passed `directory_path` in parameters for the vocabulary in "
              "your configuration file, but it will be ignored. "
          )
  
      all_datasets = datasets_from_params(params)
      vocab = model.vocab
  
      if extend_vocab:
          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(
              "Extending model vocabulary using %s data.",
              ", ".join(datasets_for_vocab_creation),
          )
          vocab.extend_from_instances(
              vocabulary_params,
              (
                  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"))
  
      iterator = DataIterator.from_params(params.pop("iterator"))
      iterator.index_with(model.vocab)
  
      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,
      )
  
      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(
                  "Fine-tuning 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
      )
  
      if test_data and evaluate_on_test:
          test_metrics = evaluate(
              model,
              test_data,
              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 model
  
imports: from __future__ import with_statement
  from __future__ import absolute_import
  import argparse
  import json
  import logging
  import os
  from copy import deepcopy
  import re
  from allennlp.commands.evaluate import evaluate
  from allennlp.commands.subcommand import Subcommand
  from allennlp.commands.train import datasets_from_params
  from allennlp.common import Params
  from allennlp.common.util import prepare_environment, prepare_global_logging, get_frozen_and_tunable_parameter_names
  from allennlp.data.iterators.data_iterator import DataIterator
  from allennlp.models import load_archive, archive_model
  from allennlp.models.archival import CONFIG_NAME
  from allennlp.models.model import Model, _DEFAULT_WEIGHTS
  from allennlp.training.trainer import Trainer
  from allennlp.common.checks import ConfigurationError
  from io import open
label_desc: Use image node_id 3 for calling a global function with example usage: fine_tune_model(model, params, serialization_dir, extend_vocab, file_friendly_logging) and returns: model