optax 0.2.2__tar.gz → 0.2.3__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 (121) hide show
  1. {optax-0.2.2 → optax-0.2.3}/PKG-INFO +8 -4
  2. {optax-0.2.2 → optax-0.2.3}/README.md +1 -1
  3. {optax-0.2.2 → optax-0.2.3}/optax/__init__.py +86 -10
  4. {optax-0.2.2 → optax-0.2.3}/optax/_src/alias.py +227 -16
  5. optax-0.2.3/optax/_src/alias_test.py +783 -0
  6. {optax-0.2.2 → optax-0.2.3}/optax/_src/base.py +10 -17
  7. optax-0.2.3/optax/_src/clipping.py +31 -0
  8. optax-0.2.3/optax/_src/combine.py +22 -0
  9. optax-0.2.3/optax/_src/constrain.py +22 -0
  10. optax-0.2.3/optax/_src/deprecations.py +58 -0
  11. {optax-0.2.2 → optax-0.2.3}/optax/_src/linear_algebra_test.py +2 -2
  12. optax-0.2.3/optax/_src/linesearch.py +1541 -0
  13. optax-0.2.3/optax/_src/linesearch_test.py +675 -0
  14. {optax-0.2.2 → optax-0.2.3}/optax/_src/lookahead.py +29 -19
  15. {optax-0.2.2 → optax-0.2.3}/optax/_src/lookahead_test.py +3 -3
  16. {optax-0.2.2 → optax-0.2.3}/optax/_src/schedule.py +1 -0
  17. {optax-0.2.2 → optax-0.2.3}/optax/_src/transform.py +506 -407
  18. {optax-0.2.2 → optax-0.2.3}/optax/_src/transform_test.py +1 -146
  19. {optax-0.2.2 → optax-0.2.3}/optax/_src/utils.py +13 -10
  20. {optax-0.2.2 → optax-0.2.3}/optax/_src/utils_test.py +0 -19
  21. optax-0.2.3/optax/_src/wrappers.py +59 -0
  22. {optax-0.2.2 → optax-0.2.3}/optax/contrib/__init__.py +18 -0
  23. optax-0.2.3/optax/contrib/_acprop.py +162 -0
  24. {optax-0.2.2 → optax-0.2.3}/optax/contrib/_cocob.py +40 -3
  25. {optax-0.2.2 → optax-0.2.3}/optax/contrib/_common_test.py +32 -10
  26. optax-0.2.3/optax/contrib/_dog.py +344 -0
  27. {optax-0.2.2 → optax-0.2.3}/optax/contrib/_mechanic.py +2 -1
  28. {optax-0.2.2 → optax-0.2.3}/optax/contrib/_mechanic_test.py +3 -3
  29. optax-0.2.3/optax/contrib/_momo.py +343 -0
  30. {optax-0.2.2 → optax-0.2.3}/optax/contrib/_prodigy.py +11 -3
  31. {optax-0.2.2 → optax-0.2.3}/optax/contrib/_reduce_on_plateau.py +19 -6
  32. {optax-0.2.2 → optax-0.2.3}/optax/contrib/_reduce_on_plateau_test.py +41 -6
  33. {optax-0.2.2 → optax-0.2.3}/optax/contrib/_sam.py +6 -5
  34. {optax-0.2.2 → optax-0.2.3}/optax/contrib/_sam_test.py +6 -5
  35. optax-0.2.3/optax/contrib/_schedule_free.py +351 -0
  36. optax-0.2.3/optax/contrib/_schedule_free_test.py +110 -0
  37. {optax-0.2.2 → optax-0.2.3}/optax/losses/__init__.py +9 -0
  38. {optax-0.2.2 → optax-0.2.3}/optax/losses/_classification.py +171 -8
  39. {optax-0.2.2 → optax-0.2.3}/optax/losses/_classification_test.py +400 -119
  40. optax-0.2.3/optax/losses/_self_supervised.py +88 -0
  41. optax-0.2.3/optax/losses/_self_supervised_test.py +57 -0
  42. {optax-0.2.2 → optax-0.2.3}/optax/monte_carlo/control_variates.py +23 -22
  43. {optax-0.2.2 → optax-0.2.3}/optax/monte_carlo/control_variates_test.py +9 -7
  44. {optax-0.2.2 → optax-0.2.3}/optax/optax_test.py +3 -0
  45. {optax-0.2.2 → optax-0.2.3}/optax/projections/__init__.py +1 -0
  46. {optax-0.2.2 → optax-0.2.3}/optax/projections/_projections.py +73 -0
  47. optax-0.2.3/optax/projections/_projections_test.py +172 -0
  48. {optax-0.2.2 → optax-0.2.3}/optax/schedules/__init__.py +1 -0
  49. {optax-0.2.2 → optax-0.2.3}/optax/schedules/_inject.py +38 -28
  50. {optax-0.2.2 → optax-0.2.3}/optax/schedules/_inject_test.py +2 -2
  51. {optax-0.2.2 → optax-0.2.3}/optax/schedules/_schedule.py +23 -0
  52. optax-0.2.3/optax/transforms/__init__.py +92 -0
  53. optax-0.2.3/optax/transforms/_accumulation.py +393 -0
  54. optax-0.2.3/optax/transforms/_accumulation_test.py +298 -0
  55. optax-0.2.3/optax/transforms/_adding.py +105 -0
  56. optax-0.2.3/optax/transforms/_adding_test.py +96 -0
  57. optax-0.2.2/optax/_src/clipping.py → optax-0.2.3/optax/transforms/_clipping.py +25 -48
  58. optax-0.2.2/optax/_src/clipping_test.py → optax-0.2.3/optax/transforms/_clipping_test.py +11 -11
  59. optax-0.2.2/optax/_src/combine.py → optax-0.2.3/optax/transforms/_combining.py +66 -59
  60. optax-0.2.3/optax/transforms/_combining_test.py +284 -0
  61. optax-0.2.3/optax/transforms/_conditionality.py +253 -0
  62. optax-0.2.3/optax/transforms/_conditionality_test.py +286 -0
  63. optax-0.2.2/optax/_src/constrain.py → optax-0.2.3/optax/transforms/_constraining.py +8 -9
  64. optax-0.2.2/optax/_src/constrain_test.py → optax-0.2.3/optax/transforms/_constraining_test.py +14 -11
  65. optax-0.2.3/optax/transforms/_layouts.py +77 -0
  66. optax-0.2.3/optax/transforms/_layouts_test.py +59 -0
  67. optax-0.2.3/optax/transforms/_masking.py +136 -0
  68. optax-0.2.3/optax/transforms/_masking_test.py +348 -0
  69. {optax-0.2.2 → optax-0.2.3}/optax/tree_utils/__init__.py +11 -3
  70. optax-0.2.3/optax/tree_utils/_casting.py +31 -0
  71. optax-0.2.3/optax/tree_utils/_casting_test.py +50 -0
  72. optax-0.2.3/optax/tree_utils/_random.py +68 -0
  73. optax-0.2.3/optax/tree_utils/_random_test.py +102 -0
  74. {optax-0.2.2 → optax-0.2.3}/optax/tree_utils/_state_utils.py +3 -3
  75. {optax-0.2.2 → optax-0.2.3}/optax/tree_utils/_state_utils_test.py +1 -1
  76. optax-0.2.3/optax/tree_utils/_tree_math.py +352 -0
  77. {optax-0.2.2 → optax-0.2.3}/optax/tree_utils/_tree_math_test.py +78 -42
  78. {optax-0.2.2 → optax-0.2.3}/pyproject.toml +8 -3
  79. optax-0.2.2/optax/_src/alias_test.py +0 -207
  80. optax-0.2.2/optax/_src/linesearch.py +0 -367
  81. optax-0.2.2/optax/_src/linesearch_test.py +0 -262
  82. optax-0.2.2/optax/_src/wrappers.py +0 -612
  83. optax-0.2.2/optax/_src/wrappers_test.py +0 -771
  84. optax-0.2.2/optax/projections/_projections_test.py +0 -98
  85. optax-0.2.2/optax/tree_utils/_tree_math.py +0 -253
  86. {optax-0.2.2 → optax-0.2.3}/LICENSE +0 -0
  87. {optax-0.2.2 → optax-0.2.3}/optax/_src/base_test.py +0 -0
  88. {optax-0.2.2 → optax-0.2.3}/optax/_src/combine_test.py +0 -0
  89. {optax-0.2.2 → optax-0.2.3}/optax/_src/factorized.py +0 -0
  90. {optax-0.2.2 → optax-0.2.3}/optax/_src/factorized_test.py +0 -0
  91. {optax-0.2.2 → optax-0.2.3}/optax/_src/float64_test.py +0 -0
  92. {optax-0.2.2 → optax-0.2.3}/optax/_src/linear_algebra.py +0 -0
  93. {optax-0.2.2 → optax-0.2.3}/optax/_src/numerics.py +0 -0
  94. {optax-0.2.2 → optax-0.2.3}/optax/_src/numerics_test.py +0 -0
  95. {optax-0.2.2 → optax-0.2.3}/optax/_src/update.py +0 -0
  96. {optax-0.2.2 → optax-0.2.3}/optax/_src/update_test.py +0 -0
  97. {optax-0.2.2 → optax-0.2.3}/optax/contrib/_complex_valued.py +0 -0
  98. {optax-0.2.2 → optax-0.2.3}/optax/contrib/_complex_valued_test.py +0 -0
  99. {optax-0.2.2 → optax-0.2.3}/optax/contrib/_dadapt_adamw.py +0 -0
  100. {optax-0.2.2 → optax-0.2.3}/optax/contrib/_privacy.py +0 -0
  101. {optax-0.2.2 → optax-0.2.3}/optax/contrib/_privacy_test.py +0 -0
  102. {optax-0.2.2 → optax-0.2.3}/optax/losses/_fenchel_young.py +0 -0
  103. {optax-0.2.2 → optax-0.2.3}/optax/losses/_fenchel_young_test.py +0 -0
  104. {optax-0.2.2 → optax-0.2.3}/optax/losses/_ranking.py +0 -0
  105. {optax-0.2.2 → optax-0.2.3}/optax/losses/_ranking_test.py +0 -0
  106. {optax-0.2.2 → optax-0.2.3}/optax/losses/_regression.py +0 -0
  107. {optax-0.2.2 → optax-0.2.3}/optax/losses/_regression_test.py +0 -0
  108. {optax-0.2.2 → optax-0.2.3}/optax/losses/_smoothing.py +0 -0
  109. {optax-0.2.2 → optax-0.2.3}/optax/losses/_smoothing_test.py +0 -0
  110. {optax-0.2.2 → optax-0.2.3}/optax/monte_carlo/__init__.py +0 -0
  111. {optax-0.2.2 → optax-0.2.3}/optax/monte_carlo/stochastic_gradient_estimators.py +0 -0
  112. {optax-0.2.2 → optax-0.2.3}/optax/monte_carlo/stochastic_gradient_estimators_test.py +0 -0
  113. {optax-0.2.2 → optax-0.2.3}/optax/schedules/_join.py +0 -0
  114. {optax-0.2.2 → optax-0.2.3}/optax/schedules/_join_test.py +0 -0
  115. {optax-0.2.2 → optax-0.2.3}/optax/schedules/_schedule_test.py +0 -0
  116. {optax-0.2.2 → optax-0.2.3}/optax/schedules/inject.py +0 -0
  117. {optax-0.2.2 → optax-0.2.3}/optax/second_order/__init__.py +0 -0
  118. {optax-0.2.2 → optax-0.2.3}/optax/second_order/_base.py +0 -0
  119. {optax-0.2.2 → optax-0.2.3}/optax/second_order/_fisher.py +0 -0
  120. {optax-0.2.2 → optax-0.2.3}/optax/second_order/_hessian.py +0 -0
  121. {optax-0.2.2 → optax-0.2.3}/optax/second_order/_hessian_test.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: optax
