class_docstr: Cyclic LR Scheduler.
  
  Implement the cyclical learning rate policy (CLR) described in
  https://arxiv.org/pdf/1506.01186.pdf
  
  Different from the original paper, we use cosine annealing rather than
  triangular policy inside a cycle. This improves the performance in the
  3D detection area.
  
  Args:
      by_epoch (bool): Whether to update LR by epoch.
      target_ratio (tuple[float]): Relative ratio of the highest LR and the
          lowest LR to the initial LR.
      cyclic_times (int): Number of cycles during training
      step_ratio_up (float): The ratio of the increasing process of LR in
          the total cycle.
      anneal_strategy (str): {'cos', 'linear'}
          Specifies the annealing strategy: 'cos' for cosine annealing,
          'linear' for linear annealing. Default: 'cos'.
code: def __init__(
      self,
      by_epoch=False,
      target_ratio=(10, 1e-4),
      cyclic_times=1,
      step_ratio_up=0.4,
      anneal_strategy="cos",
      **kwargs,
  ):
      if isinstance(target_ratio, float):
          target_ratio = (target_ratio, target_ratio / 1e5)
      elif isinstance(target_ratio, tuple):
          target_ratio = (
              (target_ratio[0], target_ratio[0] / 1e5)
              if len(target_ratio) == 1
              else target_ratio
          )
      else:
          raise ValueError(
              "target_ratio should be either float "
              f"or tuple, got {type(target_ratio)}"
          )
  
      assert (
          len(target_ratio) == 2
      ), '"target_ratio" must be list or tuple of two floats'
      assert (
          0 <= step_ratio_up < 1.0
      ), '"step_ratio_up" must be in range [0,1)'
  
      self.target_ratio = target_ratio
      self.cyclic_times = cyclic_times
      self.step_ratio_up = step_ratio_up
      self.lr_phases = []  # init lr_phases
      # validate anneal_strategy
      if anneal_strategy not in ["cos", "linear"]:
          raise ValueError(
              'anneal_strategy must be one of "cos" or '
              f'"linear", instead got {anneal_strategy}'
          )
      elif anneal_strategy == "cos":
          self.anneal_func = annealing_cos
      elif anneal_strategy == "linear":
          self.anneal_func = annealing_linear
  
      assert not by_epoch, 'currently only support "by_epoch" = False'
      super(CyclicLrUpdaterHook, self).__init__(by_epoch, **kwargs)
  
imports: import numbers
  from math import cos, pi
  import annotator.uniformer.mmcv
  from .hook import HOOKS, Hook
label_desc: Use image node_id 1 to create a new CyclicLrUpdaterHook object from inherited base classes: LrUpdaterHook with example: obj = CyclicLrUpdaterHook(by_epoch, target_ratio, cyclic_times, step_ratio_up, anneal_strategy)