code: def create_lr_scheduler(
      optimizer,
      num_step: int,
      epochs: int,
      warmup=True,
      warmup_epochs=1,
      warmup_factor=1e-3,
  ):
      assert num_step > 0 and epochs > 0
      if warmup is False:
          warmup_epochs = 0
  
      def f(x):
          """
          根据step数返回一个学习率倍率因子，
          注意在训练开始之前，pytorch会提前调用一次lr_scheduler.step()方法
          """
          if warmup is True and x <= (warmup_epochs * num_step):
              alpha = float(x) / (warmup_epochs * num_step)
              # warmup过程中lr倍率因子从warmup_factor -> 1
              return warmup_factor * (1 - alpha) + alpha
          else:
              # warmup后lr倍率因子从1 -> 0
              # 参考deeplab_v2: Learning rate policy
              return (
                  1
                  - (x - warmup_epochs * num_step)
                  / ((epochs - warmup_epochs) * num_step)
              ) ** 0.9
  
      return torch.optim.lr_scheduler.LambdaLR(optimizer, lr_lambda=f)
  
file_path: deep-learning-for-image-processing/pytorch_segmentation/unet/train_utils/train_and_eval.py
imports: import torch
  from torch import nn
  import train_utils.distributed_utils
  from .dice_coefficient_loss import dice_loss, build_target
label_desc: Use image node_id 4 for calling a global function with example usage: create_lr_scheduler(optimizer, num_step, epochs, warmup, warmup_epochs, warmup_factor) and returns: torch, unknown, unknown