3
- Version: 0.2.2
3
+ Version: 0.2.3
4
4
  Summary: A gradient processing and optimisation library in JAX.
5
5
  Keywords: python,machine learning,reinforcement-learning
6
6
  Author-email: Google DeepMind <optax-dev@google.com>
@@ -18,9 +18,10 @@ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
18
18
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
19
19
  Requires-Dist: absl-py>=0.7.1
20
20
  Requires-Dist: chex>=0.1.86
21
- Requires-Dist: jax>=0.1.55
22
- Requires-Dist: jaxlib>=0.1.37
21
+ Requires-Dist: jax>=0.4.27
22
+ Requires-Dist: jaxlib>=0.4.27
23
23
  Requires-Dist: numpy>=1.18.0
24
+ Requires-Dist: etils[epy]
24
25
  Requires-Dist: sphinx>=6.0.0 ; extra == "docs"
25
26
  Requires-Dist: sphinx-book-theme>=1.0.1 ; extra == "docs"
26
27
  Requires-Dist: sphinxcontrib-katex ; extra == "docs"
@@ -42,9 +43,12 @@ Requires-Dist: scipy>=1.7.1 ; extra == "dp-accounting"
42
43
  Requires-Dist: tensorflow-datasets>=4.2.0 ; extra == "examples"
