class_docstr: Finetune a backbone model based on a learning rate user-defined scheduling.
  
  When the backbone learning rate reaches the current model learning rate
  and ``should_align`` is set to True, it will align with it for the rest of the training.
  
  Args:
      unfreeze_backbone_at_epoch: Epoch at which the backbone will be unfreezed.
      lambda_func: Scheduling function for increasing backbone learning rate.
      backbone_initial_ratio_lr:
          Used to scale down the backbone learning rate compared to rest of model
      backbone_initial_lr: Optional, Initial learning rate for the backbone.
          By default, we will use ``current_learning /  backbone_initial_ratio_lr``
      should_align: Whether to align with current learning rate when backbone learning
          reaches it.
      initial_denom_lr: When unfreezing the backbone, the initial learning rate will
          ``current_learning_rate /  initial_denom_lr``.
      train_bn: Whether to make Batch Normalization trainable.
      verbose: Display current learning rate for model and backbone
      rounding: Precision for displaying learning rate
  
  Example::
  
      >>> from lightning.pytorch import Trainer
      >>> from lightning.pytorch.callbacks import BackboneFinetuning
      >>> multiplicative = lambda epoch: 1.5
      >>> backbone_finetuning = BackboneFinetuning(200, multiplicative)
      >>> trainer = Trainer(callbacks=[backbone_finetuning])
docstr: Called when the epoch begins.
code: def finetune_function(
      self,
      pl_module: "pl.LightningModule",
      epoch: int,
      optimizer: Optimizer,
  ) -> None:
      """Called when the epoch begins."""
      if epoch == self.unfreeze_backbone_at_epoch:
          current_lr = optimizer.param_groups[0]["lr"]
          initial_backbone_lr = (
              self.backbone_initial_lr
              if self.backbone_initial_lr is not None
              else current_lr * self.backbone_initial_ratio_lr
          )
          self.previous_backbone_lr = initial_backbone_lr
          self.unfreeze_and_add_param_group(
              pl_module.backbone,
              optimizer,
              initial_backbone_lr,
              train_bn=self.train_bn,
              initial_denom_lr=self.initial_denom_lr,
          )
          if self.verbose:
              log.info(
                  f"Current lr: {round(current_lr, self.rounding)}, "
                  f"Backbone lr: {round(initial_backbone_lr, self.rounding)}"
              )
  
      elif epoch > self.unfreeze_backbone_at_epoch:
          current_lr = optimizer.param_groups[0]["lr"]
          next_current_backbone_lr = (
              self.lambda_func(epoch + 1) * self.previous_backbone_lr
          )
          next_current_backbone_lr = (
              current_lr
              if (
                  self.should_align
                  and next_current_backbone_lr > current_lr
              )
              else next_current_backbone_lr
          )
          optimizer.param_groups[-1]["lr"] = next_current_backbone_lr
          self.previous_backbone_lr = next_current_backbone_lr
          if self.verbose:
              log.info(
                  f"Current lr: {round(current_lr, self.rounding)}, "
                  f"Backbone lr: {round(next_current_backbone_lr, self.rounding)}"
              )
  
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 6 for calling the BackboneFinetuning obj's underlying member method code with example usage: obj.finetune_function(pl_module, epoch, optimizer) without return types