TICKET-052: Model persistence round-trip for ActorCriticNetworks
Status: OPEN
Cycle: 43
Priority: High
Target module: alloc/models/networks.py — ActorCriticNetworks
Summary
Backtest mode (alloc/core.py main) saves actor_weights.h5 and
critic_weights.h5 after training, but there is no load path: a saved
model cannot be re-instantiated. The seed's predict mode loads a previously
trained model before producing a live allocation. To close that parity gap
(see TICKET-053), ActorCriticNetworks needs a save/load round-trip that
persists both the weights and the config needed to reconstruct the
network (input_dim, num_assets, min_cash_allocation, and the hyperparameters
that affect architecture: dropout, gamma, tau).
Evidence
alloc/core.py lines 733-735: networks.actor.save_weights(...) /
networks.critic.save_weights(...) — save only, never load.
alloc/models/networks.py ActorCriticNetworks.__init__ (lines 285-340)
builds actor/critic/targets/optimizers from input_dim, num_assets,
min_cash_allocation, dropout. There is no save_model/load_model
method and no config file is written.
- The actor architecture depends on
input_dim and num_assets (per-asset
branch widths scale with the asset index), so loading weights into a
freshly-built network with the wrong dimensions will fail or silently
mismatch. The config must be persisted alongside the weights.
Implementation plan
ActorCriticNetworks.save_model(directory) — write:
actor_weights.h5, critic_weights.h5 (via keras save_weights).
model_config.json with input_dim, num_assets,
min_cash_allocation, dropout, gamma, tau, actor_lr,
critic_lr.
ActorCriticNetworks.load_model(directory) (classmethod) — read
model_config.json, construct an ActorCriticNetworks with those
parameters, then actor.load_weights / critic.load_weights, and
re-sync the target networks (actor_target.set_weights,
critic_target.set_weights). Return the instance.
- Raise
FileNotFoundError with a clear message if model_config.json or
either weights file is missing.
Verification
pytest tests/test_actor_critic.py -x -q — new round-trip test passes:
build a small network, save to a tmp dir, load, assert
get_allocation(state) is identical (or near-identical) before/after and
that config fields round-trip.
ruff check alloc/models/networks.py — clean.
mypy alloc/models/networks.py --ignore-missing-imports — clean.
TICKET-052: Model persistence round-trip for ActorCriticNetworks
Status: OPEN
Cycle: 43
Priority: High
Target module:
alloc/models/networks.py—ActorCriticNetworksSummary
Backtest mode (
alloc/core.pymain) savesactor_weights.h5andcritic_weights.h5after training, but there is no load path: a savedmodel cannot be re-instantiated. The seed's predict mode loads a previously
trained model before producing a live allocation. To close that parity gap
(see TICKET-053),
ActorCriticNetworksneeds a save/load round-trip thatpersists both the weights and the config needed to reconstruct the
network (input_dim, num_assets, min_cash_allocation, and the hyperparameters
that affect architecture: dropout, gamma, tau).
Evidence
alloc/core.pylines 733-735:networks.actor.save_weights(...)/networks.critic.save_weights(...)— save only, never load.alloc/models/networks.pyActorCriticNetworks.__init__(lines 285-340)builds actor/critic/targets/optimizers from
input_dim,num_assets,min_cash_allocation,dropout. There is nosave_model/load_modelmethod and no config file is written.
input_dimandnum_assets(per-assetbranch widths scale with the asset index), so loading weights into a
freshly-built network with the wrong dimensions will fail or silently
mismatch. The config must be persisted alongside the weights.
Implementation plan
ActorCriticNetworks.save_model(directory)— write:actor_weights.h5,critic_weights.h5(viakerassave_weights).model_config.jsonwithinput_dim,num_assets,min_cash_allocation,dropout,gamma,tau,actor_lr,critic_lr.ActorCriticNetworks.load_model(directory)(classmethod) — readmodel_config.json, construct anActorCriticNetworkswith thoseparameters, then
actor.load_weights/critic.load_weights, andre-sync the target networks (
actor_target.set_weights,critic_target.set_weights). Return the instance.FileNotFoundErrorwith a clear message ifmodel_config.jsonoreither weights file is missing.
Verification
pytest tests/test_actor_critic.py -x -q— new round-trip test passes:build a small network, save to a tmp dir, load, assert
get_allocation(state)is identical (or near-identical) before/after andthat config fields round-trip.
ruff check alloc/models/networks.py— clean.mypy alloc/models/networks.py --ignore-missing-imports— clean.