Quick Start¶
Low-Level PyTorch API¶
AMICA operates directly on PyTorch tensors.
Input shape is (T, n_channels): samples x channels.
import torch
from pyamica import AMICA
# Synthetic data: 8 channels, 5000 samples
X = torch.randn(5000, 8, dtype=torch.float64)
model = AMICA(
n_models=3, # number of mixture models (M)
max_iter=200,
device="cpu", # or "cuda" / "mps"
)
model.fit(X)
# Log-likelihood curve
ll = model.ll_history() # (n_iter,)
# Posterior probabilities: which model is dominant at each sample
post = model.posteriors_ # (n_models, T)
# Source activations for each model
sources = model.transform(X) # (T, n_models, n_components)
MNE-Python Wrapper¶
AmicaICA wraps AMICA with an MNE-compatible
interface. It accepts mne.io.Raw and mne.Epochs objects.
import mne
from pyamica import AmicaICA
raw = mne.io.read_raw_fif("recording.fif", preload=True)
raw.filter(1, 40)
ica = AmicaICA(
n_models=3,
n_components=30,
device="cuda",
)
ica.fit(raw, picks="eeg")
Visualising Model Dominance¶
# Stacked area chart: which model dominates each moment
ica.plot_model_dominance(smooth_s=1.0)
# Line plot of raw posteriors
ica.plot_model_posteriors()
Inspecting and Removing Artefacts¶
# Open the MNE component browser for model 0
ica.review(raw, model_idx=0, eog_ch=["HEOG", "VEOG"], ecg_ch="ECG")
# Automatic EOG detection
eog_bads, scores = ica.find_bads_eog(raw, model_idx=0)
ica.get_mne_ica(0).exclude = eog_bads
# Remove artefacts and reconstruct (uses the dominant model per sample)
ica.apply(raw)
Saving and Loading¶
ica.save("my_ica") # writes my_ica.amica.npz
from pyamica import AmicaICA
ica2 = AmicaICA.load("my_ica.amica.npz")
Multi-Model vs Single-Model¶
With n_models=1, pyamica behaves like standard ICA (equivalent to
Infomax / extended Infomax). Increasing n_models adds mixture
models that compete to explain each time point.
# Standard ICA (M=1)
model = AMICA(n_models=1, max_iter=100)
# Mixture of three models (M=3)
model = AMICA(n_models=3, max_iter=200)