Skip to content

Commit 443eef3

Browse files
committed
Exposing named_chain in docs
1 parent 3d8c391 commit 443eef3

2 files changed

Lines changed: 36 additions & 17 deletions

File tree

docs/api/combining_optimizers.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@ Combining Optimizers
55

66
.. autosummary::
77
chain
8+
named_chain
89
multi_transform
910

1011
Chain
1112
~~~~~
1213
.. autofunction:: chain
14+
.. autofunction:: named_chain
1315

1416
Multi-transform
1517
~~~~~~~~~~~~~~~

optax/transforms/_combining.py

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ def chain(
3434
updates in the given order.
3535
3636
Args:
37-
*args: a sequence of chainable (init_fn, update_fn) tuples.
37+
*args: an arbitrary number of ``transform``-s of
38+
:class:`GradientTransformation` or
39+
:class:`GradientTransformationExtraArgs`.
3840
3941
Returns:
4042
A :class:`GradientTransformationExtraArgs`, created by chaining the input
@@ -55,6 +57,18 @@ def chain(
5557
>>> state = chained_transform.init(params)
5658
>>> updates = {'a': -0.5}
5759
>>> updates, new_state = chained_transform.update(updates, state, params)
60+
61+
An optimizer in the chain might require extra args:
62+
63+
>>> import optax
64+
>>> opt1 = optax.scale(0.1) # scale incoming gradients
65+
>>> opt2 = optax.polyak_sgd() # requires a `value` extra arg for `update`
66+
>>> chained_transform = optax.chain(opt1, opt2)
67+
>>> state = chained_transform.init(0.5)
68+
>>> extra_args = {"value": 1.0}
69+
>>> updates, new_state = chained_transform.update(
70+
... 0.7, state, 0.7, **extra_args # extra args for all transforms
71+
... )
5872
"""
5973

6074
transforms = [base.with_extra_args_support(t) for t in args]
@@ -85,13 +99,13 @@ def update_fn(updates, state, params=None, **extra_args):
8599

86100

87101
def named_chain(
88-
*transforms: tuple[str, base.GradientTransformation]
102+
*args: tuple[str, base.GradientTransformation]
89103
) -> base.GradientTransformationExtraArgs:
90-
"""Chains optax gradient transformations.
104+
"""Applies a list of named chainable update transformations.
91105
92106
A variant of :func:`optax.chain` that allows to name each transformation.
93107
94-
Here the ``transforms`` are ``(name, transformation)`` pairs, constituted of a
108+
Here the ``args`` are ``(name, transformation)`` pairs, constituted of a
95109
string ``name`` and an associated transformation ``transformation``. The
96110
gradient transformation must be an instance of :class:`GradientTransformation`
97111
or :class:`GradientTransformationExtraArgs`.
@@ -101,34 +115,37 @@ def named_chain(
101115
with a given ``name`` can be easily retrieved as ``opt_state[name]``.
102116
103117
Args:
104-
*transforms: an arbitrary number of ``(name, tx)`` pairs, constituted of a
105-
string ``name`` and an associated transformation ``tx``. The latter is a
106-
:class:`GradientTransformation` or
118+
*args: an arbitrary number of ``(name, transform)`` pairs, constituted of a
119+
string ``name`` and an associated transformation ``transform``. The latter
120+
is a :class:`GradientTransformation` or
107121
:class:`GradientTransformationExtraArgs`.
108122
109123
Returns:
110124
A single (init_fn, update_fn) tuple.
111125
112126
Examples:
113-
114-
>>> # tx1 is a GradientTransformation with no extra_args.
115-
>>> # tx2 is a GradientTransformationExtraArgs that requires `loss`.
116-
>>> # tx3 is a GradientTransformationExtraArgs that requires `temperature`.
117-
>>> tx = named_chain(('one', tx1), ('two', tx2), ('three', tx3))
118-
>>> extra_args={'loss': 0.3, 'temperature': 0.01}
119-
>>> tx.init(params)
120-
>>> tx.update(grads, state, params, **extra_args)
127+
>>> import optax
128+
>>> opt1 = optax.scale(0.1) # scale incoming gradients
129+
>>> opt2 = optax.polyak_sgd() # requires a `value` extra arg for `update`
130+
>>> chained_transform = optax.named_chain(("scale", opt1), ("sgd", opt2))
131+
>>> state = chained_transform.init(0.5)
132+
>>> extra_args = {"value": 1.0}
133+
>>> updates, new_state = chained_transform.update(
134+
... 0.7, state, 0.7, **extra_args # extra args for all transforms
135+
... )
136+
>>> tuple(new_state.keys()) == ("scale", "sgd")
137+
True
121138
"""
122139

123-
names = [name for name, _ in transforms]
140+
names = [name for name, _ in args]
124141

125142
if len(names) != len(set(names)):
126143
raise ValueError(
127144
f'Named transformations must have unique names, but got {names}'
128145
)
129146

130147
transforms = [
131-
(name, base.with_extra_args_support(t)) for name, t in transforms
148+
(name, base.with_extra_args_support(t)) for name, t in args
132149
]
133150

134151
def init_fn(params):

0 commit comments

Comments
 (0)