Optimizer
The optimizer is the component that updates the model’s weights from their gradients during training. It defines the optimization algorithm and its hyperparameters.
Usage
The optimizer occupies the components.optimizer slot.
components:
optimizer:
name: adam
kwargs:
lr: 0.0002
weight_decay: 0.00005
How it Works
When the run is assembled, the optimizer takes the model component’s parameters and wraps the corresponding optimization algorithm. It exposes the two operations the training loop drives: a step that applies an update, and a gradient reset.
Variants
Registering a new optimizer
An optimizer is a subclass of Optimizer that declares a name and
version, validates its configuration, performs one-time setup in build,
binds to the model parameters on attach, and implements the two operations the
training loop calls:
build(self) -> NoneOne-time setup, before the model parameters are available.
step(self) -> NoneApply one optimization update.
zero_grad(self, set_to_none=True) -> NoneClear the accumulated gradients.
The underlying algorithm is typically constructed in on_attach, where the model
component (and therefore its parameters) is available.
from typing import Any, ClassVar
from icegraph.common.engine import ComponentKind
from icegraph.engine.components.optimizer import Optimizer, OptimizerFactory
from .config import MyOptimizerConfig
class MyOptimizer(Optimizer[MyOptimizerConfig]):
name: ClassVar[str] = "my-optimizer"
version: ClassVar[int] = 1
@classmethod
def validate_config(cls, config: dict[str, Any]) -> MyOptimizerConfig:
return MyOptimizerConfig(**config)
def build(self) -> None:
... # one-time setup before the model is available
def on_attach(self) -> None:
model = self._ctx.components.require(ComponentKind.MODEL, required_by=type(self))
... # build the optimizer from model.parameters()
def step(self) -> None:
...
def zero_grad(self, set_to_none: bool = True) -> None:
...
OptimizerFactory.register(MyOptimizer)