pytorch-optimizer 2.6.0__tar.gz → 2.7.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/PKG-INFO +9 -1
  2. {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/README.rst +8 -0
  3. {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pyproject.toml +2 -1
  4. {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/__init__.py +7 -5
  5. {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/adabelief.py +69 -53
  6. {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/adabound.py +30 -26
  7. {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/adafactor.py +61 -28
  8. {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/adai.py +11 -9
  9. {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/adamp.py +36 -11
  10. {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/adams.py +39 -10
  11. {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/adan.py +44 -28
  12. pytorch_optimizer-2.7.0/pytorch_optimizer/optimizer/adanorm.py +146 -0
  13. {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/adapnm.py +45 -17
  14. {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/alig.py +8 -11
  15. {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/apollo.py +9 -8
  16. {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/dadapt.py +211 -26
  17. pytorch_optimizer-2.6.0/pytorch_optimizer/optimizer/diffrgrad.py → pytorch_optimizer-2.7.0/pytorch_optimizer/optimizer/diffgrad.py +83 -39
  18. {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/lamb.py +93 -26
  19. {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/lars.py +8 -7
  20. {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/lion.py +7 -3
  21. {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/novograd.py +12 -7
  22. {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/pnm.py +2 -5
  23. {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/radam.py +53 -33
  24. {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/ranger.py +59 -35
  25. {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/ranger21.py +4 -5
  26. pytorch_optimizer-2.7.0/pytorch_optimizer/optimizer/rotograd.py +448 -0
  27. {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/shampoo.py +20 -17
  28. {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/sm3.py +11 -28
  29. {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/utils.py +37 -4
  30. pytorch_optimizer-2.6.0/pytorch_optimizer/optimizer/diffgrad.py +0 -118
  31. pytorch_optimizer-2.6.0/pytorch_optimizer/optimizer/ralamb.py +0 -187
  32. {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/LICENSE +0 -0
  33. {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/base/__init__.py +0 -0
  34. {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/base/exception.py +0 -0
  35. {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/base/optimizer.py +0 -0
  36. {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/base/scheduler.py +0 -0
  37. {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/base/types.py +0 -0
  38. {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/experimental/__init__.py +0 -0
  39. {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/experimental/deberta_v3_lr_scheduler.py +0 -0
  40. {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/lr_scheduler/__init__.py +0 -0
  41. {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/lr_scheduler/chebyshev.py +0 -0
  42. {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/lr_scheduler/cosine_anealing.py +0 -0
  43. {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/lr_scheduler/linear_warmup.py +0 -0
  44. {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/lr_scheduler/proportion.py +0 -0
  45. {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/__init__.py +0 -0
  46. {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/agc.py +0 -0
  47. {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/fp16.py +0 -0
  48. {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/gc.py +0 -0
  49. {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/gsam.py +0 -0
  50. {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/lookahead.py +0 -0
  51. {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/madgrad.py +0 -0
  52. {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/nero.py +0 -0
  53. {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/pcgrad.py +0 -0
  54. {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/sam.py +0 -0
  55. {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/sgdp.py +0 -0
  56. {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/shampoo_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pytorch-optimizer
3
- Version: 2.6.0
3
+ Version: 2.7.0
4
4
  Summary: optimizer & lr scheduler implementations in PyTorch with clean-code, strict types. Also, including useful optimization ideas.
5
5
  Home-page: https://github.com/kozistr/pytorch_optimizer
6
6
  License: Apache-2.0
@@ -183,6 +183,10 @@ You can check the supported optimizers & lr schedulers.
183
183
  +--------------+-------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------+
184
184
  | SM3 | *Memory-Efficient Adaptive Optimization* | `github <https://github.com/google-research/google-research/tree/master/sm3>`__ | `https://arxiv.org/abs/1901.11150 <https://arxiv.org/abs/1901.11150>`__ |
185
185
  +--------------+-------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------+
186
+ | AdaNorm | *Adaptive Gradient Norm Correction based Optimizer for CNNs* | `github <https://github.com/shivram1987/AdaNorm>`__ | `https://arxiv.org/abs/2210.06364 <https://arxiv.org/abs/2210.06364>`__ |
187
+ +--------------+-------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------+
188
+ | RotoGrad | *Gradient Homogenization in Multitask Learning* | `github <https://github.com/adrianjav/rotograd>`__ | `https://openreview.net/pdf?id=T8wHz4rnuGL <https://openreview.net/pdf?id=T8wHz4rnuGL>`__ |
189
+ +--------------+-------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------+
186
190
 
187
191
  Useful Resources
188
192
  ----------------
@@ -390,6 +394,10 @@ Citations
390
394
 
391
395
  `SM3 <https://ui.adsabs.harvard.edu/abs/2019arXiv190111150A/exportcitation>`__
392
396
 
397
+ `AdaNorm <https://github.com/shivram1987/AdaNorm/tree/main#citation>`__
398
+
399
+ `RotoGrad <https://github.com/adrianjav/rotograd#citing>`__
400
+
393
401
  Citation
394
402
  --------
395
403
 
@@ -140,6 +140,10 @@ You can check the supported optimizers & lr schedulers.
140
140
  +--------------+-------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------+
141
141
  | SM3 | *Memory-Efficient Adaptive Optimization* | `github <https://github.com/google-research/google-research/tree/master/sm3>`__ | `https://arxiv.org/abs/1901.11150 <https://arxiv.org/abs/1901.11150>`__ |
142
142
  +--------------+-------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------+
143
+ | AdaNorm | *Adaptive Gradient Norm Correction based Optimizer for CNNs* | `github <https://github.com/shivram1987/AdaNorm>`__ | `https://arxiv.org/abs/2210.06364 <https://arxiv.org/abs/2210.06364>`__ |
144
+ +--------------+-------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------+
145
+ | RotoGrad | *Gradient Homogenization in Multitask Learning* | `github <https://github.com/adrianjav/rotograd>`__ | `https://openreview.net/pdf?id=T8wHz4rnuGL <https://openreview.net/pdf?id=T8wHz4rnuGL>`__ |
146
+ +--------------+-------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------+
143
147
 
144
148
  Useful Resources
145
149
  ----------------
@@ -347,6 +351,10 @@ Citations
347
351
 
348
352
  `SM3 <https://ui.adsabs.harvard.edu/abs/2019arXiv190111150A/exportcitation>`__
349
353
 
354
+ `AdaNorm <https://github.com/shivram1987/AdaNorm/tree/main#citation>`__
355
+
356
+ `RotoGrad <https://github.com/adrianjav/rotograd#citing>`__
357
+
350
358
  Citation
351
359
  --------
352
360
 
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "pytorch_optimizer"
3
- version = "2.6.0"
3
+ version = "2.7.0"
4
4
  description = "optimizer & lr scheduler implementations in PyTorch with clean-code, strict types. Also, including useful optimization ideas."
5
5
  license = "Apache-2.0"
6
6
  authors = ["kozistr <kozistr@gmail.com>"]
@@ -103,6 +103,7 @@ target-version = "py39"
103
103
  omit = [
104
104
  "./pytorch_optimizer/optimizer/gsam.py",
105
105
  "./pytorch_optimizer/optimizer/fp16.py",
106
+ "./pytorch_optimizer/optimizer/rotograd.py",
106
107
  ]
107
108
 
108
109
  [build-system]
@@ -23,13 +23,13 @@ from pytorch_optimizer.optimizer.adai import Adai
23
23
  from pytorch_optimizer.optimizer.adamp import AdamP
24
24
  from pytorch_optimizer.optimizer.adams import AdamS
25
25
  from pytorch_optimizer.optimizer.adan import Adan
26
+ from pytorch_optimizer.optimizer.adanorm import AdaNorm
26
27
  from pytorch_optimizer.optimizer.adapnm import AdaPNM
27
28
  from pytorch_optimizer.optimizer.agc import agc
28
29
  from pytorch_optimizer.optimizer.alig import AliG
29
30
  from pytorch_optimizer.optimizer.apollo import Apollo
30
- from pytorch_optimizer.optimizer.dadapt import DAdaptAdaGrad, DAdaptAdam, DAdaptSGD
31
+ from pytorch_optimizer.optimizer.dadapt import DAdaptAdaGrad, DAdaptAdam, DAdaptAdan, DAdaptSGD
31
32
  from pytorch_optimizer.optimizer.diffgrad import DiffGrad
32
- from pytorch_optimizer.optimizer.diffrgrad import DiffRGrad
33
33
  from pytorch_optimizer.optimizer.fp16 import DynamicLossScaler, SafeFP16Optimizer
34
34
  from pytorch_optimizer.optimizer.gc import centralize_gradient
35
35
  from pytorch_optimizer.optimizer.gsam import GSAM
@@ -43,9 +43,9 @@ from pytorch_optimizer.optimizer.novograd import NovoGrad
43
43
  from pytorch_optimizer.optimizer.pcgrad import PCGrad
44
44
  from pytorch_optimizer.optimizer.pnm import PNM
45
45
  from pytorch_optimizer.optimizer.radam import RAdam
46
- from pytorch_optimizer.optimizer.ralamb import RaLamb
47
46
  from pytorch_optimizer.optimizer.ranger import Ranger
48
47
  from pytorch_optimizer.optimizer.ranger21 import Ranger21
48
+ from pytorch_optimizer.optimizer.rotograd import RotoGrad
49
49
  from pytorch_optimizer.optimizer.sam import SAM
50
50
  from pytorch_optimizer.optimizer.sgdp import SGDP
51
51
  from pytorch_optimizer.optimizer.shampoo import ScalableShampoo, Shampoo
@@ -69,8 +69,10 @@ from pytorch_optimizer.optimizer.utils import (
69
69
  clip_grad_norm,
70
70
  disable_running_stats,
71
71
  enable_running_stats,
72
+ get_global_gradient_norm,
72
73
  get_optimizer_parameters,
73
74
  normalize_gradient,
75
+ reduce_max_except_dim,
74
76
  unit_norm,
75
77
  )
76
78
 
@@ -82,14 +84,12 @@ OPTIMIZER_LIST: List[OPTIMIZER] = [
82
84
  Adan,
83
85
  AdaPNM,
84
86
  DiffGrad,
85
- DiffRGrad,
86
87
  Lamb,
87
88
  LARS,
88
89
  MADGRAD,
89
90
  Nero,
90
91
  PNM,
91
92
  RAdam,
92
- RaLamb,
93
93
  Ranger,
94
94
  Ranger21,
95
95
  SGDP,
@@ -98,6 +98,7 @@ OPTIMIZER_LIST: List[OPTIMIZER] = [
98
98
  DAdaptAdaGrad,
99
99
  DAdaptAdam,
100
100
  DAdaptSGD,
101
+ DAdaptAdan,
101
102
  AdamS,
102
103
  AdaFactor,
103
104
  Apollo,
@@ -105,6 +106,7 @@ OPTIMIZER_LIST: List[OPTIMIZER] = [
105
106
  Lion,
106
107
  AliG,
107
108
  SM3,
109
+ AdaNorm,
108
110
  ]
109
111
  OPTIMIZERS: Dict[str, OPTIMIZER] = {str(optimizer.__name__).lower(): optimizer for optimizer in OPTIMIZER_LIST}
110
112
 
@@ -21,7 +21,9 @@ class AdaBelief(Optimizer, BaseOptimizer):
21
21
  :param rectify: bool. perform the rectified update similar to RAdam.
22
22
  :param degenerated_to_sgd: bool. perform SGD update when variance of gradient is high.
23
23
  :param amsgrad: bool. whether to use the AMSBound variant.
24
- :param adamd_debias_term: bool. Only correct the denominator to avoid inflating step sizes early in training.
24
+ :param r: float. EMA factor. between 0.9 ~ 0.99 is preferred.
25
+ :param adanorm: bool. whether to use the AdaNorm variant.
26
+ :param adam_debias: bool. Only correct the denominator to avoid inflating step sizes early in training.
25
27
  :param eps: float. term added to the denominator to improve numerical stability.
26
28
  """
27
29
 
@@ -37,18 +39,16 @@ class AdaBelief(Optimizer, BaseOptimizer):
37
39
  rectify: bool = True,
38
40
  degenerated_to_sgd: bool = True,
39
41
  amsgrad: bool = False,
40
- adamd_debias_term: bool = False,
42
+ r: float = 0.95,
43
+ adanorm: bool = False,
44
+ adam_debias: bool = False,
41
45
  eps: float = 1e-16,
42
46
  ):
43
47
  self.lr = lr
44
48
  self.betas = betas
45
49
  self.weight_decay = weight_decay
46
50
  self.n_sma_threshold = n_sma_threshold
47
- self.weight_decouple = weight_decouple
48
- self.fixed_decay = fixed_decay
49
- self.rectify = rectify
50
51
  self.degenerated_to_sgd = degenerated_to_sgd
51
- self.adamd_debias_term = adamd_debias_term
52
52
  self.eps = eps
53
53
 
54
54
  self.validate_parameters()
@@ -56,12 +56,18 @@ class AdaBelief(Optimizer, BaseOptimizer):
56
56
  defaults: DEFAULTS = {
57
57
  'lr': lr,
58
58
  'betas': betas,
59
- 'eps': eps,
60
59
  'weight_decay': weight_decay,
60
+ 'weight_decouple': weight_decouple,
61
+ 'fixed_decay': fixed_decay,
62
+ 'rectify': rectify,
61
63
  'amsgrad': amsgrad,
62
- 'adamd_debias_term': adamd_debias_term,
63
- 'buffer': [[None, None, None] for _ in range(10)],
64
+ 'adanorm': adanorm,
65
+ 'adam_debias': adam_debias,
66
+ 'eps': eps,
64
67
  }
68
+ if adanorm:
69
+ defaults.update({'r': r})
70
+
65
71
  super().__init__(params, defaults)
66
72
 
67
73
  def validate_parameters(self):
@@ -76,12 +82,14 @@ class AdaBelief(Optimizer, BaseOptimizer):
76
82
  @torch.no_grad()
77
83
  def reset(self):
78
84
  for group in self.param_groups:
85
+ group['step'] = 0
79
86
  for p in group['params']:
80
87
  state = self.state[p]
81
88
 
82
- state['step'] = 0
83
89
  state['exp_avg'] = torch.zeros_like(p)
84
90
  state['exp_avg_var'] = torch.zeros_like(p)
91
+ if group['adanorm']:
92
+ state['exp_grad_norm'] = torch.zeros((1,), dtype=p.dtype, device=p.device)
85
93
  if group['amsgrad']:
86
94
  state['max_exp_avg_var'] = torch.zeros_like(p)
87
95
 
@@ -93,11 +101,21 @@ class AdaBelief(Optimizer, BaseOptimizer):
93
101
  loss = closure()
94
102
 
95
103
  for group in self.param_groups:
104
+ if 'step' in group:
105
+ group['step'] += 1
106
+ else:
107
+ group['step'] = 1
108
+
96
109
  beta1, beta2 = group['betas']
97
- weight_decay: float = group['weight_decay']
110
+ weight_decay = group['weight_decay']
111
+
112
+ bias_correction1 = 1.0 - beta1 ** group['step']
113
+ bias_correction2_sq = math.sqrt(1.0 - beta2 ** group['step'])
98
114
 
99
- if self.rectify:
115
+ if group['rectify']:
100
116
  n_sma_max: float = 2.0 / (1.0 - beta2) - 1.0
117
+ beta2_t: float = beta2 ** group['step']
118
+ n_sma: float = n_sma_max - 2 * group['step'] * beta2_t / (1.0 - beta2_t)
101
119
 
102
120
  for p in group['params']:
103
121
  if p.grad is None:
@@ -109,70 +127,68 @@ class AdaBelief(Optimizer, BaseOptimizer):
109
127
 
110
128
  state = self.state[p]
111
129
  if len(state) == 0:
112
- state['step'] = 0
113
130
  state['exp_avg'] = torch.zeros_like(p)
114
131
  state['exp_avg_var'] = torch.zeros_like(p)
132
+ if group['adanorm']:
133
+ state['exp_grad_norm'] = torch.zeros((1,), dtype=grad.dtype, device=grad.device)
115
134
  if group['amsgrad']:
116
135
  state['max_exp_avg_var'] = torch.zeros_like(p)
117
136
 
118
- if self.weight_decouple:
119
- p.mul_(1.0 - (group['lr'] * weight_decay if not self.fixed_decay else weight_decay))
137
+ if group['weight_decouple']:
138
+ p.mul_(1.0 - group['weight_decay'] * (1.0 if group['fixed_decay'] else group['lr']))
120
139
  elif weight_decay > 0.0:
121
140
  grad.add_(p, alpha=weight_decay)
122
141
 
123
- state['step'] += 1
124
142
  exp_avg, exp_avg_var = state['exp_avg'], state['exp_avg_var']
125
143
 
126
- bias_correction1 = 1.0 - beta1 ** state['step']
127
- bias_correction2_sq = math.sqrt(1.0 - beta2 ** state['step'])
144
+ s_grad = grad
145
+ if group['adanorm']:
146
+ grad_norm = torch.linalg.norm(grad)
128
147
 
129
- exp_avg.mul_(beta1).add_(grad, alpha=1.0 - beta1)
130
- grad_residual = grad - exp_avg
131
- exp_avg_var.mul_(beta2).addcmul_(grad_residual, grad_residual, value=1.0 - beta2).add_(group['eps'])
148
+ exp_grad_norm = state['exp_grad_norm']
149
+ exp_grad_norm.mul_(group['r']).add_(grad_norm, alpha=1.0 - group['r'])
150
+
151
+ if exp_grad_norm > grad_norm:
152
+ s_grad *= exp_grad_norm / grad_norm
153
+
154
+ exp_avg.mul_(beta1).add_(s_grad, alpha=1.0 - beta1)
155
+ grad_residual = s_grad - exp_avg
156
+ exp_avg_var.mul_(beta2).addcmul_(grad_residual, grad_residual, value=1.0 - beta2).add_(self.eps)
132
157
 
133
158
  if group['amsgrad']:
134
159
  max_exp_avg_var = state['max_exp_avg_var']
135
160
  torch.max(max_exp_avg_var, exp_avg_var, out=max_exp_avg_var)
136
- de_nom = max_exp_avg_var.sqrt()
161
+ de_nom = max_exp_avg_var.add(self.eps).sqrt()
137
162
  else:
138
- de_nom = exp_avg_var.sqrt()
139
- de_nom.div_(bias_correction2_sq).add_(group['eps'])
163
+ de_nom = exp_avg_var.add(self.eps).sqrt()
164
+
165
+ de_nom.div_(bias_correction2_sq).add_(self.eps)
140
166
 
141
- if not self.rectify:
142
- step_size: float = group['lr'] if group['adamd_debias_term'] else group['lr'] / bias_correction1
167
+ if not group['rectify']:
168
+ step_size: float = group['lr'] if group['adam_debias'] else group['lr'] / bias_correction1
143
169
  p.addcdiv_(exp_avg, de_nom, value=-step_size)
144
170
  continue
145
171
 
146
- buffered = group['buffer'][state['step'] % 10]
147
- if state['step'] == buffered[0]:
148
- n_sma, step_size = buffered[1], buffered[2]
172
+ if n_sma >= self.n_sma_threshold:
173
+ step_size = math.sqrt(
174
+ (1 - beta2_t)
175
+ * (n_sma - 4)
176
+ / (n_sma_max - 4)
177
+ * (n_sma - 2)
178
+ / n_sma
179
+ * n_sma_max
180
+ / (n_sma_max - 2)
181
+ )
182
+ elif self.degenerated_to_sgd:
183
+ step_size = 1.0
149
184
  else:
150
- buffered[0] = state['step']
151
- beta2_t = beta2 ** state['step']
152
- n_sma = n_sma_max - 2 * state['step'] * beta2_t / (1 - beta2_t)
153
- buffered[1] = n_sma
154
-
155
- if n_sma >= self.n_sma_threshold:
156
- step_size = math.sqrt(
157
- (1 - beta2_t)
158
- * (n_sma - 4)
159
- / (n_sma_max - 4)
160
- * (n_sma - 2)
161
- / n_sma
162
- * n_sma_max
163
- / (n_sma_max - 2)
164
- )
165
- if not group['adamd_debias_term']:
166
- step_size /= bias_correction1
167
- elif self.degenerated_to_sgd:
168
- step_size = 1.0 / bias_correction1
169
- else:
170
- step_size = -1
171
-
172
- buffered[2] = step_size
185
+ step_size = -1
186
+
187
+ if not group['adam_debias']:
188
+ step_size /= bias_correction1
173
189
 
174
190
  if n_sma >= self.n_sma_threshold:
175
- de_nom = exp_avg_var.sqrt().add_(group['eps'])
191
+ de_nom = exp_avg_var.sqrt().add_(self.eps)
176
192
  p.addcdiv_(exp_avg, de_nom, value=-step_size * group['lr'])
177
193
  elif step_size > 0:
178
194
  p.add_(exp_avg, alpha=-step_size * group['lr'])
@@ -21,7 +21,7 @@ class AdaBound(Optimizer, BaseOptimizer):
21
21
  :param weight_decouple: bool. the optimizer uses decoupled weight decay as in AdamW.
22
22
  :param fixed_decay: bool. fix weight decay.
23
23
  :param amsbound: bool. whether to use the AMSBound variant.
24
- :param adamd_debias_term: bool. Only correct the denominator to avoid inflating step sizes early in training.
24
+ :param adam_debias_term: bool. Only correct the denominator to avoid inflating step sizes early in training.
25
25
  :param eps: float. term added to the denominator to improve numerical stability.
26
26
  """
27
27
 
@@ -36,14 +36,12 @@ class AdaBound(Optimizer, BaseOptimizer):
36
36
  weight_decouple: bool = True,
37
37
  fixed_decay: bool = False,
38
38
  amsbound: bool = False,
39
- adamd_debias_term: bool = False,
39
+ adam_debias: bool = False,
40
40
  eps: float = 1e-8,
41
41
  ):
42
42
  self.lr = lr
43
43
  self.betas = betas
44
44
  self.weight_decay = weight_decay
45
- self.weight_decouple = weight_decouple
46
- self.fixed_decay = fixed_decay
47
45
  self.eps = eps
48
46
 
49
47
  self.validate_parameters()
@@ -54,8 +52,10 @@ class AdaBound(Optimizer, BaseOptimizer):
54
52
  'final_lr': final_lr,
55
53
  'gamma': gamma,
56
54
  'weight_decay': weight_decay,
55
+ 'weight_decouple': weight_decouple,
56
+ 'fixed_decay': fixed_decay,
57
57
  'amsbound': amsbound,
58
- 'adamd_debias_term': adamd_debias_term,
58
+ 'adam_debias': adam_debias,
59
59
  'eps': eps,
60
60
  }
61
61
  super().__init__(params, defaults)
@@ -91,7 +91,20 @@ class AdaBound(Optimizer, BaseOptimizer):
91
91
  loss = closure()
92
92
 
93
93
  for group, base_lr in zip(self.param_groups, self.base_lrs):
94
+ if 'step' in group:
95
+ group['step'] += 1
96
+ else:
97
+ group['step'] = 1
98
+
94
99
  beta1, beta2 = group['betas']
100
+
101
+ bias_correction1 = 1.0 - beta1 ** group['step']
102
+ bias_correction2_sq = math.sqrt(1.0 - beta2 ** group['step'])
103
+
104
+ final_lr = group['final_lr'] * group['lr'] / base_lr
105
+ lower_bound = final_lr * (1 - 1 / (group['gamma'] * group['step'] + 1))
106
+ upper_bound = final_lr * (1 + 1 / (group['gamma'] * group['step']))
107
+
95
108
  for p in group['params']:
96
109
  if p.grad is None:
97
110
  continue
@@ -103,41 +116,32 @@ class AdaBound(Optimizer, BaseOptimizer):
103
116
  state = self.state[p]
104
117
 
105
118
  if len(state) == 0:
106
- state['step'] = 0
107
119
  state['exp_avg'] = torch.zeros_like(p)
108
120
  state['exp_avg_sq'] = torch.zeros_like(p)
109
121
  if group['amsbound']:
110
122
  state['max_exp_avg_sq'] = torch.zeros_like(p)
111
123
 
112
- state['step'] += 1
113
- exp_avg, exp_avg_sq = state['exp_avg'], state['exp_avg_sq']
124
+ if group['weight_decouple']:
125
+ p.mul_(1.0 - group['weight_decay'] * (1.0 if group['fixed_decay'] else group['lr']))
126
+ elif group['weight_decay'] > 0.0:
127
+ grad.add_(p, alpha=group['weight_decay'])
114
128
 
115
- if group['weight_decay'] > 0.0:
116
- if self.weight_decouple:
117
- p.mul_(
118
- 1.0 - (group['weight_decay'] if self.fixed_decay else group['lr'] * group['weight_decay'])
119
- )
120
- else:
121
- grad.add_(p, alpha=group['weight_decay'])
129
+ exp_avg, exp_avg_sq = state['exp_avg'], state['exp_avg_sq']
122
130
 
123
131
  exp_avg.mul_(beta1).add_(grad, alpha=1.0 - beta1)
124
132
  exp_avg_sq.mul_(beta2).addcmul_(grad, grad, value=1.0 - beta2)
125
- if group['amsbound']:
126
- torch.max(state['max_exp_avg_sq'], exp_avg_sq, out=exp_avg_sq)
127
-
128
- de_nom = exp_avg_sq.sqrt().add_(group['eps'])
129
133
 
130
- bias_correction1 = 1.0 - beta1 ** state['step']
131
- bias_correction2_sq = math.sqrt(1.0 - beta2 ** state['step'])
134
+ if group['amsbound']:
135
+ max_exp_avg_sq = state['max_exp_avg_sq']
136
+ torch.max(max_exp_avg_sq, exp_avg_sq, out=max_exp_avg_sq)
137
+ de_nom = max_exp_avg_sq.add(group['eps']).sqrt()
138
+ else:
139
+ de_nom = exp_avg_sq.add(group['eps']).sqrt()
132
140
 
133
141
  step_size = group['lr'] * bias_correction2_sq
134
- if not group['adamd_debias_term']:
142
+ if not group['adam_debias']:
135
143
  step_size /= bias_correction1
136
144
 
137
- final_lr = group['final_lr'] * group['lr'] / base_lr
138
- lower_bound = final_lr * (1 - 1 / (group['gamma'] * state['step'] + 1))
139
- upper_bound = final_lr * (1 + 1 / (group['gamma'] * state['step']))
140
-
141
145
  step_size = torch.full_like(de_nom, step_size)
142
146
  step_size.div_(de_nom).clamp_(lower_bound, upper_bound).mul_(exp_avg)
143
147
 
@@ -18,10 +18,11 @@ class AdaFactor(Optimizer, BaseOptimizer):
18
18
  :param decay_rate: float. coefficient used to compute running averages of square gradient.
19
19
  :param weight_decay: float. weight decay (L2 penalty).
20
20
  :param clip_threshold: float. threshold of root-mean-square of final gradient update.
21
+ :param amsgrad: bool. whether to use the AMSBound variant.
21
22
  :param scale_parameter: bool. if true, learning rate is scaled by root-mean-square of parameter.
22
23
  :param relative_step: bool. if true, time-dependent learning rate is computed instead of external learning rate.
23
- :param warmup_init: bool. time-dependent learning rate computation depends on
24
- whether warm-up initialization is being used.
24
+ :param warmup_init: bool. time-dependent learning rate computation depends on whether warm-up initialization
25
+ is being used.
25
26
  :param eps1: float. term added to the denominator to improve numerical stability.
26
27
  :param eps2: float. term added to the denominator to improve numerical stability.
27
28
  """
@@ -34,6 +35,7 @@ class AdaFactor(Optimizer, BaseOptimizer):
34
35
  decay_rate: float = -0.8,
35
36
  weight_decay: float = 0.0,
36
37
  clip_threshold: float = 1.0,
38
+ amsgrad: bool = False,
37
39
  scale_parameter: bool = True,
38
40
  relative_step: bool = True,
39
41
  warmup_init: bool = False,
@@ -45,15 +47,23 @@ class AdaFactor(Optimizer, BaseOptimizer):
45
47
  self.decay_rate = decay_rate
46
48
  self.weight_decay = weight_decay
47
49
  self.clip_threshold = clip_threshold
48
- self.scale_parameter = scale_parameter
50
+ self.amsgrad = amsgrad
49
51
  self.relative_step = relative_step
50
- self.warmup_init = warmup_init
51
52
  self.eps1 = eps1
52
53
  self.eps2 = eps2
53
54
 
54
55
  self.validate_parameters()
55
56
 
56
- defaults: DEFAULTS = {'lr': lr, 'weight_decay': weight_decay}
57
+ defaults: DEFAULTS = {
58
+ 'lr': lr,
59
+ 'weight_decay': weight_decay,
60
+ 'amsgrad': amsgrad,
61
+ 'scale_parameter': scale_parameter,
62
+ 'relative_step': relative_step,
63
+ 'warmup_init': warmup_init,
64
+ 'eps1': eps1,
65
+ 'eps2': eps2,
66
+ }
57
67
  super().__init__(params, defaults)
58
68
 
59
69
  def validate_parameters(self):
@@ -69,6 +79,7 @@ class AdaFactor(Optimizer, BaseOptimizer):
69
79
  @torch.no_grad()
70
80
  def reset(self):
71
81
  for group in self.param_groups:
82
+ group['step'] = 0
72
83
  for p in group['params']:
73
84
  state = self.state[p]
74
85
 
@@ -77,24 +88,31 @@ class AdaFactor(Optimizer, BaseOptimizer):
77
88
  grad_shape: Tuple[int, ...] = grad.shape
78
89
  factored: bool = self.get_options(grad_shape)
79
90
 
80
- state['step'] = 0
81
91
  state['exp_avg'] = torch.zeros_like(p)
82
92
 
83
93
  if factored:
84
- state['exp_avg_sq_row'] = torch.zeros(grad_shape[:-1], dtype=grad.dtype)
85
- state['exp_avg_sq_col'] = torch.zeros(grad_shape[:-2] + grad_shape[-1:], dtype=grad.dtype)
94
+ state['exp_avg_sq_row'] = torch.zeros(grad_shape[:-1], dtype=grad.dtype, device=grad.device)
95
+ state['exp_avg_sq_col'] = torch.zeros(
96
+ grad_shape[:-2] + grad_shape[-1:], dtype=grad.dtype, device=grad.device
97
+ )
86
98
  else:
87
99
  state['exp_avg_sq'] = torch.zeros_like(grad)
88
100
 
101
+ if group['amsgrad']:
102
+ state['exp_avg_sq_hat'] = torch.zeros_like(grad)
103
+
89
104
  state['RMS'] = 0.0
90
105
 
91
- def get_lr(self, lr: float, step: int, rms: float) -> float:
106
+ def get_lr(
107
+ self, lr: float, step: int, rms: float, relative_step: bool, warmup_init: bool, scale_parameter: bool
108
+ ) -> float:
109
+ r"""Get AdaFactor learning rate."""
92
110
  relative_step_size: float = lr
93
- if self.relative_step:
94
- min_step: float = 1e-6 * step if self.warmup_init else 1e-2
111
+ if relative_step:
112
+ min_step: float = 1e-6 * step if warmup_init else 1e-2
95
113
  relative_step_size = min(min_step, 1.0 / math.sqrt(step))
96
114
 
97
- param_scale: float = 1.0 if self.scale_parameter else max(self.eps2, rms)
115
+ param_scale: float = 1.0 if scale_parameter else max(self.eps2, rms)
98
116
 
99
117
  return param_scale * relative_step_size
100
118
 
@@ -114,8 +132,8 @@ class AdaFactor(Optimizer, BaseOptimizer):
114
132
  exp_avg_sq_col: torch.Tensor,
115
133
  output: torch.Tensor,
116
134
  ):
117
- r"""Get approximate squared gradient."""
118
- r_factor: torch.Tensor = (exp_avg_sq_row / exp_avg_sq_row.mean(dim=-1)).rsqrt_().unsqueeze(-1)
135
+ r"""Get approximation of EMA of squared gradient."""
136
+ r_factor: torch.Tensor = (exp_avg_sq_row / exp_avg_sq_row.mean(dim=-1, keepdim=True)).rsqrt_().unsqueeze(-1)
119
137
  c_factor: torch.Tensor = exp_avg_sq_col.unsqueeze(-2).rsqrt()
120
138
  torch.mul(r_factor, c_factor, out=output)
121
139
 
@@ -127,6 +145,13 @@ class AdaFactor(Optimizer, BaseOptimizer):
127
145
  loss = closure()
128
146
 
129
147
  for group in self.param_groups:
148
+ if 'step' in group:
149
+ group['step'] += 1
150
+ else:
151
+ group['step'] = 1
152
+
153
+ beta2_t: float = 1.0 - math.pow(group['step'], self.decay_rate)
154
+
130
155
  for p in group['params']:
131
156
  if p.grad is None:
132
157
  continue
@@ -141,23 +166,32 @@ class AdaFactor(Optimizer, BaseOptimizer):
141
166
  factored: bool = self.get_options(grad_shape)
142
167
 
143
168
  if len(state) == 0:
144
- state['step'] = 0
145
169
  state['exp_avg'] = torch.zeros_like(p)
146
170
 
147
171
  if factored:
148
- state['exp_avg_sq_row'] = torch.zeros(grad_shape[:-1], dtype=grad.dtype)
149
- state['exp_avg_sq_col'] = torch.zeros(grad_shape[:-2] + grad_shape[-1:], dtype=grad.dtype)
172
+ state['exp_avg_sq_row'] = torch.zeros(grad_shape[:-1], dtype=grad.dtype, device=grad.device)
173
+ state['exp_avg_sq_col'] = torch.zeros(
174
+ grad_shape[:-2] + grad_shape[-1:], dtype=grad.dtype, device=grad.device
175
+ )
150
176
  else:
151
177
  state['exp_avg_sq'] = torch.zeros_like(grad)
152
178
 
153
- state['RMS'] = 0.0
179
+ if group['amsgrad']:
180
+ state['exp_avg_sq_hat'] = torch.zeros_like(grad)
154
181
 
155
- state['step'] += 1
182
+ state['RMS'] = 0.0
156
183
 
157
184
  state['RMS'] = self.get_rms(p)
158
- lr = self.get_lr(group['lr'], state['step'], state['RMS'])
159
185
 
160
- beta2_t: float = 1.0 - math.pow(state['step'], self.decay_rate)
186
+ lr = self.get_lr(
187
+ group['lr'],
188
+ group['step'],
189
+ state['RMS'],
190
+ relative_step=group['relative_step'],
191
+ warmup_init=group['warmup_init'],
192
+ scale_parameter=group['scale_parameter'],
193
+ )
194
+
161
195
  update = torch.mul(grad, grad).add_(self.eps1)
162
196
 
163
197
  if factored:
@@ -166,28 +200,27 @@ class AdaFactor(Optimizer, BaseOptimizer):
166
200
  exp_avg_sq_row.mul_(beta2_t).add_(update.mean(dim=-1), alpha=1.0 - beta2_t)
167
201
  exp_avg_sq_col.mul_(beta2_t).add_(update.mean(dim=-2), alpha=1.0 - beta2_t)
168
202
 
169
- # Approximation of exponential moving average of square of gradient
170
203
  self.approximate_sq_grad(exp_avg_sq_row, exp_avg_sq_col, update)
171
204
  else:
172
205
  exp_avg_sq = state['exp_avg_sq']
173
-
174
206
  exp_avg_sq.mul_(beta2_t).add_(update, alpha=1.0 - beta2_t)
175
207
  torch.rsqrt(exp_avg_sq, out=update)
176
208
 
177
- update.mul_(grad)
209
+ if group['amsgrad']:
210
+ exp_avg_sq_hat = state['exp_avg_sq_hat']
211
+ torch.max(exp_avg_sq_hat, 1 / update, out=exp_avg_sq_hat)
212
+ torch.rsqrt(exp_avg_sq_hat / beta2_t, out=update)
178
213
 
179
- # TODO: implement AMSGrad
214
+ update.mul_(grad)
180
215
 
181
216
  update.div_((self.get_rms(update) / self.clip_threshold).clamp_(min=1.0)).mul_(lr)
182
217
 
183
218
  exp_avg = state['exp_avg']
184
219
  exp_avg.mul_(self.betas[0]).add_(update, alpha=1.0 - self.betas[0])
185
220
 
186
- update = exp_avg
187
-
188
221
  if group['weight_decay'] > 0.0:
189
222
  p.add_(p, alpha=-lr * group['weight_decay'])
190
223
 
191
- p.add_(-update)
224
+ p.add_(-exp_avg)
192
225
 
193
226
  return loss