code: def __init__(
      self,
      params,
      lr=0.0005,
      alpha=0.5,
      k=5,
      N_sma_threshold=5,
      betas=(0.9, 0.999),
      eps=1e-5,
      weight_decay=0.000,
  ):
      # parameter checks
      if not 0.0 <= alpha <= 1.0:
          raise ValueError(f"Invalid slow update rate: {alpha}")
      if not 1 <= k:
          raise ValueError(f"Invalid lookahead steps: {k}")
      if not lr > 0:
          raise ValueError(f"Invalid Learning Rate: {lr}")
      if not eps > 0:
          raise ValueError(f"Invalid eps: {eps}")
  
      # parameter comments:
      # beta1 (momentum) of .95 seems to work better than .90...
      # N_sma_threshold of 5 seems better in testing than 4.
      # In both cases, worth testing on your dataset (.90 vs .95, 4 vs 5) to make sure which works best for you.
      # @TODO Implement the above testing with AX ^
  
      # prep defaults and init torch.optim base
      defaults = dict(
          lr=lr,
          alpha=alpha,
          k=k,
          betas=betas,
          N_sma_threshold=N_sma_threshold,
          eps=eps,
          weight_decay=weight_decay,
      )
      super().__init__(params, defaults)
  
      # Since we keep LR the same for all param groups,
      # store it here for now for quick&easy access if we want to know it
      self.lr = lr
  
      # adjustable threshold
      self.N_sma_threshold = N_sma_threshold
  
      # look ahead params
      self.initial_lr = lr
      self.alpha = alpha
      self.k = k
  
      # radam buffer for state
      self.radam_buffer = [[None, None, None] for ind in range(10)]
  
file_path: lightwood/lightwood/mixer/helpers/ranger.py
imports: import math
  import torch
  from torch.optim.optimizer import Optimizer
label_desc: Use image node_id 1 to create a new Ranger object from inherited base classes: Optimizer with example: obj = Ranger(params, lr, alpha, k, N_sma_threshold, betas, eps, weight_decay)