class_docstr: Multi step learning rate decay
  
  Args:
      gamma (float | list): decay factor
      milestones (list): steps at which to decay learning rate
class_docstr_tok: ["Multi","step","learning","rate","decay","Args",":","gamma","(","float","|","list",")",":","decay","factor","milestones","(","list",")",":","steps","at","which","to","decay","learning","rate"]
code: def __call__(
      self, base_lr=None, boundary=None, value=None, step_per_epoch=None
  ):
      if boundary is not None and self.use_warmup:
          boundary.extend(
              [int(step_per_epoch) * i for i in self.milestones]
          )
      else:
          # do not use LinearWarmup
          boundary = [int(step_per_epoch) * i for i in self.milestones]
          value = [base_lr]  # during step[0, boundary[0]] is base_lr
  
      # self.values is setted directly in config
      if self.values is not None:
          assert len(self.milestones) + 1 == len(self.values)
          return optimizer.lr.PiecewiseDecay(boundary, self.values)
  
      # value is computed by self.gamma
      value = value if value is not None else [base_lr]
      for i in self.gamma:
          value.append(base_lr * i)
  
      return optimizer.lr.PiecewiseDecay(boundary, value)
  
imports: from __future__ import absolute_import
  from __future__ import division
  from __future__ import print_function
  import sys
  import math
  import paddle
  import paddle.nn
  import paddle.optimizer
  import paddle.regularizer
  from ppdet.core.workspace import register, serializable
  import copy
  from .adamw import AdamWDL, build_adamwdl
  from ppdet.utils.logger import setup_logger
label_desc: Use image node_id 2 for calling the PiecewiseDecay obj's underlying member method code with example usage: obj.__call__(base_lr, boundary, value, step_per_epoch) and returns: optimizer, optimizer