@yibeichan/claude-skills 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +98 -0
- package/cli.js +272 -0
- package/install.py +240 -0
- package/package.json +44 -0
- package/skills/bidsapp-nidm-standards/SKILL.md +202 -0
- package/skills/bidsapp-nidm-standards/references/babs_config.md +20 -0
- package/skills/bidsapp-nidm-standards/references/cli_arguments.md +76 -0
- package/skills/bidsapp-nidm-standards/references/container_patterns.md +53 -0
- package/skills/bidsapp-nidm-standards/references/nidm_integration.md +403 -0
- package/skills/bidsapp-nidm-standards/references/repo_structure.md +121 -0
- package/skills/bidsapp-nidm-standards/references/testing_patterns.md +82 -0
- package/skills/dicom2fmriprep/SKILL.md +377 -0
- package/skills/dicom2fmriprep/evals/evals.json +26 -0
- package/skills/dicom2fmriprep/references/babs-details.md +407 -0
- package/skills/dicom2fmriprep/references/fmriprep-details.md +250 -0
- package/skills/dicom2fmriprep/references/heudiconv-details.md +243 -0
- package/skills/fmri-ssm/SKILL.md +317 -0
- package/skills/fmri-ssm/references/code_templates.md +1570 -0
- package/skills/fmri-ssm/references/downstream_analysis.md +680 -0
- package/skills/fmri-ssm/references/group_inference.md +608 -0
- package/skills/fmri-ssm/references/hrf_modeling.md +447 -0
- package/skills/fmri-ssm/references/model_catalog.md +436 -0
- package/skills/fmri-ssm/references/paradigm_guide.md +406 -0
- package/skills/fmri-ssm/references/preprocessing.md +614 -0
- package/skills/fmri-ssm.zip +0 -0
- package/skills/neuroimaging-qc/SKILL.md +203 -0
- package/skills/neuroimaging-qc/references/eeg_qc.md +400 -0
- package/skills/neuroimaging-qc/references/fmri_qc.md +343 -0
- package/skills/neuroimaging-qc/references/fnirs_qc.md +430 -0
- package/skills/neuroimaging-qc/references/structural_qc.md +454 -0
- package/skills/neuroimaging-qc/scripts/parse_fmriprep_confounds.py +153 -0
- package/skills/neuroimaging-qc/scripts/parse_mriqc.py +114 -0
- package/skills/neuroimaging-qc/scripts/qc_report.py +295 -0
- package/skills/scientific-writer/SKILL.md +202 -0
- package/skills/scientific-writer/references/citation_styles.md +163 -0
- package/skills/scientific-writer/references/field_conventions.md +245 -0
- package/skills/scientific-writer/references/figures_tables.md +225 -0
- package/skills/scientific-writer/references/reporting_guidelines.md +225 -0
- package/skills.json +54 -0
|
@@ -0,0 +1,436 @@
|
|
|
1
|
+
# Model Catalog: State-Space Models for fMRI
|
|
2
|
+
|
|
3
|
+
## Table of Contents
|
|
4
|
+
1. [Gaussian HMM](#gaussian-hmm)
|
|
5
|
+
2. [HMM-MAR / Gaussian-Linear HMM](#hmm-mar)
|
|
6
|
+
3. [Factorial HMM](#factorial-hmm)
|
|
7
|
+
4. [Input-Output HMM](#io-hmm)
|
|
8
|
+
5. [Sticky HMM and HDP-HMM](#sticky-hmm)
|
|
9
|
+
6. [HSMM — Hidden Semi-Markov Model](#hsmm)
|
|
10
|
+
7. [SLDS — Switching Linear Dynamical System](#slds)
|
|
11
|
+
8. [rSLDS — Recurrent Switching Linear Dynamical System](#rslds)
|
|
12
|
+
9. [SNLDS — Switching Nonlinear Dynamical System](#snlds)
|
|
13
|
+
10. [Hierarchical Extensions](#hierarchical)
|
|
14
|
+
11. [Model Comparison Table](#comparison)
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## 1. Gaussian HMM {#gaussian-hmm}
|
|
19
|
+
|
|
20
|
+
**Generative model:**
|
|
21
|
+
- Discrete hidden state: z_t ∈ {1, ..., K}
|
|
22
|
+
- Transition: P(z_t | z_{t-1}) = A[z_{t-1}, z_t] (K × K transition matrix)
|
|
23
|
+
- Emission: y_t | z_t = k ~ N(μ_k, Σ_k)
|
|
24
|
+
- Initial state: z_1 ~ π (K-dimensional probability vector)
|
|
25
|
+
|
|
26
|
+
**Parameters:** π (initial), A (transitions), {μ_k, Σ_k} for k=1..K
|
|
27
|
+
|
|
28
|
+
**What it captures in fMRI:**
|
|
29
|
+
Each state is a multivariate Gaussian over brain regions — capturing a spatial pattern of
|
|
30
|
+
mean activation and inter-regional covariance (functional connectivity). State transitions
|
|
31
|
+
capture time-varying shifts in these patterns.
|
|
32
|
+
|
|
33
|
+
**When to use:**
|
|
34
|
+
- Resting-state: identifying recurring brain states defined by FC patterns
|
|
35
|
+
- Task data: when states correspond to different activation patterns (different tasks)
|
|
36
|
+
- When you believe states differ primarily in mean and/or covariance, not temporal dynamics
|
|
37
|
+
- When data is limited (fewer parameters than HMM-MAR)
|
|
38
|
+
|
|
39
|
+
**When it breaks down:**
|
|
40
|
+
- States that differ only in temporal autocorrelation (same mean, same covariance, different
|
|
41
|
+
dynamics) — Gaussian HMM cannot distinguish these
|
|
42
|
+
- Very high-dimensional data without dimensionality reduction → Σ_k estimation is unstable
|
|
43
|
+
- Very fast state switching at BOLD timescale — HRF blurring conflated with state emissions
|
|
44
|
+
|
|
45
|
+
**Key practical considerations:**
|
|
46
|
+
- Covariance type matters enormously. Full covariance: K × p × (p+1)/2 parameters per state.
|
|
47
|
+
With 100 ROIs and 8 states, that's ~40,000 covariance parameters per state. You need
|
|
48
|
+
substantial data or regularization.
|
|
49
|
+
- Diagonal covariance is a common compromise for high-dimensional ROI data.
|
|
50
|
+
- Always use multiple random restarts (≥20) and K-means/GMM initialization.
|
|
51
|
+
|
|
52
|
+
**Python:** `hmmlearn.GaussianHMM`, `ssm.HMM` with `GaussianObservations`
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## 2. HMM-MAR / Gaussian-Linear HMM {#hmm-mar}
|
|
57
|
+
|
|
58
|
+
**Generative model:**
|
|
59
|
+
- Same discrete hidden state as Gaussian HMM
|
|
60
|
+
- Emission is autoregressive: y_t | z_t=k, y_{t-1}, ..., y_{t-p} ~ N(Σ_{l=1}^{p} W_k^{(l)} y_{t-l}, Σ_k)
|
|
61
|
+
- Each state has its own set of AR coefficient matrices W_k^{(l)} and noise covariance Σ_k
|
|
62
|
+
|
|
63
|
+
**Parameters:** π, A, {W_k^{(1)}, ..., W_k^{(p)}, Σ_k} for k=1..K
|
|
64
|
+
|
|
65
|
+
**What it captures in fMRI:**
|
|
66
|
+
Each state represents a distinct *dynamical regime* — not just a spatial pattern but a pattern
|
|
67
|
+
of temporal dependencies between regions. Two states might have similar mean activation but
|
|
68
|
+
different directed connectivity (region A drives region B in state 1, but B drives A in state 2).
|
|
69
|
+
|
|
70
|
+
**When to use:**
|
|
71
|
+
- Resting-state analyses where you care about time-varying directed connectivity
|
|
72
|
+
- When states are expected to differ in spectral content (different oscillatory profiles)
|
|
73
|
+
- Naturalistic paradigms where dynamics change with stimulus content (dialogue vs. action scenes)
|
|
74
|
+
- When you have sufficient data per state (AR parameters are expensive)
|
|
75
|
+
|
|
76
|
+
**When it breaks down:**
|
|
77
|
+
- Short scans with many states — AR parameter estimation becomes unstable
|
|
78
|
+
- High-dimensional data — AR coefficient matrices scale as p × n_features² per state
|
|
79
|
+
- When true differences between states are in mean activation, not dynamics (overkill)
|
|
80
|
+
|
|
81
|
+
**Key practical considerations:**
|
|
82
|
+
- AR order p: typical range 1-5 for fMRI. Higher p captures richer dynamics but needs more data.
|
|
83
|
+
p=1 is often sufficient for TR > 1s. For fast TR (< 0.8s), consider p=3-5.
|
|
84
|
+
- Total parameters per state: p × n_features² + n_features × (n_features+1)/2. This grows
|
|
85
|
+
fast. With 25 ICA components and p=3: 25² × 3 + 325 = 2,200 parameters per state.
|
|
86
|
+
- Dimensionality reduction (ICA, PCA to ~15-50 components) is almost essential.
|
|
87
|
+
- The original HMM-MAR toolbox (Vidaurre et al., 2016) was MATLAB-based. Python equivalents:
|
|
88
|
+
`osl-dynamics` (Oxford, actively maintained) or `glhmm` (Vidaurre's newer Python library).
|
|
89
|
+
|
|
90
|
+
**Python:** `osl-dynamics`, `glhmm`, or custom implementation with `ssm` library
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## 3. Factorial HMM {#factorial-hmm}
|
|
95
|
+
|
|
96
|
+
**Generative model:**
|
|
97
|
+
- Multiple independent hidden state chains: z_t^{(1)}, z_t^{(2)}, ..., z_t^{(M)}
|
|
98
|
+
- Each chain has its own transition matrix: P(z_t^{(m)} | z_{t-1}^{(m)}) = A_m
|
|
99
|
+
- Emission depends on all chains: y_t | z_t^{(1)}, ..., z_t^{(M)} ~ N(Σ_m μ_{z_t^{(m)}}^{(m)}, Σ)
|
|
100
|
+
|
|
101
|
+
**What it captures in fMRI:**
|
|
102
|
+
Multiple independent sources of state variation. For example, one chain captures arousal
|
|
103
|
+
(high/low), another captures task engagement (on/off), another captures default mode
|
|
104
|
+
activity (active/suppressed). The observed BOLD is a combination of all active states.
|
|
105
|
+
|
|
106
|
+
**When to use:**
|
|
107
|
+
- When you believe brain dynamics are driven by multiple independent processes
|
|
108
|
+
- Multitask paradigms where subjects do several things simultaneously
|
|
109
|
+
- When a standard HMM requires too many states to capture combinatorial structure
|
|
110
|
+
(e.g., 2 binary processes = 4 combined states, but factorial HMM uses 2+2=4 parameters
|
|
111
|
+
instead of 4×4=16 for a standard 4-state HMM transition matrix)
|
|
112
|
+
|
|
113
|
+
**When it breaks down:**
|
|
114
|
+
- When state chains are not actually independent (common in fMRI — arousal and task
|
|
115
|
+
engagement are often correlated)
|
|
116
|
+
- Exact inference is intractable — requires variational approximations
|
|
117
|
+
- Less commonly used in fMRI literature; fewer validated pipelines
|
|
118
|
+
|
|
119
|
+
**Python:** Custom implementation needed. Can be built on `ssm` or using variational
|
|
120
|
+
inference frameworks (e.g., `pyro`, `numpyro`).
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## 4. Input-Output HMM {#io-hmm}
|
|
125
|
+
|
|
126
|
+
**Generative model:**
|
|
127
|
+
- Transition depends on external input: P(z_t | z_{t-1}, u_t) ∝ A[z_{t-1}, z_t] × exp(v_k^T u_t)
|
|
128
|
+
- Emission can also depend on input: y_t | z_t=k, u_t ~ N(μ_k + B_k u_t, Σ_k)
|
|
129
|
+
|
|
130
|
+
**What it captures in fMRI:**
|
|
131
|
+
How external events (task onsets, stimuli) drive brain state transitions. A task cue might
|
|
132
|
+
increase the probability of transitioning to a "task-engaged" state. Stimulus features
|
|
133
|
+
(reward magnitude in MID, conflict level in SST) can modulate both transitions and emissions.
|
|
134
|
+
|
|
135
|
+
**When to use:**
|
|
136
|
+
- Task-based paradigms where you want to model how task events trigger state changes
|
|
137
|
+
- Naturalistic paradigms where stimulus features (audio energy, visual complexity, semantic
|
|
138
|
+
content) drive brain state dynamics
|
|
139
|
+
- When you want to dissociate stimulus-driven from endogenous state transitions
|
|
140
|
+
|
|
141
|
+
**When it breaks down:**
|
|
142
|
+
- Resting state (no external inputs to condition on)
|
|
143
|
+
- When the input-state relationship is highly nonlinear (consider rSLDS instead)
|
|
144
|
+
- Defining the right input features for naturalistic stimuli is challenging
|
|
145
|
+
|
|
146
|
+
**Key practical considerations for fMRI:**
|
|
147
|
+
- Task regressors should be convolved with HRF before entering as inputs, because the
|
|
148
|
+
BOLD response to a task event is delayed. Alternatively, shift task events by ~5s.
|
|
149
|
+
- For naturalistic paradigms, extract stimulus features at the TR resolution (e.g., using
|
|
150
|
+
movie annotation tools, optical flow, audio envelopes).
|
|
151
|
+
- The `ssm` library supports input-driven HMMs and SLDS natively.
|
|
152
|
+
|
|
153
|
+
**Python:** `ssm.HMM` with `InputDrivenObservations` or `InputDrivenTransitions`
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## 5. Sticky HMM and HDP-HMM {#sticky-hmm}
|
|
158
|
+
|
|
159
|
+
**Sticky HMM:**
|
|
160
|
+
- Standard HMM but the transition matrix has an added self-transition bias:
|
|
161
|
+
A[i,j] ∝ α_j + κ × δ(i,j), where κ > 0 encourages staying in the current state
|
|
162
|
+
|
|
163
|
+
**HDP-HMM (Hierarchical Dirichlet Process HMM):**
|
|
164
|
+
- Bayesian nonparametric extension: K is inferred from data, not fixed
|
|
165
|
+
- Uses a hierarchical Dirichlet process prior over the transition matrix
|
|
166
|
+
- Sticky variant (sticky HDP-HMM) adds the self-transition bias
|
|
167
|
+
|
|
168
|
+
**What it captures in fMRI:**
|
|
169
|
+
Same as Gaussian HMM, but with better temporal properties. The sticky prior prevents
|
|
170
|
+
the unrealistic rapid switching that standard HMMs sometimes exhibit with fMRI data
|
|
171
|
+
(where the model alternates states every 1-2 TRs due to noise, not real neural dynamics).
|
|
172
|
+
|
|
173
|
+
**When to use:**
|
|
174
|
+
- Whenever you'd use a Gaussian HMM but want more realistic state durations
|
|
175
|
+
- When you're uncertain about K — HDP-HMM can infer it
|
|
176
|
+
- Resting-state analyses where state persistence matters for interpretation
|
|
177
|
+
|
|
178
|
+
**Key practical considerations:**
|
|
179
|
+
- The stickiness parameter κ effectively sets a minimum expected dwell time. Tune it
|
|
180
|
+
based on what's physiologically plausible (e.g., states should last at least 3-5 TRs).
|
|
181
|
+
- HDP-HMM is computationally more expensive (MCMC sampling). For large datasets,
|
|
182
|
+
truncated variational inference is faster.
|
|
183
|
+
- In practice, many groups use standard HMM with post-hoc temporal filtering of the
|
|
184
|
+
state sequence (requiring minimum dwell time) as a simpler alternative to sticky HMMs.
|
|
185
|
+
|
|
186
|
+
**Python:** `pyhsmm` (Fox et al.), `ssm` (sticky HMM variant)
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## 6. HSMM — Hidden Semi-Markov Model {#hsmm}
|
|
191
|
+
|
|
192
|
+
**Generative model:**
|
|
193
|
+
- Same discrete hidden states as HMM, but the dwell time has an explicit duration distribution
|
|
194
|
+
D_k(d) instead of the implicit geometric distribution of standard HMMs
|
|
195
|
+
- Transition probability: P(z_t | z_{t-1}) only fires at the *end* of a dwell period, which
|
|
196
|
+
is drawn from D_k ~ Poisson(λ_k) or Negative-Binomial or any discrete distribution
|
|
197
|
+
- Emission: y_t | z_t = k ~ N(μ_k, Σ_k) (same Gaussian emission as HMM)
|
|
198
|
+
|
|
199
|
+
**Key difference from HMM:** Standard HMMs have geometric dwell times (probability of leaving
|
|
200
|
+
a state is constant at each TR, giving exponentially distributed durations). HSMMs explicitly
|
|
201
|
+
model the duration, allowing sub-geometric or super-geometric dwell distributions.
|
|
202
|
+
|
|
203
|
+
**What it captures in fMRI:**
|
|
204
|
+
State duration patterns that are non-geometric — e.g., if cognitive states reliably last
|
|
205
|
+
15-30 seconds, a HSMM can capture this preference, while an HMM can only approximate it
|
|
206
|
+
via a high self-transition probability (which is a geometric approximation).
|
|
207
|
+
|
|
208
|
+
**When to use:**
|
|
209
|
+
- Task block designs where blocks have a known duration (e.g., 20s, 30s) — HSMM can encode
|
|
210
|
+
duration priors matching the design, which regularizes state estimation
|
|
211
|
+
- Resting-state analyses where you have strong prior beliefs about state duration ranges
|
|
212
|
+
(e.g., from prior literature: DMN states last ~10-30s)
|
|
213
|
+
- When standard HMM produces dwell-time distributions with poor fit to a geometric assumption
|
|
214
|
+
(check: plot empirical dwell times and compare to fitted geometric — if they diverge, HSMM)
|
|
215
|
+
- When you want to separate "transition probability" from "dwell time distribution" as
|
|
216
|
+
independent parameters
|
|
217
|
+
|
|
218
|
+
**When it breaks down:**
|
|
219
|
+
- When dwell times are genuinely geometric (HSMM adds complexity without benefit)
|
|
220
|
+
- Short datasets: duration distribution estimation needs more observations per state
|
|
221
|
+
- `pyhsmm` is less maintained than `hmmlearn` / `ssm`; expect API quirks
|
|
222
|
+
|
|
223
|
+
**Key practical considerations:**
|
|
224
|
+
- Start with HMM and plot empirical dwell time distributions. If they look geometric,
|
|
225
|
+
stick with HMM. If they are peaked (mode at some finite duration), HSMM is appropriate.
|
|
226
|
+
- Poisson duration distribution is a good default: one extra parameter λ_k per state.
|
|
227
|
+
- The `ssm` library supports HSMMs natively with `ssm.HSMM`.
|
|
228
|
+
|
|
229
|
+
**Python:** `pyhsmm.models.HMM` (Bayesian, MCMC), `ssm.HSMM` (EM, preferred)
|
|
230
|
+
|
|
231
|
+
```python
|
|
232
|
+
import ssm
|
|
233
|
+
import numpy as np
|
|
234
|
+
|
|
235
|
+
def fit_hsmm(data_list, K, D, max_duration=50, n_restarts=10, n_iters=100):
|
|
236
|
+
"""Fit Hidden Semi-Markov Model using ssm library.
|
|
237
|
+
|
|
238
|
+
Parameters
|
|
239
|
+
----------
|
|
240
|
+
data_list : list of arrays, each (T, D)
|
|
241
|
+
K : int
|
|
242
|
+
Number of states
|
|
243
|
+
D : int
|
|
244
|
+
Observation dimension
|
|
245
|
+
max_duration : int
|
|
246
|
+
Maximum dwell time in TRs to model explicitly. Set to roughly 3-4× your
|
|
247
|
+
expected maximum state duration. Longer max_duration = more computation.
|
|
248
|
+
|
|
249
|
+
Returns
|
|
250
|
+
-------
|
|
251
|
+
best_model : ssm.HSMM
|
|
252
|
+
"""
|
|
253
|
+
best_model = None
|
|
254
|
+
best_ll = -np.inf
|
|
255
|
+
|
|
256
|
+
for restart in range(n_restarts):
|
|
257
|
+
model = ssm.HSMM(
|
|
258
|
+
K=K,
|
|
259
|
+
D=D,
|
|
260
|
+
observations='gaussian',
|
|
261
|
+
transitions='standard',
|
|
262
|
+
transition_kwargs={'max_duration': max_duration},
|
|
263
|
+
)
|
|
264
|
+
lls = model.fit(data_list, method='em', num_iters=n_iters, tolerance=1e-4)
|
|
265
|
+
if lls[-1] > best_ll:
|
|
266
|
+
best_ll = lls[-1]
|
|
267
|
+
best_model = model
|
|
268
|
+
best_lls = lls
|
|
269
|
+
|
|
270
|
+
# Inspect inferred duration distributions
|
|
271
|
+
print(f"Best log-likelihood: {best_ll:.2f}")
|
|
272
|
+
for k in range(K):
|
|
273
|
+
# ssm stores duration distribution parameters; access depends on version
|
|
274
|
+
print(f"State {k}: expected dwell = {model.transitions.expected_durations[k]:.1f} TRs")
|
|
275
|
+
|
|
276
|
+
return best_model, best_lls
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
---
|
|
280
|
+
|
|
281
|
+
## 7. SLDS — Switching Linear Dynamical System {#slds}
|
|
282
|
+
|
|
283
|
+
**Generative model:**
|
|
284
|
+
- Discrete switching state: z_t ∈ {1, ..., K}
|
|
285
|
+
- Continuous latent state: x_t ∈ R^d
|
|
286
|
+
- Switching dynamics: x_t | z_t=k, x_{t-1} ~ N(A_k x_{t-1} + b_k, Q_k)
|
|
287
|
+
- Emission: y_t | x_t ~ N(C x_t + d, R)
|
|
288
|
+
- Transition: P(z_t | z_{t-1}) = Π[z_{t-1}, z_t]
|
|
289
|
+
|
|
290
|
+
**Parameters:** Π, {A_k, b_k, Q_k} for k=1..K, C, d, R
|
|
291
|
+
|
|
292
|
+
**What it captures in fMRI:**
|
|
293
|
+
Brain dynamics evolve in a continuous latent space (not directly observed), and this evolution
|
|
294
|
+
switches between different linear dynamical regimes. Unlike HMM where each time point is
|
|
295
|
+
independently drawn from a state-specific distribution, SLDS captures smooth temporal
|
|
296
|
+
evolution that shifts between regimes. The observed BOLD signal is a linear readout of the
|
|
297
|
+
latent state, plus noise.
|
|
298
|
+
|
|
299
|
+
**When to use:**
|
|
300
|
+
- When you believe brain dynamics are fundamentally continuous but regime-switching
|
|
301
|
+
- When temporal smoothness of the latent trajectory is important
|
|
302
|
+
- When the observation dimension (n_regions) is much larger than the latent dimension (d)
|
|
303
|
+
— SLDS provides dimensionality reduction and dynamics simultaneously
|
|
304
|
+
- Task paradigms where you expect smooth transitions between cognitive states
|
|
305
|
+
|
|
306
|
+
**When it breaks down:**
|
|
307
|
+
- Within-regime dynamics are truly nonlinear (use rSLDS or SNLDS)
|
|
308
|
+
- K is very large — each regime has A_k (d×d), b_k (d), Q_k (d×d) parameters
|
|
309
|
+
- Exact inference is intractable; relies on approximations (Laplace-EM, variational, SMC)
|
|
310
|
+
|
|
311
|
+
**Key practical considerations for fMRI:**
|
|
312
|
+
- Latent dimension d: typically 5-20 for parcellated data. Cross-validate.
|
|
313
|
+
- The emission matrix C maps from latent space to brain regions — its columns are
|
|
314
|
+
interpretable as spatial modes.
|
|
315
|
+
- SLDS can be viewed as a generalization of both HMM (d=0, no continuous latent) and
|
|
316
|
+
linear dynamical system (K=1, single regime).
|
|
317
|
+
- For fMRI, the smooth latent trajectory in SLDS may partially absorb HRF smoothing,
|
|
318
|
+
making it somewhat more robust to HRF effects than HMM.
|
|
319
|
+
|
|
320
|
+
**Python:** `ssm.SLDS` (Linderman lab — primary recommendation)
|
|
321
|
+
|
|
322
|
+
---
|
|
323
|
+
|
|
324
|
+
## 7. rSLDS — Recurrent Switching Linear Dynamical System {#rslds}
|
|
325
|
+
|
|
326
|
+
**Generative model:**
|
|
327
|
+
- Same as SLDS, but the discrete state depends on the continuous latent:
|
|
328
|
+
P(z_t | z_{t-1}, x_{t-1}) ∝ Π[z_{t-1}, z_t] × exp(r_k^T x_{t-1})
|
|
329
|
+
- The continuous state "recurrently" influences the discrete switching
|
|
330
|
+
|
|
331
|
+
**What it captures in fMRI:**
|
|
332
|
+
The regime switches are driven by the latent brain state itself — when the brain's latent
|
|
333
|
+
trajectory crosses a boundary in state space, it switches to a different dynamical regime.
|
|
334
|
+
This creates piecewise-linear dynamics with state-dependent switching boundaries.
|
|
335
|
+
|
|
336
|
+
**When to use:**
|
|
337
|
+
- When state transitions are not random but depend on the current brain state
|
|
338
|
+
- When you want to discover the "boundaries" in neural state space where dynamics change
|
|
339
|
+
- Naturalistic paradigms where transitions are driven by internal state accumulation
|
|
340
|
+
(e.g., gradually increasing engagement until a threshold triggers mind-wandering)
|
|
341
|
+
- More principled model of nonlinear dynamics than plain SLDS
|
|
342
|
+
|
|
343
|
+
**When it breaks down:**
|
|
344
|
+
- Very short data — rSLDS has more parameters than SLDS (the recurrence weights r_k)
|
|
345
|
+
- When transitions are truly externally driven, not state-dependent (use input-driven SLDS)
|
|
346
|
+
- Inference is harder than SLDS; more sensitive to initialization
|
|
347
|
+
|
|
348
|
+
**Key practical considerations for fMRI:**
|
|
349
|
+
- The recurrence boundaries partition the latent space into regions where different dynamics
|
|
350
|
+
apply — these boundaries are scientifically interpretable
|
|
351
|
+
- Start with SLDS first. If SLDS fits poorly or you have theoretical reasons to expect
|
|
352
|
+
state-dependent switching, upgrade to rSLDS.
|
|
353
|
+
- The `ssm` library provides good implementations with Laplace-EM inference.
|
|
354
|
+
|
|
355
|
+
**Python:** `ssm.SLDS` with `recurrent=True`
|
|
356
|
+
|
|
357
|
+
---
|
|
358
|
+
|
|
359
|
+
## 8. SNLDS — Switching Nonlinear Dynamical System {#snlds}
|
|
360
|
+
|
|
361
|
+
**Generative model:**
|
|
362
|
+
- Same structure as SLDS but dynamics are nonlinear:
|
|
363
|
+
x_t | z_t=k, x_{t-1} ~ N(f_k(x_{t-1}), Q_k)
|
|
364
|
+
- f_k can be a neural network, Gaussian process, or other nonlinear function
|
|
365
|
+
|
|
366
|
+
**What it captures in fMRI:**
|
|
367
|
+
The most expressive model in this catalog. Each regime has its own nonlinear dynamics.
|
|
368
|
+
Useful when linear dynamics are insufficient to capture the complexity of brain state evolution.
|
|
369
|
+
|
|
370
|
+
**When to use:**
|
|
371
|
+
- Research settings with large datasets where linear dynamics are demonstrably insufficient
|
|
372
|
+
- Deep data (many time points per subject) that can support nonlinear function estimation
|
|
373
|
+
- When other models show systematic residual structure suggesting nonlinearity
|
|
374
|
+
|
|
375
|
+
**When it breaks down:**
|
|
376
|
+
- Almost always overkill for standard fMRI datasets
|
|
377
|
+
- Very data-hungry — nonlinear dynamics functions need much more data to estimate
|
|
378
|
+
- Interpretability is reduced (what does a neural network dynamics function mean neurally?)
|
|
379
|
+
- Risk of overfitting is high
|
|
380
|
+
|
|
381
|
+
**Key practical considerations:**
|
|
382
|
+
- Use only after demonstrating that SLDS/rSLDS are insufficient
|
|
383
|
+
- Regularization is critical — use low-rank dynamics or simple nonlinearities (RBF)
|
|
384
|
+
- Consider deep learning approaches like LFADS (Latent Factor Analysis via Dynamical Systems)
|
|
385
|
+
which use neural network dynamics but with structured priors
|
|
386
|
+
|
|
387
|
+
**Python:** Custom implementation with `ssm` or deep learning frameworks (PyTorch/JAX).
|
|
388
|
+
LFADS implementations exist in `lfads-torch` and `autolfads-tf2`.
|
|
389
|
+
|
|
390
|
+
---
|
|
391
|
+
|
|
392
|
+
## 9. Hierarchical Extensions {#hierarchical}
|
|
393
|
+
|
|
394
|
+
### Hierarchical HMM (HHMM)
|
|
395
|
+
- Two (or more) levels of hidden states: slow states (superstate) and fast states (substate)
|
|
396
|
+
- Superstate governs which set of substates is active
|
|
397
|
+
- Superstate transitions happen on a slower timescale
|
|
398
|
+
|
|
399
|
+
**Use in fMRI:** Naturalistic paradigms where dynamics operate on multiple timescales.
|
|
400
|
+
For movie watching: superstates might correspond to narrative segments (minutes), substates
|
|
401
|
+
to within-segment dynamics (seconds). For resting state: superstates might capture slow
|
|
402
|
+
fluctuations in arousal, substates capture faster network dynamics.
|
|
403
|
+
|
|
404
|
+
### Hierarchical Group Models
|
|
405
|
+
- Subject-level models share a group prior
|
|
406
|
+
- Subject-specific parameters are drawn from group distributions
|
|
407
|
+
- Enables population-level inference while respecting individual differences
|
|
408
|
+
|
|
409
|
+
**Use in fMRI:** The standard approach for group-level SSM analysis when you have
|
|
410
|
+
enough subjects. Particularly important for clinical comparisons (patient vs. control).
|
|
411
|
+
See `references/group_inference.md` for implementation details.
|
|
412
|
+
|
|
413
|
+
---
|
|
414
|
+
|
|
415
|
+
## 11. Model Comparison Summary {#comparison}
|
|
416
|
+
|
|
417
|
+
| Model | Latent type | Dynamics | Parameters (approx.) | Data needs | Compute | fMRI use cases |
|
|
418
|
+
|-------|------------|----------|---------------------|------------|---------|----------------|
|
|
419
|
+
| Gaussian HMM | Discrete | Markov chain | K²+K×p(p+1)/2 | Low-moderate | Fast (CPU) | Resting FC states, task states |
|
|
420
|
+
| HMM-MAR | Discrete | Markov + AR emissions | K²+K×L×p² | Moderate-high | Moderate (CPU) | Directed connectivity dynamics |
|
|
421
|
+
| Factorial HMM | Multiple discrete | Independent chains | M×K²+combinatorial | Moderate | Moderate (variational, CPU) | Independent neural processes |
|
|
422
|
+
| IO-HMM | Discrete | Input-driven | K²+K×q+K×p² | Moderate | Fast–moderate (CPU) | Task-evoked state dynamics |
|
|
423
|
+
| Sticky/HDP-HMM | Discrete (nonpar.) | Persistent Markov | Bayesian (inferred) | Low-moderate | Slow (MCMC); fast (var. EM) | When K is unknown, realistic dwell times |
|
|
424
|
+
| HSMM | Discrete | Semi-Markov | K²+K×p(p+1)/2+K | Moderate | Moderate (CPU) | Task blocks, explicit duration priors |
|
|
425
|
+
| SLDS | Discrete + continuous | Switching linear | K×d²+d×p | Moderate-high | Moderate; GPU 2–5× speedup | Regime-switching continuous dynamics |
|
|
426
|
+
| rSLDS | Discrete + continuous | Recurrent switching | K×d²+K×d+d×p | High | Heavy; GPU 5–10× speedup | State-dependent regime switching |
|
|
427
|
+
| SNLDS | Discrete + continuous | Switching nonlinear | K×f_params+d×p | Very high | Very heavy; GPU required | Nonlinear brain dynamics (rare in fMRI) |
|
|
428
|
+
|
|
429
|
+
Where p = observation dimension, d = latent dimension, K = number of states, L = AR order,
|
|
430
|
+
q = input dimension, M = number of factorial chains.
|
|
431
|
+
|
|
432
|
+
**Compute guidance:**
|
|
433
|
+
- **CPU is fine** for hmmlearn-based models on datasets ≤ 50 subjects × 500 TRs
|
|
434
|
+
- **GPU recommended** for rSLDS/SNLDS, osl-dynamics DyNeMo, and model-selection sweeps over K
|
|
435
|
+
- **dynamax** provides JAX JIT compilation for all models — significant speedup even on CPU; GPU is drop-in
|
|
436
|
+
- See `code_templates.md §12` for JAX/GPU setup, `§13` for dynamax modular ("Lego") model building
|