class_docstr: This class implements the base logic for writing your own Finetuning Callback.
  
  .. warning::  This is an :ref:`experimental <versioning:Experimental API>` feature.
  
  Override ``freeze_before_training`` and ``finetune_function`` methods with your own logic.
  
  ``freeze_before_training``: This method is called before ``configure_optimizers``
      and should be used to freeze any modules parameters.
  
  ``finetune_function``: This method is called on every train epoch start and should be used to
      ``unfreeze`` any parameters. Those parameters need to be added in a new ``param_group``
      within the optimizer.
  
  .. note:: Make sure to filter the parameters based on ``requires_grad``.
  
  Example::
  
      >>> from torch.optim import Adam
      >>> class MyModel(pl.LightningModule):
      ...     def configure_optimizer(self):
      ...         # Make sure to filter the parameters based on `requires_grad`
      ...         return Adam(filter(lambda p: p.requires_grad, self.parameters()))
      ...
      >>> class FeatureExtractorFreezeUnfreeze(BaseFinetuning):
      ...     def __init__(self, unfreeze_at_epoch=10):
      ...         super().__init__()
      ...         self._unfreeze_at_epoch = unfreeze_at_epoch
      ...
      ...     def freeze_before_training(self, pl_module):
      ...         # freeze any module you want
      ...         # Here, we are freezing `feature_extractor`
      ...         self.freeze(pl_module.feature_extractor)
      ...
      ...     def finetune_function(self, pl_module, current_epoch, optimizer):
      ...         # When `current_epoch` is 10, feature_extractor will start training.
      ...         if current_epoch == self._unfreeze_at_epoch:
      ...             self.unfreeze_and_add_param_group(
      ...                 modules=pl_module.feature_extractor,
      ...                 optimizer=optimizer,
      ...                 train_bn=True,
      ...             )
code: def on_fit_start(
      self, trainer: "pl.Trainer", pl_module: "pl.LightningModule"
  ) -> None:
      # restore the param_groups created during the previous training.
      if self._restarting:
          named_parameters = dict(pl_module.named_parameters())
          for opt_idx, optimizer in enumerate(trainer.optimizers):
              param_groups = self._apply_mapping_to_param_groups(
                  self._internal_optimizer_metadata[opt_idx],
                  named_parameters,
              )
              optimizer.param_groups = param_groups
          self._restarting = False
  
imports: import logging
  from typing import Any, Callable, Dict, Generator, Iterable, List, Optional, Union
  import torch
  from torch.nn import Module, ModuleDict
  from torch.nn.modules.batchnorm import _BatchNorm
  from torch.optim.optimizer import Optimizer
  from typing_extensions import override
  import lightning.pytorch
  from lightning.pytorch.callbacks.callback import Callback
  from lightning.pytorch.utilities.exceptions import MisconfigurationException
  from lightning.pytorch.utilities.rank_zero import rank_zero_warn
label_desc: Use image node_id 4 for calling the BaseFinetuning obj's underlying member method code with example usage: obj.on_fit_start(trainer, pl_module) without return types