DeepEnsemble¶
Defined in fynance.models.uncertainty
- class DeepEnsemble(factory, n_members=5, seed=0)[source]
Bases:
objectEpistemic-uncertainty proxy from an ensemble of independent nets.
Trains
n_membersindependent copies of aSignalModel-conforming net (built fresh byfactoryfor each member) and aggregates their predictions. The member-to-member spread —predict_std— is a proxy for epistemic uncertainty (how much the fit itself could have differed had training gone slightly differently), as distinct from the aleatoric noise in the data itself. See Lakshminarayanan, Pritzel & Blundell (2017), “Simple and Scalable Predictive Uncertainty Estimation using Deep Ensembles”.Conforms to the
SignalModelprotocol (fit/predict): it drops into the harness like any other model, withpredict_std/predict_membersas the extra uncertainty API.- Parameters:
- factorycallable
No-argument callable returning a fresh, unfit
SignalModel-conforming net (e.g. a closure building aMultiLayerPerceptronand callingset_optimizeron it, or any object withfit(X, y)/predict(X)). Called once per member, perfitcall.- n_membersint
Number of independently trained members. Default 5.
- seedint
Base seed. Member
iis built and trained undertorch.manual_seed(seed + i)(andnp.random.seed(seed + i)), so the ensemble as a whole is reproducible while members differ from one another.
See also
fynance.models.uncertainty.MCDropoutfynance.models.ensemble.StackingEnsemble
Notes
Determinism limits.
fitreseeds the global PyTorch and NumPy generators immediately before building and training each member. This reproducibly diversifies members whose randomness (parameter initialization, dropout masks, data shuffling) is drawn from those global generators — which coversMultiLayerPerceptronand the otherBaseNeuralNetsubclasses. A member that instead draws from its own privatetorch.Generator(for exampleObjectiveModel’s mini-batch shuffling, seeded from its own constructorseedargument rather than the global RNG) is unaffected by this reseed step: give such afactorya distinct explicit per-member seed if independent draws from that private generator are also required. Two fullfitruns with the sameDeepEnsemble.seed(and the samefactory/data) are otherwise reproducible.Examples
>>> import numpy as np >>> import torch >>> from fynance.models.mlp import MultiLayerPerceptron >>> from fynance.models.uncertainty import DeepEnsemble >>> rng = np.random.default_rng(0) >>> X = rng.standard_normal((40, 2)).astype(np.float32) >>> y = np.sin(X[:, :1]).astype(np.float32) >>> def factory(): ... net = MultiLayerPerceptron(2, 1, layers=[8], activation=torch.nn.Tanh) ... net.set_optimizer(torch.nn.MSELoss, torch.optim.Adam, lr=1e-2) ... return net >>> ens = DeepEnsemble(factory, n_members=3, seed=0).fit(X, y) >>> ens.predict(X).shape (40,) >>> ens.predict_members(X).shape (3, 40)
- fit(X, y)[source]
Build and train
n_membersindependent copies offactory().- Parameters:
- X, yarray-like
Training data forwarded verbatim to each member’s
fit(X, y).
- Returns:
- DeepEnsemble
self.
- predict(X)[source]
Ensemble mean prediction, shape
(T,).
- predict_members(X)[source]
Per-member predictions, shape
(n_members, T).- Parameters:
- Xarray-like
Inputs, shape
(T, N).
- Returns:
- numpy.ndarray
Stacked per-member predictions, shape
(n_members, T).
- Raises:
- RuntimeError
If called before
fit.
- predict_std(X)[source]
Cross-member standard deviation, shape
(T,)— epistemic proxy.