43
44
  Requires-Dist: tensorflow>=2.4.0 ; extra == "examples"
44
45
  Requires-Dist: dp_accounting>=0.4 ; extra == "examples"
46
+ Requires-Dist: ipywidgets ; extra == "examples"
45
47
  Requires-Dist: flax ; extra == "examples"
46
48
  Requires-Dist: dm-tree>=0.1.7 ; extra == "test"
47
49
  Requires-Dist: flax>=0.5.3 ; extra == "test"
50
+ Requires-Dist: scipy>=1.7.1 ; extra == "test"
51
+ Requires-Dist: scikit-learn ; extra == "test"
48
52
  Project-URL: documentation, https://optax.readthedocs.io/
49
53
  Project-URL: homepage, https://github.com/google-deepmind/optax
50
54
  Project-URL: repository, https://github.com/google-deepmind/optax
@@ -132,7 +136,7 @@ updates, opt_state = optimizer.update(grads, opt_state)
132
136
  params = optax.apply_updates(params, updates)
133
137
  ```
134
138
 
135
- You can continue the quick start in [the Optax 101 notebook.](https://github.com/google-deepmind/optax/blob/main/docs/optax-101.ipynb)
139
+ You can continue the quick start in [the Optax 🚀 Getting started notebook.](https://github.com/google-deepmind/optax/blob/main/docs/getting_started.ipynb)
136
140
 
137
141
  ## Development
138
142
 
@@ -77,7 +77,7 @@ updates, opt_state = optimizer.update(grads, opt_state)
77
77
  params = optax.apply_updates(params, updates)
78
78
  ```
79
79
 
