code: def step(self, closure: Optional[Callable] = None) -> Any:
      loss = None
      if closure is not None:
          loss = closure()
  
      for group in self.param_groups:
          for p in group["params"]:
              if p.grad is None:
                  continue
  
              grad = p.grad.data
              beta1, beta2 = group["betas"]
              nesterov = group["nesterov"]
  
              state = self.state[p]
              if len(state) == 0:
                  state["step"] = 0
                  state["exp_avg"] = torch.zeros_like(p.data)
                  state["exp_avg_sq"] = torch.zeros_like(p.data)
  
              # Adam
              exp_avg, exp_avg_sq = (
                  state["exp_avg"],
                  state["exp_avg_sq"],
              )
  
              state["step"] += 1
              bias_correction1 = 1.0 - beta1 ** state["step"]
              bias_correction2 = 1.0 - beta2 ** state["step"]
              bias_correction2 = math.sqrt(bias_correction2)
  
              exp_avg.mul_(beta1).add_(grad, alpha=1.0 - beta1)
              exp_avg_sq.mul_(beta2).addcmul_(
                  grad, grad, value=1.0 - beta2
              )
  
              denom = (exp_avg_sq.sqrt() / bias_correction2).add_(
                  group["eps"]
              )
              step_size = group["lr"] / bias_correction1
  
              if nesterov:
                  perturb = (
                      beta1 * exp_avg + (1 - beta1) * grad
                  ) / denom
              else:
                  perturb = exp_avg / denom
  
              # Projection
              wd_ratio = 1.0
              if len(p.shape) > 1:
                  perturb, wd_ratio = projection(
                      p,
                      grad,
                      perturb,
                      group["delta"],
                      group["wd_ratio"],
                      group["eps"],
                  )
  
              # Weight decay
              if group["weight_decay"] > 0.0:
                  p.data.mul_(
                      1.0
                      - group["lr"] * group["weight_decay"] * wd_ratio
                  )
  
              # Step
              p.data.add_(perturb, alpha=-step_size)
  
      return loss
  
imports: import math
  import torch
  import torch.nn.functional
  from torch import Tensor
  from typing import Any
  from typing import Dict
  from typing import Type
  from typing import Tuple
  from typing import Callable
  from typing import Iterable
  from typing import Optional
  from torch.optim.optimizer import Optimizer
label_desc: Use image node_id 2 for calling the AdamP obj's underlying member method code with example usage: obj.step(closure) and returns: loss