r"""Implements the AdamW algorithm proposed in `"Decoupled Weight Decay Regularization" `_. This optimizer combines the Adam optimizer with weight decay regularization to prevent overfitting. Args: params (Union[Iterable[Parameter], dict]): Iterabl
| 9 | |
| 10 | |
| 11 | class AdamW(Optimizer): |
| 12 | r"""Implements the AdamW algorithm proposed in `"Decoupled Weight Decay Regularization" <https://arxiv.org/abs/1711.05101>`_. |
| 13 | |
| 14 | This optimizer combines the Adam optimizer with weight decay regularization to prevent overfitting. |
| 15 | |
| 16 | Args: |
| 17 | params (Union[Iterable[Parameter], dict]): Iterable of parameters to optimize or dicts defining |
| 18 | parameter groups. |
| 19 | lr (float): Learning rate. |
| 20 | betas (Tuple[float, float], optional): Coefficients used for computing running averages of gradient |
| 21 | and its square. Default: (0.9, 0.999). |
| 22 | eps (float, optional): Term added to the denominator to improve numerical stability. Default: 1e-8. |
| 23 | weight_decay (float, optional): Weight decay (L2 penalty). Default: 1e-2. |
| 24 | |
| 25 | Returns: |
| 26 | An instance of the AdamW optimizer. |
| 27 | """ |
| 28 | |
| 29 | def __init__( |
| 30 | self, |
| 31 | params: Union[Iterable[Parameter], dict], |
| 32 | lr: float, |
| 33 | betas: Tuple[float, float] = (0.9, 0.999), |
| 34 | eps: float = 1e-8, |
| 35 | weight_decay: float = 1e-2, |
| 36 | ): |
| 37 | if lr < 0.0: |
| 38 | raise ValueError("Invalid learning rate: {}".format(lr)) |
| 39 | if weight_decay < 0.0: |
| 40 | raise ValueError("Invalid weight_decay value: {}".format(weight_decay)) |
| 41 | if not 0.0 <= betas[0] < 1.0: |
| 42 | raise ValueError("Invalid beta parameter at index 0: {}".format(betas[0])) |
| 43 | if not 0.0 <= betas[1] < 1.0: |
| 44 | raise ValueError("Invalid beta parameter at index 1: {}".format(betas[1])) |
| 45 | |
| 46 | defaults = dict(lr=lr, weight_decay=weight_decay, betas=betas, eps=eps) |
| 47 | super().__init__(params, defaults) |
| 48 | self._disable_type_convert = True |
| 49 | |
| 50 | def _create_state(self, param_group): |
| 51 | for param in param_group["params"]: |
| 52 | self._add_state(param, "exp_avg") |
| 53 | self._add_state(param, "exp_avg_sq") |
| 54 | self._add_state(param, "step", initializer=0.0) |
| 55 | |
| 56 | def _updates(self, param_group): |
| 57 | lr = param_group["lr"] |
| 58 | weight_decay = param_group["weight_decay"] |
| 59 | eps = param_group["eps"] |
| 60 | beta0, beta1 = param_group["betas"] |
| 61 | |
| 62 | def make_scalar(val): |
| 63 | return tensor(val, dtype="float32") |
| 64 | |
| 65 | # since `conver_inputs` is disabled for param updates, |
| 66 | # scalar should be explicitly tansforred to tensor |
| 67 | |
| 68 | _lr, _neg_lr = map(make_scalar, (lr, -lr)) |