omnibias.keras.training.k_scheduler
Keras 3 operator layers and activation paths implemented with keras.ops for TensorFlow, JAX, or Torch.
import omnibias.keras.training.k_schedulerModule contract & mathematical conventions
Plateau-triggered K-growth scheduler (Keras backend).
Watches a scalar metric; when it has not improved by min_delta for
patience consecutive epochs, calls grow(strategy) on every
GrowableOperatorMultiBiasUnit reachable from the model. After
growth, an LR-boost window is opened. Mirrors
omnibias.torch.training.k_scheduler.KGrowthScheduler; the
training loop is responsible for reading current_lr_multiplier.
Shared formulas do not imply universal floating-point identity. Verify dtype, shape, derivative-order support, and the stated numerical assumptions for the path you use.
AnchorProvider
omnibias.keras.training.AnchorProviderSource ↗AnchorProvider = Callable[[str, GrowableOperatorMultiBiasUnit], 'float | np.ndarray | None']This exported constant is defined by the expression above. Its exact value and annotation come from the pinned source; use it with the module contract.
Read the implementation
AnchorProvider = Callable[
[str, GrowableOperatorMultiBiasUnit], "float | np.ndarray | None"
]Other public import paths
omnibias.keras.training.AnchorProvideromnibias.keras.training.k_scheduler.AnchorProvider
GrowthEvent
omnibias.keras.training.GrowthEventSource ↗class GrowthEventDataclass constructor fields; inherited fields, if any, are declared by the base class. A field(...) expression describes a default factory or field options, not a literal argument default.
One growth event recorded by the scheduler.
Parameters
| Name | Type & default | Contract |
|---|---|---|
epochdataclass field | intRequired | See the operation contract and implementation below. |
module_namedataclass field | strRequired | See the operation contract and implementation below. |
new_active_Kdataclass field | intRequired | See the operation contract and implementation below. |
strategydataclass field | strRequired | See the operation contract and implementation below. |
anchordataclass field | float | NoneDefault: None | See the operation contract and implementation below. |
Fields & methods
epochfield
epoch: intDeclared int field on GrowthEvent. A value must be provided when constructing the configuration, unless an inherited constructor supplies it.
View source ↗module_namefield
module_name: strDeclared str field on GrowthEvent. A value must be provided when constructing the configuration, unless an inherited constructor supplies it.
View source ↗new_active_Kfield
new_active_K: intDeclared int field on GrowthEvent. A value must be provided when constructing the configuration, unless an inherited constructor supplies it.
View source ↗strategyfield
strategy: strDeclared str field on GrowthEvent. A value must be provided when constructing the configuration, unless an inherited constructor supplies it.
View source ↗anchorfield
anchor: float | None = NoneDeclared float | None field on GrowthEvent. Default expression: None.
Read the implementation
class GrowthEvent:
"""One growth event recorded by the scheduler."""
epoch: int
module_name: str
new_active_K: int
strategy: str
anchor: float | None = NoneOther public import paths
omnibias.keras.training.GrowthEventomnibias.keras.training.k_scheduler.GrowthEvent
KGrowthScheduler
omnibias.keras.KGrowthSchedulerSource ↗class KGrowthSchedulerDataclass constructor fields; inherited fields, if any, are declared by the base class. A field(...) expression describes a default factory or field options, not a literal argument default.
Plateau-triggered K-growth controller (Keras backend).
Parameters mirror the torch scheduler: patience, min_delta,
max_K, strategy, lr_boost_factor, lr_boost_epochs,
cooldown_epochs, and an optional anchor_provider.
Parameters
| Name | Type & default | Contract |
|---|---|---|
modeldataclass field | layers.LayerRequired | See the operation contract and implementation below. |
patiencedataclass field | intDefault: 10 | See the operation contract and implementation below. |
min_deltadataclass field | floatDefault: 0.001 | See the operation contract and implementation below. |
max_Kdataclass field | intDefault: 8 | See the operation contract and implementation below. |
strategydataclass field | GrowStrategyDefault: 'pair' | See the operation contract and implementation below. |
lr_boost_factordataclass field | floatDefault: 10.0 | See the operation contract and implementation below. |
lr_boost_epochsdataclass field | intDefault: 5 | See the operation contract and implementation below. |
cooldown_epochsdataclass field | intDefault: 5 | See the operation contract and implementation below. |
anchor_providerdataclass field | AnchorProvider | NoneDefault: None | See the operation contract and implementation below. |
best_lossdataclass field | floatDefault: float('inf') | See the operation contract and implementation below. |
epochs_since_improvedataclass field | intDefault: 0 | See the operation contract and implementation below. |
cooldown_remainingdataclass field | intDefault: 0 | See the operation contract and implementation below. |
boost_remainingdataclass field | intDefault: 0 | See the operation contract and implementation below. |
growth_historydataclass field | list[GrowthEvent]Default: field(default_factory=list) | See the operation contract and implementation below. |
Executed regression · scheduler requires growable unit
Recorded coverage confirms this test executed the API body. This example belongs to the pinned upstream test suite. It may use fixtures and imports from its full file. Run it from that checkout with its test dependencies installed.
def test_scheduler_requires_growable_unit() -> None:
model = keras.Sequential(
[keras.layers.Input(shape=(4,)), keras.layers.Dense(4)]
)
with pytest.raises(ValueError):
KGrowthScheduler(model)python -m pytest "packages/omnibias-keras/tests/test_growable.py::test_scheduler_requires_growable_unit" -qRegression example · scheduler grows on plateau
This example belongs to the pinned upstream test suite. It may use fixtures and imports from its full file. Run it from that checkout with its test dependencies installed.
def test_scheduler_grows_on_plateau() -> None:
model = keras.Sequential(
[keras.layers.Input(shape=(4,)), GrowableOMBU(num_channels=4, init_K=1, K_max=5)]
)
sched = KGrowthScheduler(model, patience=2, min_delta=1e-3, max_K=5, strategy="pair")
# Feed a flat metric to trigger a plateau.
for epoch in range(6):
sched.step(1.0, epoch=epoch)
assert sched.total_growth_events() >= 1python -m pytest packages/omnibias-keras/tests/test_growable.py -k test_scheduler_grows_on_plateau -qFields & methods
modelfield
model: layers.LayerDeclared layers.Layer field on KGrowthScheduler. A value must be provided when constructing the configuration, unless an inherited constructor supplies it.
View source ↗patiencefield
patience: int = 10Declared int field on KGrowthScheduler. Default expression: 10.
min_deltafield
min_delta: float = 0.001Declared float field on KGrowthScheduler. Default expression: 0.001.
strategyfield
strategy: GrowStrategy = 'pair'Declared GrowStrategy field on KGrowthScheduler. Default expression: 'pair'.
lr_boost_factorfield
lr_boost_factor: float = 10.0Declared float field on KGrowthScheduler. Default expression: 10.0.
lr_boost_epochsfield
lr_boost_epochs: int = 5Declared int field on KGrowthScheduler. Default expression: 5.
cooldown_epochsfield
cooldown_epochs: int = 5Declared int field on KGrowthScheduler. Default expression: 5.
anchor_providerfield
anchor_provider: AnchorProvider | None = NoneDeclared AnchorProvider | None field on KGrowthScheduler. Default expression: None.
best_lossfield
best_loss: float = float('inf')Declared float field on KGrowthScheduler. Default expression: float('inf').
epochs_since_improvefield
epochs_since_improve: int = 0Declared int field on KGrowthScheduler. Default expression: 0.
cooldown_remainingfield
cooldown_remaining: int = 0Declared int field on KGrowthScheduler. Default expression: 0.
boost_remainingfield
boost_remaining: int = 0Declared int field on KGrowthScheduler. Default expression: 0.
growth_historyfield
growth_history: list[GrowthEvent] = field(default_factory=list)Declared list[GrowthEvent] field on KGrowthScheduler. Default expression: field(default_factory=list).
__post_init__method
__post_init__(self) -> NoneSee the class contract above and the exact method implementation below.
Returns: None
Validation & failure cases
- When
not self._growable_units(), raisesValueError('KGrowthScheduler: the model contains no GrowableOperatorMultiBiasUnit children; nothing to grow.').
Executed regression · scheduler requires growable unit
Recorded coverage confirms this test executed the API body. This example belongs to the pinned upstream test suite. It may use fixtures and imports from its full file. Run it from that checkout with its test dependencies installed.
def test_scheduler_requires_growable_unit() -> None:
model = keras.Sequential(
[keras.layers.Input(shape=(4,)), keras.layers.Dense(4)]
)
with pytest.raises(ValueError):
KGrowthScheduler(model)python -m pytest "packages/omnibias-keras/tests/test_growable.py::test_scheduler_requires_growable_unit" -qMethod implementation
def __post_init__(self) -> None:
if not self._growable_units():
raise ValueError(
"KGrowthScheduler: the model contains no "
"GrowableOperatorMultiBiasUnit children; nothing to grow."
)current_lr_multiplierproperty
current_lr_multiplier(self) -> floatSee the class contract above and the exact method implementation below.
Returns: float
Executed regression · scheduler grows on plateau
Recorded coverage confirms this test executed the API body. This example belongs to the pinned upstream test suite. It may use fixtures and imports from its full file. Run it from that checkout with its test dependencies installed.
def test_scheduler_grows_on_plateau() -> None:
model = keras.Sequential(
[keras.layers.Input(shape=(4,)), GrowableOMBU(num_channels=4, init_K=1, K_max=5)]
)
sched = KGrowthScheduler(model, patience=2, min_delta=1e-3, max_K=5, strategy="pair")
# Feed a flat metric to trigger a plateau.
for epoch in range(6):
sched.step(1.0, epoch=epoch)
assert sched.total_growth_events() >= 1python -m pytest "packages/omnibias-keras/tests/test_growable.py::test_scheduler_grows_on_plateau" -qMethod implementation
def current_lr_multiplier(self) -> float:
return self.lr_boost_factor if self.boost_remaining > 0 else 1.0stepmethod
step(self, metric: float, *, epoch: int) -> floatUpdate with the latest metric; return the LR multiplier to apply next.
Parameters
| Name | Type & default | Contract |
|---|---|---|
metricpositional-or-keyword | floatRequired | See the operation contract and implementation below. |
epochkeyword-only | intRequired | See the operation contract and implementation below. |
Returns: float
Executed regression · scheduler grows on plateau
Recorded coverage confirms this test executed the API body. This example belongs to the pinned upstream test suite. It may use fixtures and imports from its full file. Run it from that checkout with its test dependencies installed.
def test_scheduler_grows_on_plateau() -> None:
model = keras.Sequential(
[keras.layers.Input(shape=(4,)), GrowableOMBU(num_channels=4, init_K=1, K_max=5)]
)
sched = KGrowthScheduler(model, patience=2, min_delta=1e-3, max_K=5, strategy="pair")
# Feed a flat metric to trigger a plateau.
for epoch in range(6):
sched.step(1.0, epoch=epoch)
assert sched.total_growth_events() >= 1python -m pytest "packages/omnibias-keras/tests/test_growable.py::test_scheduler_grows_on_plateau" -qMethod implementation
def step(self, metric: float, *, epoch: int) -> float:
"""Update with the latest metric; return the LR multiplier to apply next."""
if self.boost_remaining > 0:
self.boost_remaining -= 1
if not self._initialized:
self.best_loss = metric
self.epochs_since_improve = 0
self._initialized = True
else:
improved = metric < self.best_loss * (1.0 - self.min_delta)
if improved:
self.best_loss = metric
self.epochs_since_improve = 0
else:
self.epochs_since_improve += 1
ready = (
self.epochs_since_improve >= self.patience
and self.cooldown_remaining == 0
and self._has_capacity()
)
grew_this_step = False
if ready:
grew_this_step = self._grow_all_eligible(epoch=epoch)
if grew_this_step:
self.epochs_since_improve = 0
self.boost_remaining = self.lr_boost_epochs
self.cooldown_remaining = self.cooldown_epochs
if not grew_this_step and self.cooldown_remaining > 0:
self.cooldown_remaining -= 1
return self.current_lr_multiplierreset_bestmethod
reset_best(self) -> NoneSee the class contract above and the exact method implementation below.
Returns: None
Method implementation
def reset_best(self) -> None:
self.best_loss = float("inf")
self.epochs_since_improve = 0
self._initialized = Falseactive_K_summarymethod
active_K_summary(self) -> dict[str, int]See the class contract above and the exact method implementation below.
Returns: dict[str, int]
Method implementation
def active_K_summary(self) -> dict[str, int]:
return {name: mod.active_K for name, mod in self._growable_units()}total_growth_eventsmethod
total_growth_events(self) -> intSee the class contract above and the exact method implementation below.
Returns: int
Executed regression · scheduler grows on plateau
Recorded coverage confirms this test executed the API body. This example belongs to the pinned upstream test suite. It may use fixtures and imports from its full file. Run it from that checkout with its test dependencies installed.
def test_scheduler_grows_on_plateau() -> None:
model = keras.Sequential(
[keras.layers.Input(shape=(4,)), GrowableOMBU(num_channels=4, init_K=1, K_max=5)]
)
sched = KGrowthScheduler(model, patience=2, min_delta=1e-3, max_K=5, strategy="pair")
# Feed a flat metric to trigger a plateau.
for epoch in range(6):
sched.step(1.0, epoch=epoch)
assert sched.total_growth_events() >= 1python -m pytest "packages/omnibias-keras/tests/test_growable.py::test_scheduler_grows_on_plateau" -qMethod implementation
def total_growth_events(self) -> int:
return len(self.growth_history)Read the implementation
class KGrowthScheduler:
"""Plateau-triggered K-growth controller (Keras backend).
Parameters mirror the torch scheduler: ``patience``, ``min_delta``,
``max_K``, ``strategy``, ``lr_boost_factor``, ``lr_boost_epochs``,
``cooldown_epochs``, and an optional ``anchor_provider``.
"""
model: layers.Layer
patience: int = 10
min_delta: float = 1e-3
max_K: int = 8
strategy: GrowStrategy = "pair"
lr_boost_factor: float = 10.0
lr_boost_epochs: int = 5
cooldown_epochs: int = 5
anchor_provider: AnchorProvider | None = None
best_loss: float = float("inf")
epochs_since_improve: int = 0
cooldown_remaining: int = 0
boost_remaining: int = 0
growth_history: list[GrowthEvent] = field(default_factory=list)
_initialized: bool = False
def __post_init__(self) -> None:
if not self._growable_units():
raise ValueError(
"KGrowthScheduler: the model contains no "
"GrowableOperatorMultiBiasUnit children; nothing to grow."
)
@property
def current_lr_multiplier(self) -> float:
return self.lr_boost_factor if self.boost_remaining > 0 else 1.0
def step(self, metric: float, *, epoch: int) -> float:
"""Update with the latest metric; return the LR multiplier to apply next."""
if self.boost_remaining > 0:
self.boost_remaining -= 1
if not self._initialized:
self.best_loss = metric
self.epochs_since_improve = 0
self._initialized = True
else:
improved = metric < self.best_loss * (1.0 - self.min_delta)
if improved:
self.best_loss = metric
self.epochs_since_improve = 0
else:
self.epochs_since_improve += 1
ready = (
self.epochs_since_improve >= self.patience
and self.cooldown_remaining == 0
and self._has_capacity()
)
grew_this_step = False
if ready:
grew_this_step = self._grow_all_eligible(epoch=epoch)
if grew_this_step:
self.epochs_since_improve = 0
self.boost_remaining = self.lr_boost_epochs
self.cooldown_remaining = self.cooldown_epochs
if not grew_this_step and self.cooldown_remaining > 0:
self.cooldown_remaining -= 1
return self.current_lr_multiplier
def reset_best(self) -> None:
self.best_loss = float("inf")
self.epochs_since_improve = 0
self._initialized = False
def active_K_summary(self) -> dict[str, int]:
return {name: mod.active_K for name, mod in self._growable_units()}
def total_growth_events(self) -> int:
return len(self.growth_history)
# ----- internals -------------------------------------------------------
def _growable_units(self) -> list[tuple[str, GrowableOperatorMultiBiasUnit]]:
return [
(name, mod)
for name, mod in _iter_sublayers(self.model)
if isinstance(mod, GrowableOperatorMultiBiasUnit)
]
def _strategy_increment(self) -> int:
return 2 if self.strategy == "pair" else 1
def _has_capacity(self) -> bool:
inc = self._strategy_increment()
for _, mod in self._growable_units():
if mod.active_K + inc <= min(self.max_K, mod.K_max):
return True
return False
def _grow_all_eligible(self, *, epoch: int) -> bool:
inc = self._strategy_increment()
grew_any = False
for name, mod in self._growable_units():
if mod.active_K + inc > min(self.max_K, mod.K_max):
continue
anchor: float | np.ndarray | None = None
if self.anchor_provider is not None and self.strategy == "pair":
try:
anchor = self.anchor_provider(name, mod)
except Exception as exc: # noqa: BLE001
# An anchor provider failure must not abort training; log and
# fall back to the default anchor (anchor=None).
_LOGGER.warning(
"anchor_provider failed for %r: %r; falling back to "
"default anchor.",
name,
exc,
)
anchor = None
try:
if anchor is not None:
mod.grow(strategy=self.strategy, anchor_value=anchor)
else:
mod.grow(strategy=self.strategy)
except (RuntimeError, ValueError):
continue
anchor_scalar: float | None = None
if isinstance(anchor, np.ndarray):
anchor_scalar = float(anchor.mean())
elif anchor is not None:
anchor_scalar = float(anchor)
self.growth_history.append(
GrowthEvent(
epoch=epoch,
module_name=name,
new_active_K=mod.active_K,
strategy=self.strategy,
anchor=anchor_scalar,
)
)
grew_any = True
return grew_anyOther public import paths
omnibias.keras.KGrowthScheduleromnibias.keras.training.KGrowthScheduleromnibias.keras.training.k_scheduler.KGrowthScheduler