80
- You can continue the quick start in [the Optax 101 notebook.](https://github.com/google-deepmind/optax/blob/main/docs/optax-101.ipynb)
80
+ You can continue the quick start in [the Optax 🚀 Getting started notebook.](https://github.com/google-deepmind/optax/blob/main/docs/getting_started.ipynb)
81
81
 
82
82
  ## Development
83
83
 
@@ -14,12 +14,16 @@
14
14
  # ==============================================================================
15
15
  """Optax: composable gradient processing and optimization, in JAX."""
16
16
 
17
+ # pylint: disable=wrong-import-position
18
+ # pylint: disable=g-importing-member
19
+
17
20
  from optax import contrib
18
21
  from optax import losses
19
22
  from optax import monte_carlo
20
23
  from optax import projections
21
24
  from optax import schedules
22
25
  from optax import second_order
26
+ from optax import transforms
23
27
  from optax import tree_utils
24
28
  from optax._src.alias import adabelief
25
29
  from optax._src.alias import adadelta
@@ -33,6 +37,7 @@ from optax._src.alias import amsgrad
33
37
  from optax._src.alias import fromage
34
38
  from optax._src.alias import lamb
35
39
  from optax._src.alias import lars
40
+ from optax._src.alias import lbfgs
36
41
  from optax._src.alias import lion
37
42
  from optax._src.alias import MaskOrFn
38
43
  from optax._src.alias import nadam
@@ -86,7 +91,10 @@ from optax._src.linear_algebra import global_norm
86
91
  from optax._src.linear_algebra import matrix_inverse_pth_root
87
92
  from optax._src.linear_algebra import power_iteration
88
93
  from optax._src.linesearch import scale_by_backtracking_linesearch
94
+ from optax._src.linesearch import scale_by_zoom_linesearch
89
95
  from optax._src.linesearch import ScaleByBacktrackingLinesearchState
96
+ from optax._src.linesearch import ScaleByZoomLinesearchState
97
+ from optax._src.linesearch import ZoomLinesearchInfo
90
98
  from optax._src.lookahead import lookahead
91
99
  from optax._src.lookahead import LookaheadParams
92
100
  from optax._src.lookahead import LookaheadState
@@ -99,10 +107,10 @@ from optax._src.transform import AddDecayedWeightsState
99
107
  from optax._src.transform import AddNoiseState
100
108
  from optax._src.transform import apply_every
101
109
  from optax._src.transform import ApplyEvery
102
- from optax._src.transform import bias_correction
103
110
  from optax._src.transform import centralize
104
111
  from optax._src.transform import ema
105
112
  from optax._src.transform import EmaState
113
+ from optax._src.transform import normalize_by_update_norm
106
114
  from optax._src.transform import scale
107
115
  from optax._src.transform import scale_by_adadelta
108
116
  from optax._src.transform import scale_by_adam
@@ -110,6 +118,7 @@ from optax._src.transform import scale_by_adamax
110
118
  from optax._src.transform import scale_by_amsgrad
111
119
  from optax._src.transform import scale_by_belief
112
120
  from optax._src.transform import scale_by_distance_over_gradients
121
+ from optax._src.transform import scale_by_lbfgs
113
122
  from optax._src.transform import scale_by_learning_rate
114
123
  from optax._src.transform import scale_by_lion
115
124
  from optax._src.transform import scale_by_novograd
@@ -130,6 +139,7 @@ from optax._src.transform import ScaleByAdaDeltaState
130
139
  from optax._src.transform import ScaleByAdamState
131
140
  from optax._src.transform import ScaleByAmsgradState
132
141
  from optax._src.transform import ScaleByBeliefState
142
+ from optax._src.transform import ScaleByLBFGSState
133
143
  from optax._src.transform import ScaleByLionState
134
144
  from optax._src.transform import ScaleByNovogradState
135
145
  from optax._src.transform import ScaleByRmsState
@@ -142,9 +152,6 @@ from optax._src.transform import ScaleByTrustRatioState
142
152
  from optax._src.transform import ScaleState
143
153
  from optax._src.transform import trace
144
154
  from optax._src.transform import TraceState
145
- from optax._src.transform import update_infinity_moment
146
- from optax._src.transform import update_moment
147
- from optax._src.transform import update_moment_per_elem_norm
148
155
  from optax._src.update import apply_updates
149
156
  from optax._src.update import incremental_update
150
157
  from optax._src.update import periodic_update
@@ -153,6 +160,10 @@ from optax._src.utils import scale_gradient
153
160
  from optax._src.utils import value_and_grad_from_state
154
161
  from optax._src.wrappers import apply_if_finite
155
162
  from optax._src.wrappers import ApplyIfFiniteState
163
+ from optax._src.wrappers import conditionally_mask
164
+ from optax._src.wrappers import conditionally_transform
165
+ from optax._src.wrappers import ConditionallyMaskState
166
+ from optax._src.wrappers import ConditionallyTransformState
156
167
  from optax._src.wrappers import flatten
157
168
  from optax._src.wrappers import masked
158
169
  from optax._src.wrappers import MaskedNode
@@ -165,8 +176,13 @@ from optax._src.wrappers import ShouldSkipUpdateFunction
165
176
  from optax._src.wrappers import skip_large_updates
166
177
  from optax._src.wrappers import skip_not_finite
167
178
 
179
+
168
180
  # TODO(mtthss): remove tree_utils aliases after updates.
169
181
  tree_map_params = tree_utils.tree_map_params
182
+ bias_correction = tree_utils.tree_bias_correction
183
+ update_infinity_moment = tree_utils.tree_update_infinity_moment
184
+ update_moment = tree_utils.tree_update_moment
185
+ update_moment_per_elem_norm = tree_utils.tree_update_moment_per_elem_norm
170
186
 
171
187
  # TODO(mtthss): remove schedules alises from flat namespaces after user updates.
172
188
  constant_schedule = schedules.constant_schedule
@@ -199,8 +215,10 @@ huber_loss = losses.huber_loss
199
215
  kl_divergence = losses.kl_divergence
200
216
  l2_loss = losses.l2_loss
201
217
  log_cosh = losses.log_cosh
218
+ ntxent = losses.ntxent
202
219
  sigmoid_binary_cross_entropy = losses.sigmoid_binary_cross_entropy
203
220
  smooth_labels = losses.smooth_labels
221
+ safe_softmax_cross_entropy = losses.safe_softmax_cross_entropy
204
222
  softmax_cross_entropy = losses.softmax_cross_entropy
205
223
  softmax_cross_entropy_with_integer_labels = (
206
224
  losses.softmax_cross_entropy_with_integer_labels
@@ -208,14 +226,61 @@ softmax_cross_entropy_with_integer_labels = (
208
226
  squared_error = losses.squared_error
209
227
  sigmoid_focal_loss = losses.sigmoid_focal_loss
210
228
 
229
+ # pylint: disable=g-import-not-at-top
211
230
  # TODO(mtthss): remove contrib aliases from flat namespace once users updated.
212
- differentially_private_aggregate = contrib.differentially_private_aggregate
213
- DifferentiallyPrivateAggregateState = (
214
- contrib.DifferentiallyPrivateAggregateState
215
- )
216
- dpsgd = contrib.dpsgd
231
+ # Deprecated modules
232
+ from optax.contrib import differentially_private_aggregate as _deprecated_differentially_private_aggregate
233
+ from optax.contrib import DifferentiallyPrivateAggregateState as _deprecated_DifferentiallyPrivateAggregateState
234
+ from optax.contrib import dpsgd as _deprecated_dpsgd
235
+
236
+ _deprecations = {
237
+ # Added Apr 2024
238
+ "differentially_private_aggregate": (
239
+ (
240
+ "optax.differentially_private_aggregate is deprecated: use"
241
+ " optax.contrib.differentially_private_aggregate (optax v0.1.8 or"
242
+ " newer)."
243
+ ),
244
+ _deprecated_differentially_private_aggregate,
245
+ ),
246
+ "DifferentiallyPrivateAggregateState": (
247
+ (
248
+ "optax.DifferentiallyPrivateAggregateState is deprecated: use"
249
+ " optax.contrib.DifferentiallyPrivateAggregateState (optax v0.1.8"
250
+ " or newer)."
251
+ ),
252
+ _deprecated_DifferentiallyPrivateAggregateState,
253
+ ),
254
+ "dpsgd": (
255
+ (
256
+ "optax.dpsgd is deprecated: use optax.contrib.dpsgd (optax v0.1.8"
257
+ " or newer)."
258
+ ),
259
+ _deprecated_dpsgd,
260
+ ),
261
+ }
262
+ # pylint: disable=g-bad-import-order
263
+ import typing as _typing
264
+
265
+ if _typing.TYPE_CHECKING:
266
+ # pylint: disable=reimported
267
+ from optax.contrib import differentially_private_aggregate
268
+ from optax.contrib import DifferentiallyPrivateAggregateState
269
+ from optax.contrib import dpsgd
270
+ # pylint: enable=reimported
271
+
272
+ else:
273
+ from optax._src.deprecations import deprecation_getattr as _deprecation_getattr
274
+
275
+ __getattr__ = _deprecation_getattr(__name__, _deprecations)
276
+ del _deprecation_getattr
277
+ del _typing
278
+ # pylint: enable=g-bad-import-order
279
+ # pylint: enable=g-import-not-at-top
280
+ # pylint: enable=g-importing-member
281
+
217
282
 
218
- __version__ = "0.2.2"
283
+ __version__ = "0.2.3"
219
284
 
220
285
  __all__ = (
221
286
  "adabelief",
@@ -245,6 +310,10 @@ __all__ = (
245
310
  "clip",
246
311
  "ClipByGlobalNormState",
247
312
  "ClipState",
313
+ "conditionally_mask",
314
+ "ConditionallyMaskState",
315
+ "conditionally_transform",
316
+ "ConditionallyTransformState",
248
317
  "constant_schedule",
249
318
  "ctc_loss",
250
319
  "ctc_loss_with_forward_probs",
@@ -278,6 +347,7 @@ __all__ = (
278
347
  "l2_loss",
279
348
  "lamb",
280
349
  "lars",
350
+ "lbfgs",
281
351
  "lion",
282
352
  "linear_onecycle_schedule",
283
353
  "linear_schedule",
@@ -301,6 +371,7 @@ __all__ = (
301
371
  "noisy_sgd",
302
372
  "novograd",
303
373
  "NonNegativeParamsState",
374
+ "ntxent",
304
375
  "OptState",
305
376
  "Params",
306
377
  "periodic_update",
@@ -324,6 +395,7 @@ __all__ = (
324
395
  "scale_by_amsgrad",
325
396
  "scale_by_backtracking_linesearch",
326
397
  "scale_by_belief",
398
+ "scale_by_lbfgs",
327
399
  "scale_by_lion",
328
400
  "scale_by_factored_rms",
329
401
  "scale_by_novograd",
@@ -339,6 +411,7 @@ __all__ = (
339
411
  "scale_by_stddev",
340
412
  "scale_by_trust_ratio",
341
413
  "scale_by_yogi",
414
+ "scale_by_zoom_linesearch",
342
415
  "scale_gradient",
343
416
  "scale",
344
417
  "ScaleByAdaDeltaState",
@@ -346,6 +419,7 @@ __all__ = (
346
419
  "ScaleByAmsgradState",
347
420
  "ScaleByBacktrackingLinesearchState",
348
421
  "ScaleByBeliefState",
422
+ "ScaleByLBFGSState",
349
423
  "ScaleByLionState",
350
424
  "ScaleByNovogradState",
351
425
  "ScaleByRmsState",
@@ -355,6 +429,7 @@ __all__ = (
355
429
  "ScaleByScheduleState",
356
430
  "ScaleBySM3State",
357
431
  "ScaleByTrustRatioState",
432
+ "ScaleByZoomLinesearchState",
358
433
  "ScaleState",
359
434
  "Schedule",
360
435
  "set_to_zero",
@@ -382,6 +457,7 @@ __all__ = (
382
457
  "yogi",
383
458
  "zero_nans",
384
459
  "ZeroNansState",
460
+ "ZoomLinesearchInfo",
385
461
  )
386
462
 
387
463
  # _________________________________________
@@ -23,6 +23,7 @@ from optax._src import base
23
23
  from optax._src import clipping
24
24
  from optax._src import combine
25
25
  from optax._src import factorized
26
+ from optax._src import linesearch as _linesearch
26
27
  from optax._src import transform
27
28
  from optax._src import wrappers
28
29
 
@@ -530,15 +531,50 @@ def adamw(
530
531
  *,
531
532
  nesterov: bool = False,
532
533
  ) -> base.GradientTransformation:
533
- """Adam with weight decay regularization.
534
+ r"""Adam with weight decay regularization.
534
535
 
535
536
  AdamW uses weight decay to regularize learning towards small weights, as
536
537
  this leads to better generalization. In SGD you can also use L2 regularization
537
538
  to implement this as an additive loss term, however L2 regularization
538
- does not behave as intended for adaptive gradient algorithms such as Adam.
539
+ does not behave as intended for adaptive gradient algorithms such as Adam,
540
+ see [Loshchilov et al, 2019].
541
+
542
+ Let :math:`\alpha_t` represent the learning rate and :math:`\beta_1, \beta_2`,
543
+ :math:`\varepsilon`, :math:`\bar{\varepsilon}` represent the arguments
544
+ ``b1``, ``b2``, ``eps`` and ``eps_root`` respectively. The learning rate is
545
+ indexed by :math:`t` since the learning rate may also be provided by a
546
+ schedule function. Let :math:`\lambda` be the weight decay and
547
+ :math:`\theta_t` the parameter vector at time :math:`t`.
548
+
549
+ The ``init`` function of this optimizer initializes an internal state
550
+ :math:`S_0 := (m_0, v_0) = (0, 0)`, representing initial estimates for the
551
+ first and second moments. In practice these values are stored as pytrees
552
+ containing all zeros, with the same shape as the model updates.
553
+ At step :math:`t`, the ``update`` function of this optimizer takes as
554
+ arguments the incoming gradients :math:`g_t`, the optimizer state :math:`S_t`
555
+ and the parameters :math:`\theta_t` and computes updates :math:`u_t` and
556
+ new state :math:`S_{t+1}`. Thus, for :math:`t > 0`, we have,
557
+
558
+ .. math::
559
+
560
+ \begin{align*}
561
+ m_t &\leftarrow \beta_1 \cdot m_{t-1} + (1-\beta_1) \cdot g_t \\
562
+ v_t &\leftarrow \beta_2 \cdot v_{t-1} + (1-\beta_2) \cdot {g_t}^2 \\
563
+ \hat{m}_t &\leftarrow m_t / {(1-\beta_1^t)} \\
564
+ \hat{v}_t &\leftarrow v_t / {(1-\beta_2^t)} \\
565
+ u_t &\leftarrow -\alpha_t \cdot \left( \hat{m}_t / \left({\sqrt{\hat{v}_t
566
+ + \bar{\varepsilon}} + \varepsilon} \right) + \lambda \theta_{t} \right)\\
567
+ S_t &\leftarrow (m_t, v_t).
568
+ \end{align*}
539
569
 
540
570
  This implementation can incorporate a momentum a la Nesterov introduced by
541
571
  [Dozat 2016]. The resulting optimizer is then often referred as NAdamW.
572
+ With the keyword argument `nesterov=True`, the optimizer uses Nesterov
573
+ momentum, replacing the above :math:`\hat{m}_t` with
574
+
575
+ .. math::
576
+ \hat{m}_t \leftarrow
577
+ \beta_1 m_t / {(1-\beta_1^{t+1})} + (1 - \beta_1) g_t / {(1-\beta_1^t)}.
542
578
 
543
579
  Examples:
544
580
  >>> import optax
@@ -1206,7 +1242,9 @@ def radam(
1206
1242
  b2: float = 0.999,
1207
1243
  eps: float = 1e-8,
1208
1244
  eps_root: float = 0.0,
1209
- threshold: float = 5.0
1245
+ threshold: float = 5.0,
1246
+ *,
1247
+ nesterov: bool = False,
1210
1248
  ) -> base.GradientTransformation:
1211
1249
  """The Rectified Adam optimizer.
1212
1250
 
@@ -1250,13 +1288,20 @@ def radam(
1250
1288
  in RMSProp), to avoid dividing by zero when rescaling. This is needed for
1251
1289
  instance when computing (meta-)gradients through Adam.
1252
1290
  threshold: Threshold for variance tractability.
1291
+ nesterov: Whether to use Nesterov momentum.
1253
1292
 
1254
1293
  Returns:
1255
1294
  The corresponding `GradientTransformation`.
1256
1295
  """
1257
1296
  return combine.chain(
1258
1297
  transform.scale_by_radam(
1259
- b1=b1, b2=b2, eps=eps, eps_root=eps_root, threshold=threshold),
1298
+ b1=b1,
1299
+ b2=b2,
1300
+ eps=eps,
1301
+ eps_root=eps_root,
1302
+ threshold=threshold,
1303
+ nesterov=nesterov,
1304
+ ),
1260
1305
  transform.scale_by_learning_rate(learning_rate),
1261
1306
  )
1262
1307
 
@@ -1373,12 +1418,12 @@ def sgd(
1373
1418
  .. math::
1374
1419
 
1375
1420
  \begin{align*}
1376
- m_t & \leftarrow \begin{cases}
1377
- g_t + \mu m_t & \mathrm{if \ \texttt{nesterov=False}}\\
1378
- g_t + \mu (g_t + \mu m_{t-1}) & \mathrm{if \ \texttt{nesterov=True}}
1379
- \end{cases} \\
1380
- u_t & \leftarrow - \alpha_t m_t \\
1381
- S_t & = m_t,
1421
+ m_t &\leftarrow g_t + \mu m_{t-1} \\
1422
+ u_t &\leftarrow \begin{cases}
1423
+ -\alpha_t m_t & \text{ if } \texttt{nesterov = False} \\
1424
+ -\alpha_t (g_t + \mu m_t) & \text{ if } \texttt{nesterov = True}
1425
+ \end{cases} \\
1426
+ S_t &\leftarrow m_t,
1382
1427
  \end{align*}
1383
1428
 
1384
1429
  where :math:`\mu` is the ``momentum`` parameter and :math:`S_t` is the state
@@ -1546,7 +1591,37 @@ def adamax(
1546
1591
  b2: float = 0.999,
1547
1592
  eps: float = 1e-8,
1548
1593
  ) -> base.GradientTransformation:
1549
- """A variant of the Adam optimizer that uses the infinity norm.
1594
+ r"""A variant of the Adam optimizer that uses the infinity norm.
1595
+
1596
+ AdaMax is a variant of the :func:`optax.adam` optimizer. By generalizing
1597
+ Adam's :math:`L^2` norm to an :math:`L^p` norm and taking the limit as
1598
+ :math:`p \rightarrow \infty`, we obtain a simple and stable update rule.
1599
+
1600
+ Let :math:`\alpha_t` represent the learning rate and :math:`\beta_1, \beta_2`,
1601
+ :math:`\varepsilon` represent the arguments
1602
+ ``b1``, ``b2`` and ``eps`` respectively. The learning rate is
1603
+ indexed by :math:`t` since the learning rate may also be provided by a
1604
+ schedule function.
1605
+
1606
+ The ``init`` function of this optimizer initializes an internal state
1607
+ :math:`S_0 := (m_0, v_0) = (0, 0)`, representing initial estimates for the
1608
+ first and second moments. In practice these values are stored as pytrees
1609
+ containing all zeros, with the same shape as the model updates.
1610
+ At step :math:`t`, the ``update`` function of this optimizer takes as
1611
+ arguments the incoming gradients :math:`g_t` and optimizer state :math:`S_t`
1612
+ and computes updates :math:`u_t` and new state :math:`S_{t+1}`. Thus, for
1613
+ :math:`t > 0`, we have,
1614
+
1615
+ .. math::
1616
+
1617
+ \begin{align*}
1618
+ m_t &\leftarrow \beta_1 \cdot m_{t-1} + (1-\beta_1) \cdot g_t \\
1619
+ v_t &\leftarrow \max(\left| g_t \right| + \varepsilon, \beta_2 \cdot
1620
+ v_{t-1}) \\
1621
+ \hat{m}_t &\leftarrow m_t / (1-\beta_1^t) \\
1622
+ u_t &\leftarrow -\alpha_t \cdot \hat{m}_t / v_t \\
1623
+ S_t &\leftarrow (m_t, v_t).
1624
+ \end{align*}
1550
1625
 
1551
1626
  Examples:
1552
1627
  >>> import optax
@@ -1700,11 +1775,14 @@ def rprop(
1700
1775
  Objective function: 1.38E+01
1701
1776
 
1702
1777
  References:
1703
- PyTorch implementation:
1704
- https://pytorch.org/docs/stable/generated/torch.optim.Rprop.html
1705
- Riedmiller and Braun, 1993: https://ieeexplore.ieee.org/document/298623
1706
- Igel and Hüsken, 2003:
1707
- https://www.sciencedirect.com/science/article/abs/pii/S0925231201007007
1778
+ Riedmiller and Braun. `A direct adaptive method for faster backpropagation
1779
+ learning: the RPROP algorithm
1780
+ <https://ieeexplore.ieee.org/document/298623>`_, 1993
1781
+
1782
+ Igel and Hüsken. `Empirical evaluation of the improved Rprop learning
1783
+ algorithms
1784
+ <https://www.sciencedirect.com/science/article/abs/pii/S0925231201007007>`_,
1785
+ 2003
1708
1786
 
1709
1787
  Args:
1710
1788
  learning_rate: The initial step size.
@@ -1809,3 +1887,136 @@ def polyak_sgd(
1809
1887
  max_learning_rate=max_learning_rate, f_min=f_min, eps=eps
1810
1888
  ),
1811
1889
  )
1890
+
1891
+
1892
+ def lbfgs(
1893
+ learning_rate: Optional[base.ScalarOrSchedule] = None,
1894
+ memory_size: int = 10,
1895
+ scale_init_precond: bool = True,
1896
+ linesearch: Optional[
1897
+ base.GradientTransformationExtraArgs
1898
+ ] = _linesearch.scale_by_zoom_linesearch(max_linesearch_steps=15),
1899
+ ) -> base.GradientTransformationExtraArgs:
1900
+ r"""L-BFGS optimizer.
1901
+
1902
+ L-BFGS is a quasi-Newton method that multiplies the update (gradient)
1903
+ with an approximation of the inverse Hessian. This algorithm does not need
1904
+ access to the Hessian, as this approximation is constructed from the gradient
1905
+ evaluations seen during optimization. L-BFGS is a limited-memory variant of
1906
+ the Broyden-Fletcher-Goldfarb-Shanno (BFGS) algorithm. The BFGS algorithm
1907
+ requires storing a matrix of size :math:`p \times p` with :math:`p` the
1908
+ dimension of the parameters.
1909
+ The limited variant circuments this issue by computing the approximation of
1910
+ the inverse using only :math:`m` (``memory_size``) past differences of
1911
+ parameters/gradients. Namely, the approximation of the Hessian inverse is
1912
+ denoted :math:`P_k = P_{k, k}`, where
1913
+
1914
+ .. math::
1915
+
1916
+ \begin{align*}
1917
+ P_{k, j+1} & = V_j^\top P_{k, j} V_j + \rho_j \delta w_j \delta w_j^\top
1918
+ \quad \text{for} \ j \in \{k-m, \ldots, k-1\}\\
1919
+ P_{k, k-m} & = \gamma_k I \\
1920
+ V_k & = I - \rho_k \delta u_k \delta w_k^\top \\
1921
+ \rho_k & = 1/(\delta u_k^\top \delta w_k) \\
1922
+ \delta w_k & = w_{k+1} - w_k \\
1923
+ \delta u_k & = u_{k+1} - u_k \\
1924
+ \gamma_k & =
1925
+ \begin{cases}
1926
+ (\delta w_{k-1}^\top \delta u_{k-1}) /
1927
+ (\delta u_{k-1}^\top \delta u_{k-1})
1928
+ & \text{if} \ \texttt{scale\_init\_hess} \\
1929
+ 1 & \text{otherwise}
1930
+ \end{cases},
1931
+ \end{align*}
1932
+
1933
+ for
1934
+ :math:`u_k` the gradients/updates at iteration :math:`k`,
1935
+ :math:`w_k` the parameters at iteration :math:`k`.
1936
+
1937
+ The formula for updating :math:`P_k` is obtained by computing the optimal
1938
+ preconditioning matrix subject to some secant condition, see references
1939
+ for more details. Computing :math:`P_k u_k` can be done by a sequence of
1940
+ vector operations using past differences of parameters and gradients stored in
1941
+ a memory bufffer.
1942
+
1943
+ The present function just outputs the LBFGS direction :math:`P_k u_k`.
1944
+ It can be chained with a linesearch ensuring sufficient decrease and low
1945
+ curvature, such as a zoom linesearch. The linesearch computes a stepsize
1946
+ :math:`\eta_k`, such that the updated parameters
1947
+ (using :func:`optax.apply_updates`) take the form
1948
+ :math:`w_{k+1} = w_k - \eta_k P_k u_k`.
1949
+
1950
+ Example:
1951
+ >>> import optax
1952
+ >>> import jax
1953
+ >>> import jax.numpy as jnp
1954
+ >>> def f(x): return jnp.sum(x ** 2)
1955
+ >>> solver = optax.lbfgs()
1956
+ >>> params = jnp.array([1., 2., 3.])
1957
+ >>> print('Objective function: ', f(params))
1958
+ Objective function: 14.0
1959
+ >>> opt_state = solver.init(params)
1960
+ >>> value_and_grad = optax.value_and_grad_from_state(f)
1961
+ >>> for _ in range(5):
1962
+ ... value, grad = value_and_grad(params, state=opt_state)
1963
+ ... updates, opt_state = solver.update(
1964
+ ... grad, opt_state, params, value=value, grad=grad, value_fn=f
1965
+ ... )
1966
+ ... params = optax.apply_updates(params, updates)
1967
+ ... print('Objective function: ', f(params))
1968
+ Objective function: 0.0
1969
+ Objective function: 0.0
1970
+ Objective function: 0.0
1971
+ Objective function: 0.0
1972
+ Objective function: 0.0
1973
+
1974
+ .. warning::
1975
+ This method is memory intensive optimizer, best used for small to medium
1976
+ scale problems.
1977
+
1978
+ .. warning::
1979
+ This optimizer works best with a linesearch (current default is a
1980
+ zoom linesearch). See example above for best use in a non-stochastic
1981
+ setting, where we can recycle gradients computed by the linesearch using
1982
+ :func:`optax.value_and_grad_from_state`.
1983
+
1984
+ References:
1985
+ Algorithms 7.4, 7.5 (page 199) of Nocedal et al, `Numerical Optimization
1986
+ <https://www.math.uci.edu/~qnie/Publications/NumericalOptimization.pdf>`_
1987
+ , 1999
1988
+
1989
+ Liu et al., `On the limited memory BFGS method for large scale optimization
1990
+ <https://users.iems.northwestern.edu/~nocedal/PDFfiles/limited-memory.pdf>`_
1991
+ , 1989.
1992
+
1993
+ Args:
1994
+ learning_rate: optional global scaling factor, either fixed or evolving
1995
+ along iterations with a scheduler, see
1996
+ :func:`optax.scale_by_learning_rate`. By default the learning rate is
1997
+ handled by a linesearch.
1998
+ memory_size: number of past updates to keep in memory to approximate the
1999
+ Hessian inverse.
2000
+ scale_init_precond: whether to use a scaled identity as the initial
2001
+ preconditioner, see formula above.
2002
+ linesearch: an instance of :class:`optax.GradientTransformationExtraArgs`
2003
+ such as :func:`optax.scale_by_zoom_linesearch` that computes a
2004
+ learning rate, a.k.a. stepsize, to satisfy some criterion such as a
2005
+ sufficient decrease of the objective by additional calls to the objective.
2006
+
2007
+ Returns:
2008
+ A :class:`optax.GradientTransformationExtraArgs` object.
2009
+ """
2010
+ if learning_rate is None:
2011
+ base_scaling = transform.scale(-1.0)
2012
+ else:
2013
+ base_scaling = transform.scale_by_learning_rate(learning_rate)
2014
+ if linesearch is None:
2015
+ linesearch = base.identity()
2016
+ return combine.chain(
2017
+ transform.scale_by_lbfgs(
2018
+ memory_size=memory_size, scale_init_precond=scale_init_precond
2019
+ ),
2020
+ base_scaling,
2021
+ linesearch,
2022
+ )