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.
- {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/PKG-INFO +9 -1
- {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/README.rst +8 -0
- {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pyproject.toml +2 -1
- {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/__init__.py +7 -5
- {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/adabelief.py +69 -53
- {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/adabound.py +30 -26
- {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/adafactor.py +61 -28
- {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/adai.py +11 -9
- {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/adamp.py +36 -11
- {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/adams.py +39 -10
- {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/adan.py +44 -28
- pytorch_optimizer-2.7.0/pytorch_optimizer/optimizer/adanorm.py +146 -0
- {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/adapnm.py +45 -17
- {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/alig.py +8 -11
- {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/apollo.py +9 -8
- {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/dadapt.py +211 -26
- pytorch_optimizer-2.6.0/pytorch_optimizer/optimizer/diffrgrad.py → pytorch_optimizer-2.7.0/pytorch_optimizer/optimizer/diffgrad.py +83 -39
- {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/lamb.py +93 -26
- {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/lars.py +8 -7
- {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/lion.py +7 -3
- {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/novograd.py +12 -7
- {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/pnm.py +2 -5
- {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/radam.py +53 -33
- {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/ranger.py +59 -35
- {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/ranger21.py +4 -5
- pytorch_optimizer-2.7.0/pytorch_optimizer/optimizer/rotograd.py +448 -0
- {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/shampoo.py +20 -17
- {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/sm3.py +11 -28
- {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/utils.py +37 -4
- pytorch_optimizer-2.6.0/pytorch_optimizer/optimizer/diffgrad.py +0 -118
- pytorch_optimizer-2.6.0/pytorch_optimizer/optimizer/ralamb.py +0 -187
- {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/LICENSE +0 -0
- {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/base/__init__.py +0 -0
- {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/base/exception.py +0 -0
- {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/base/optimizer.py +0 -0
- {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/base/scheduler.py +0 -0
- {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/base/types.py +0 -0
- {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/experimental/__init__.py +0 -0
- {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/experimental/deberta_v3_lr_scheduler.py +0 -0
- {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/lr_scheduler/__init__.py +0 -0
- {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/lr_scheduler/chebyshev.py +0 -0
- {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/lr_scheduler/cosine_anealing.py +0 -0
- {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/lr_scheduler/linear_warmup.py +0 -0
- {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/lr_scheduler/proportion.py +0 -0
- {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/__init__.py +0 -0
- {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/agc.py +0 -0
- {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/fp16.py +0 -0
- {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/gc.py +0 -0
- {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/gsam.py +0 -0
- {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/lookahead.py +0 -0
- {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/madgrad.py +0 -0
- {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/nero.py +0 -0
- {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/pcgrad.py +0 -0
- {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/sam.py +0 -0
- {pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/sgdp.py +0 -0
- {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.
|
|
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.
|
|
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
|
|
{pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/adabelief.py
RENAMED
|
@@ -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
|
|
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
|
-
|
|
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
|
-
'
|
|
63
|
-
'
|
|
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
|
|
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
|
|
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
|
|
119
|
-
p.mul_(1.0 -
|
|
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
|
-
|
|
127
|
-
|
|
144
|
+
s_grad = grad
|
|
145
|
+
if group['adanorm']:
|
|
146
|
+
grad_norm = torch.linalg.norm(grad)
|
|
128
147
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
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
|
-
|
|
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
|
|
142
|
-
step_size: float = group['lr'] if group['
|
|
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
|
-
|
|
147
|
-
|
|
148
|
-
|
|
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
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
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_(
|
|
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
|
|
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
|
-
|
|
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
|
-
'
|
|
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
|
-
|
|
113
|
-
|
|
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
|
-
|
|
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
|
-
|
|
131
|
-
|
|
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['
|
|
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
|
|
{pytorch_optimizer-2.6.0 → pytorch_optimizer-2.7.0}/pytorch_optimizer/optimizer/adafactor.py
RENAMED
|
@@ -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
|
-
|
|
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.
|
|
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 = {
|
|
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(
|
|
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(
|
|
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
|
|
94
|
-
min_step: float = 1e-6 * step if
|
|
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
|
|
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
|
|
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(
|
|
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
|
-
|
|
179
|
+
if group['amsgrad']:
|
|
180
|
+
state['exp_avg_sq_hat'] = torch.zeros_like(grad)
|
|
154
181
|
|
|
155
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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_(-
|
|
224
|
+
p.add_(-exp_avg)
|
|
192
225
|
|
|
193
226
|
return loss
|