SNLDS
Switching non-linear dynamical system trained with collapsed amortized variational inference (CAVI-SNLDS).
Warning
Experimental. On a 54-series sample of TSB-SEG (TSSB, UTSA, SKAB, MoCap), with the default parameters, SNLDS scores below a random segmentation (bidirectional covering 0.074 against 0.377, ARI 0.066 against 0.208): its labels change about 200 times more often than the true regimes. Training five times longer did not help on the two series tried. It is kept for further study, not as a recommended detector.
Description
SNLDS models a time series with a discrete regime \(s_t \in \{1, \dots, K\}\), a continuous latent state \(z_t\) and an observation \(x_t\). Each regime has its own non-linear transition \(p(z_t \mid z_{t-1}, s_t)\), an MLP; the regime switches follow \(p(s_t \mid s_{t-1}, x_{t-1})\), and \(x_t\) is emitted from \(z_t\) by a shared network.
Training maximises an evidence lower bound. An RNN infers the continuous states \(q(z_{1:T} \mid x_{1:T})\), and the discrete states are integrated out exactly with the forward-backward algorithm.
After training, each time step receives the regime of highest posterior probability \(p(s_t \mid x_{1:T}, z_{1:T})\).
Two devices from the paper prevent the collapse onto a single regime: a
cross-entropy regulariser between the regime posterior and a uniform prior,
with weight \(\beta\), and a temperature \(\tau\) on the discrete
transitions. Both start large and decay, \(\beta\) first, then
\(\tau\) down to 1. tsseg follows the schedule of the paper’s Reacher
experiment (\(\beta_0 = \tau_0 = 1000\), decay by 0.975 every 500 steps
after steps 50,000 and 100,000, out of 300,000), scaled to n_train_steps:
the decays start after n_train_steps / 6 and n_train_steps / 3 steps,
with a factor 0.975 every n_train_steps / 600 steps.
Each gradient step uses batch_size windows of train_window points drawn
at random positions of the series, which bounds the cost of a step; prediction
runs on the whole series. The paper trains on minibatches of 32 short
sequences (50 to 100 steps) from many trajectories; tsseg draws its windows from
the single series it segments.
n_states is the number of regimes)tf-keras
(pip install tsseg[snlds])Note
Training is slow. A step costs \(O(BLK^2)\) for batch_size \(B\)
windows of \(L\) points, independent of the length of the series: about
0.1 s on one CPU thread with the defaults, so about 3 minutes for the 2,000
default steps. The first call also spends a few seconds compiling the training
graph.
Parameters
Name |
Type |
Default |
Description |
|---|---|---|---|
|
int |
|
Number of discrete regimes \(K\). |
|
int |
|
Dimension of the continuous latent state \(z_t\). |
|
int |
|
Hidden size of the inference RNN. |
|
str |
|
Inference RNN cell ( |
|
int |
|
Number of gradient steps; the schedules scale with it. |
|
float |
|
Adam learning rate. |
|
int |
|
Training windows per gradient step. |
|
int / None |
|
Length of the training windows ( |
|
str |
|
Training objective ( |
|
bool |
|
Anneal the temperature of the discrete transitions down to 1. |
|
float |
|
Initial temperature. |
|
bool |
|
Add the cross-entropy regulariser on regime usage. |
|
float |
|
Initial weight of the regulariser. |
|
int / None |
|
Seed of the training windows and of TensorFlow (a few labels can still differ between calls). |
|
int |
|
Log the objective every tenth of training when |
|
int |
|
Time axis. |
Usage
from tsseg.algorithms import SNLDSDetector
detector = SNLDSDetector(n_states=3)
labels = detector.fit_predict(X)
Implementation: wrapper around the authors’ TensorFlow code (Google
Research, Apache License 2.0), vendored in
tsseg/algorithms/snlds/vendor with relative imports and a Keras 3 fix of the
inference RNN.
Reference: Dong, Seybold, Murphy & Bui (2020), Collapsed Amortized Variational Inference for Switching Nonlinear Dynamical Systems, ICML.
API reference
SNLDS (Switching Non-Linear Dynamical System) detector for time series segmentation.
- Wraps the CAVI-SNLDS model from:
Dong, Z., Seybold, B., Murphy, K., & Bui, H. (2020). Collapsed Amortized Variational Inference for Switching Nonlinear Dynamical Systems. ICML 2020.
The model learns discrete regime labels via variational inference with a forward-backward algorithm over discrete states, making it a natural state detector.
- class tsseg.algorithms.snlds.detector.SNLDSDetector(*, n_states=3, hidden_dim=8, rnn_dim=4, rnn_type='simplernn', n_train_steps=2000, learning_rate=0.0001, batch_size=8, train_window=256, objective='elbo', use_temperature_annealing=True, temperature_init=1000.0, use_cross_entropy_reg=True, xent_init=1000.0, random_state=42, verbose=0, axis=0)[source]
Bases:
BaseSegmenterState detector based on Switching Non-Linear Dynamical Systems (CAVI-SNLDS).
Uses collapsed amortized variational inference to learn discrete regimes in time series data. After training, the discrete state posterior
p(s_t | x_{1:T}, z_{1:T})is used to assign a regime label to each time-step.Warning
Experimental. On a sample of TSB-SEG, with the default parameters, SNLDS scores below a random segmentation: its labels change far more often than the true regimes. See the documentation page.
- Parameters:
n_states (
int) – Number of discrete regimes (K).hidden_dim (
int) – Dimension of the continuous latent state z_t.rnn_dim (
int) – Hidden dimension of the posterior inference RNN.rnn_type (
str) – RNN cell type for inference network (“gru”, “lstm”, “simplernn”).n_train_steps (
int) – Number of gradient steps for training.learning_rate (
float) – Learning rate for Adam optimiser.batch_size (
int) – Number of training windows per gradient step.train_window (
int|None) – Length of the training windows, drawn at random positions of the series at each step.None(or a value at least the length of the series) trains on the whole series, withbatch_sizecopies of it.objective (
str) – Training objective (“elbo” or “iwae”).use_temperature_annealing (
bool) – Anneal the temperature of the discrete transitions fromtemperature_initdown to 1 (see Notes).temperature_init (
float) – Initial temperature.use_cross_entropy_reg (
bool) – Add the cross-entropy regulariser on regime usage, with a weight that decays fromxent_inittowards 0 (see Notes).xent_init (
float) – Initial weight of the cross-entropy regulariser.random_state (
int|None) – Seed of the training windows, and of TensorFlow (global seed, set at the start offitandpredict). TensorFlow’s sampling is not fully reproducible: a few labels (about 0.1 % on MoCap) can differ between two calls.verbose (
int) – Log the objective ten times during training when>= 1.axis (
int) – Time axis of the input array.
Notes
The schedules follow the paper’s Reacher experiment (appendix), scaled to
n_train_steps: there, the regulariser weight starts at 1,000 and decays by a factor 0.975 every 500 steps after step 50,000, the temperature does the same after step 100,000 (down to 1), and training lasts 300,000 steps. Here the weight decays aftern_train_steps / 6steps and the temperature aftern_train_steps / 3, by 0.975 everyn_train_steps / 600steps, so that both reach the same final values.Training on random windows bounds the cost of a step, which otherwise runs a forward-backward pass over the whole series. The paper trains on minibatches of 32 short sequences (50 to 100 steps) from many trajectories; here the windows come from the single series to segment. Prediction uses the whole series.
The vendored model code comes from Google Research (Apache License 2.0), see
tsseg/algorithms/snlds/vendor.References
- set_fit_request(*, axis: bool | None | str = '$UNCHANGED$') SNLDSDetector
Configure whether metadata should be requested to be passed to the
fitmethod.Note that this method is only relevant when this estimator is used as a sub-estimator within a meta-estimator and metadata routing is enabled with
enable_metadata_routing=True(seesklearn.set_config()). Please check the User Guide on how the routing mechanism works.The options for each parameter are:
True: metadata is requested, and passed tofitif provided. The request is ignored if metadata is not provided.False: metadata is not requested and the meta-estimator will not pass it tofit.None: metadata is not requested, and the meta-estimator will raise an error if the user provides it.str: metadata should be passed to the meta-estimator with this given alias instead of the original name.
The default (
sklearn.utils.metadata_routing.UNCHANGED) retains the existing request. This allows you to change the request for some parameters and not others.Added in version 1.3.
- set_predict_request(*, axis: bool | None | str = '$UNCHANGED$') SNLDSDetector
Configure whether metadata should be requested to be passed to the
predictmethod.Note that this method is only relevant when this estimator is used as a sub-estimator within a meta-estimator and metadata routing is enabled with
enable_metadata_routing=True(seesklearn.set_config()). Please check the User Guide on how the routing mechanism works.The options for each parameter are:
True: metadata is requested, and passed topredictif provided. The request is ignored if metadata is not provided.False: metadata is not requested and the meta-estimator will not pass it topredict.None: metadata is not requested, and the meta-estimator will raise an error if the user provides it.str: metadata should be passed to the meta-estimator with this given alias instead of the original name.
The default (
sklearn.utils.metadata_routing.UNCHANGED) retains the existing request. This allows you to change the request for some parameters and not others.Added in version 1.3.