code: def gradual_unfreezing(self):
      for name, param in self.model.named_parameters():
          if "embeddings" not in name and "classification" not in name:
              param.detach_()
              param.requires_grad = False
  
          else:
              param.requires_grad = True
  
      full_parameters = sum(p.numel() for p in self.model.parameters())
      trained_parameters = sum(
          p.numel() for p in self.model.parameters() if p.requires_grad
      )
  
      logger.info(
          f"We will start by training {trained_parameters:3e} parameters out of {full_parameters:3e},"
          f" i.e. {100 * trained_parameters / full_parameters:.2f}%"
      )
  
      # We will unfreeze blocks regularly along the training: one block every `unfreezing_interval` step
      unfreezing_interval = int(
          len(self.dataset_splits.train_data_loader())
          * self.num_epochs
          / (self.model.num_layers + 1)
      )
  
      @self.trainer.on(Events.ITERATION_COMPLETED)
      def unfreeze_layer_if_needed(engine):
          if engine.state.iteration % unfreezing_interval == 0:
              # Which layer should we unfreeze now
              unfreezing_index = self.model.num_layers - (
                  engine.state.iteration // unfreezing_interval
              )
  
              # Let's unfreeze it
              unfreezed = []
              for name, param in self.model.named_parameters():
                  if re.match(
                      r"transformer\.[^\.]*\."
                      + str(unfreezing_index)
                      + r"\.",
                      name,
                  ):
                      unfreezed.append(name)
                      param.require_grad = True
              logger.info(
                  f"Unfreezing block {unfreezing_index} with {unfreezed}"
              )
  
imports: import inspect
  import logging
  import re
  from abc import abstractmethod
  from collections import defaultdict
  from typing import Dict, List, Any, Union, Tuple
  import numpy
  import torch
  import torch.nn
  import torch.optim
  from ignite.contrib.handlers.tensorboard_logger import TensorboardLogger, OutputHandler, OptimizerParamsHandler, WeightsScalarHandler, WeightsHistHandler, GradsScalarHandler
  from ignite.contrib.handlers.tqdm_logger import ProgressBar
  from ignite.engine import Events
  from ignite.engine.engine import Engine
  from ignite.metrics import Loss, Metric, RunningAverage, MetricsLambda, Accuracy
  from ignite.utils import convert_tensor
  from transfer_nlp.loaders.loaders import DatasetSplits
  from transfer_nlp.plugins.config import register_plugin
  from transfer_nlp.plugins.regularizers import RegularizerABC
  from transfer_nlp.plugins.trainer_abc import TrainerABC
label_desc: Use image node_id 4 for calling the SingleTaskFineTuner obj's underlying member method code with example usage: obj.gradual_unfreezing() without return types