| Title: | Leakage-Aware Machine Learning for Physiological Time Series |
|---|---|
| Description: | Provides leakage-aware, reproducible feature transforms and reference deep-learning workflows for physiological time series stored in PhysioExperiment objects. Canonical catch22 characteristics are computed through the official R backend, while ROCKET and MiniRocket transforms use guarded optional Python backends. Guarded optional torch and luz backends provide case-aware datasets, compact neural architectures, training, and prediction. Explicit contracts preserve case, channel, feature, normalization, backend, and model provenance without claiming clinical validation. Named transfer-learning policies, leakage-safe CORAL alignment, and immutable hash-verified foundation-model caches provide bounded reuse across domains. |
| Authors: | Yusuke Matsui [aut, cre] |
| Maintainer: | Yusuke Matsui <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.4.2 |
| Built: | 2026-10-03 13:41:58 UTC |
| Source: | https://github.com/x-biosignal/PhysioML |
A first network download requires explicit consent, a fixed 40-character revision, a predeclared canonical manifest hash, and license acceptance. Cache hits revalidate the complete inventory and perform no download.
cacheFoundationModel( model = c("moment", "chronos2", "labram", "bendr"), model_id = NULL, revision, manifest_sha256, cache_dir = tools::R_user_dir("PhysioML", "cache"), allow_download = FALSE, offline = FALSE, license_accepted = FALSE, overwrite = FALSE )cacheFoundationModel( model = c("moment", "chronos2", "labram", "bendr"), model_id = NULL, revision, manifest_sha256, cache_dir = tools::R_user_dir("PhysioML", "cache"), allow_download = FALSE, offline = FALSE, license_accepted = FALSE, overwrite = FALSE )
model |
Exact adapter name. |
model_id |
Optional exact upstream model identifier. |
revision |
Immutable 40-character commit hash. |
manifest_sha256 |
Expected canonical manifest SHA-256. |
cache_dir |
Caller-owned cache root. |
allow_download |
Explicit first-download consent. |
offline |
Whether all network access is forbidden. |
license_accepted |
Whether the upstream license was accepted. |
overwrite |
Whether an existing valid entry may be replaced. |
Invisibly, path-free cache provenance.
# A first download needs explicit consent, the exact pinned revision, and the # expected canonical manifest hash; it also needs a caller-managed Python env. cacheFoundationModel( model = "moment", revision = "411e288267f82cce86296dbe4d6c8bc533cc162f", manifest_sha256 = strrep("0", 64), # replace with the real manifest hash cache_dir = tempfile("physioml-cache"), allow_download = TRUE, license_accepted = TRUE )# A first download needs explicit consent, the exact pinned revision, and the # expected canonical manifest hash; it also needs a caller-managed Python env. cacheFoundationModel( model = "moment", revision = "411e288267f82cce86296dbe4d6c8bc533cc162f", manifest_sha256 = strrep("0", 64), # replace with the real manifest hash cache_dir = tempfile("physioml-cache"), allow_download = TRUE, license_accepted = TRUE )
Calls the official C-backed Rcatch22::catch22_all() implementation for
every selected case-channel series. Input samples are passed unchanged.
catch22(x, assay_name = NULL, channels = NULL, cases = NULL, catch24 = FALSE)catch22(x, assay_name = NULL, channels = NULL, cases = NULL, catch24 = FALSE)
x |
A |
assay_name |
|
channels |
|
cases |
|
catch24 |
One non-missing logical. When |
A 2-D assay is interpreted as time x channel for one case. A 3-D assay is interpreted as time x channel x case. Series must be finite, equal length within an assay, and contain at least 10 samples. PhysioML does not impute, resample, normalize, detrend, or collapse channels before calling Rcatch22.
An S4Vectors::DataFrame() with one row per case-channel pair,
identity columns followed by 22 or 24 numeric feature columns. Stable
transform provenance and typed diagnostics are stored as attributes.
Lubba CH, Sethi SS, Knaute P, Schultz SR, Fulcher BD, Jones NS (2019). catch22: CAnonical Time-series CHaracteristics. Data Mining and Knowledge Discovery, 33, 1821-1852. doi:10.1007/s10618-019-00647-x
Henderson T (2026). Rcatch22: Calculation of 22 Canonical Time-Series Characteristics. R package.
if (requireNamespace("Rcatch22", quietly = TRUE)) { values <- matrix(sin(seq(0, 8 * pi, length.out = 100)), 100, 1) pe <- PhysioExperiment::PhysioExperiment( assays = list(raw = values), colData = S4Vectors::DataFrame(label = "signal"), samplingRate = 100 ) catch22(pe) }if (requireNamespace("Rcatch22", quietly = TRUE)) { values <- matrix(sin(seq(0, 8 * pi, length.out = 100)), 100, 1) pe <- PhysioExperiment::PhysioExperiment( assays = list(raw = values), colData = S4Vectors::DataFrame(label = "signal"), samplingRate = 100 ) catch22(pe) }
Fit CORAL only with training-source observations and an explicitly designated unlabeled target adaptation set. Held-out target validation and test observations must not be supplied. CORAL matches first- and second-order statistics; it does not establish causal, class-conditional, fairness, or clinical invariance.
domainAdapt( source, target, method = c("coral"), regularization = 1e-06, return_model = TRUE )domainAdapt( source, target, method = c("coral"), regularization = 1e-06, return_model = TRUE )
source, target
|
Finite observation-by-feature matrices, or foundation embedding results, with identical exact feature names and order. |
method |
Currently exactly |
regularization |
Positive covariance regularization. |
return_model |
Whether to return the fitted transform and diagnostics. |
A matrix, or a plain list containing aligned source data and model.
set.seed(1) feat <- c("f1", "f2", "f3") source <- matrix(stats::rnorm(30), ncol = 3, dimnames = list(NULL, feat)) target <- matrix(stats::rnorm(30, mean = 1), ncol = 3, dimnames = list(NULL, feat)) fit <- domainAdapt(source, target) fit$diagnostics$source_mean_residualset.seed(1) feat <- c("f1", "f2", "f3") source <- matrix(stats::rnorm(30), ncol = 3, dimnames = list(NULL, feat)) target <- matrix(stats::rnorm(30, mean = 1), ncol = 3, dimnames = list(NULL, feat)) fit <- domainAdapt(source, target) fit$diagnostics$source_mean_residual
Uses the governed R torch to TorchScript to Python PyTorch bridge. Only the batch axis may be dynamic. The graph and canonical model card are validated before they are atomically landed.
exportONNX( model, path, opset = 17L, dynamic_batch = TRUE, validate = TRUE, metadata_path = paste0(path, ".json"), overwrite = FALSE )exportONNX( model, path, opset = 17L, dynamic_batch = TRUE, validate = TRUE, metadata_path = paste0(path, ".json"), overwrite = FALSE )
model |
A fitted |
path |
Destination |
opset |
Positive ONNX opset; the initial default is 17. |
dynamic_batch |
Whether the batch axis is dynamic. |
validate |
Whether to enforce the full ONNX checker, graph/card consistency, and logit parity tolerance. Basic graph parsing, I/O contract checks, and CPU inference are always required. |
metadata_path |
Destination canonical JSON model-card path. |
overwrite |
Whether an existing graph/card pair may be replaced. |
Invisibly, a plain physio_onnx_export list.
arr <- array(stats::rnorm(50 * 2 * 6), dim = c(50, 2, 6)) pe <- PhysioExperiment::PhysioExperiment( assays = list(raw = arr), colData = S4Vectors::DataFrame(label = c("C3", "C4")), samplingRate = 100 ) path <- tempfile(fileext = ".onnx") # Export needs torch plus the governed torch->ONNX Python bridge. train <- peDataset( pe, targets = rep(c("a", "b"), 3), task = "classification", class_levels = c("a", "b") ) fit <- trainModel(train, model = "cnn1d", epochs = 1L) exportONNX(fit, path)arr <- array(stats::rnorm(50 * 2 * 6), dim = c(50, 2, 6)) pe <- PhysioExperiment::PhysioExperiment( assays = list(raw = arr), colData = S4Vectors::DataFrame(label = c("C3", "C4")), samplingRate = 100 ) path <- tempfile(fileext = ".onnx") # Export needs torch plus the governed torch->ONNX Python bridge. train <- peDataset( pe, targets = rep(c("a", "b"), 3), task = "classification", class_levels = c("a", "b") ) fit <- trainModel(train, model = "cnn1d", epochs = 1L) exportONNX(fit, path)
Training is CPU-only and passes only explicitly trainable parameters to Adam. Frozen modules, including their batch-normalization buffers, remain in evaluation mode. Validation and prediction data must reuse frozen normalization statistics.
fineTune( model, train, valid = NULL, strategy = c("linear_probe", "partial", "full"), unfreeze = NULL, epochs = 10L, batch_size = 32L, learning_rate = 1e-04, weight_decay = 0, callbacks = NULL, seed = 1L, device = "cpu", num_workers = 0L, verbose = FALSE )fineTune( model, train, valid = NULL, strategy = c("linear_probe", "partial", "full"), unfreeze = NULL, epochs = 10L, batch_size = 32L, learning_rate = 1e-04, weight_decay = 0, callbacks = NULL, seed = 1L, device = "cpu", num_workers = 0L, verbose = FALSE )
model |
A fitted |
train, valid
|
Compatible targeted datasets. |
strategy |
Exact tuning strategy. |
unfreeze |
Component prefixes used only by partial tuning. |
epochs, batch_size
|
Positive whole-number settings. |
learning_rate |
Positive Adam learning rate. |
weight_decay |
Non-negative Adam weight decay. |
callbacks |
Currently |
seed |
Whole-number CPU seed. |
device |
Currently exactly |
num_workers |
Currently exactly zero. |
verbose |
Whether to print one line per epoch. |
A fitted physio_dl_model with a plain transfer record.
arr <- array(stats::rnorm(50 * 2 * 6), dim = c(50, 2, 6)) pe <- PhysioExperiment::PhysioExperiment( assays = list(raw = arr), colData = S4Vectors::DataFrame(label = c("C3", "C4")), samplingRate = 100 ) # Needs the optional torch and luz backends. if (requireNamespace("torch", quietly = TRUE) && requireNamespace("luz", quietly = TRUE)) { train <- peDataset( pe, targets = rep(c("a", "b"), 3), task = "classification", class_levels = c("a", "b") ) fit <- trainModel(train, model = "cnn1d", epochs = 1L) tuned <- fineTune(fit, train, strategy = "linear_probe", epochs = 1L) }arr <- array(stats::rnorm(50 * 2 * 6), dim = c(50, 2, 6)) pe <- PhysioExperiment::PhysioExperiment( assays = list(raw = arr), colData = S4Vectors::DataFrame(label = c("C3", "C4")), samplingRate = 100 ) # Needs the optional torch and luz backends. if (requireNamespace("torch", quietly = TRUE) && requireNamespace("luz", quietly = TRUE)) { train <- peDataset( pe, targets = rep(c("a", "b"), 3), task = "classification", class_levels = c("a", "b") ) fit <- trainModel(train, model = "cnn1d", epochs = 1L) tuned <- fineTune(fit, train, strategy = "linear_probe", epochs = 1L) }
Inspect immutable foundation-model cache entries
foundationCacheInfo( model = NULL, cache_dir = tools::R_user_dir("PhysioML", "cache"), verify = TRUE )foundationCacheInfo( model = NULL, cache_dir = tools::R_user_dir("PhysioML", "cache"), verify = TRUE )
model |
Optional exact adapter filter. |
cache_dir |
Caller-owned cache root. |
verify |
Whether to revalidate every manifest and asset. |
A path-free data frame, one row per READY entry.
# An empty cache root returns a zero-row inventory, offline. foundationCacheInfo(cache_dir = tempfile("physioml-cache"))# An empty cache root returns a zero-row inventory, offline. foundationCacheInfo(cache_dir = tempfile("physioml-cache"))
The exact model ID, immutable revision, complete manifest hash, ordered channels, sampling rate, units, and window contract are recorded. Python and all provider packages remain caller-managed. A first upstream download is explicit; package code never installs software or selects an environment.
foundationEmbed( x, model = c("moment", "chronos2", "labram", "bendr"), model_id = NULL, revision, manifest_sha256, assay_name = NULL, cases = NULL, channels = NULL, window_samples = NULL, stride_samples = NULL, reduction = c("mean", "none"), batch_size = 16L, device = "cpu", cache_dir = tools::R_user_dir("PhysioML", "cache"), allow_download = FALSE, offline = FALSE )foundationEmbed( x, model = c("moment", "chronos2", "labram", "bendr"), model_id = NULL, revision, manifest_sha256, assay_name = NULL, cases = NULL, channels = NULL, window_samples = NULL, stride_samples = NULL, reduction = c("mean", "none"), batch_size = 16L, device = "cpu", cache_dir = tools::R_user_dir("PhysioML", "cache"), allow_download = FALSE, offline = FALSE )
x |
A |
model |
Exact adapter name. |
model_id |
Optional exact upstream model identifier. |
revision |
Immutable 40-character commit hash. |
manifest_sha256 |
Expected canonical cache-manifest SHA-256. |
assay_name, cases, channels
|
Exact input selections. |
window_samples, stride_samples
|
Complete-window settings. |
reduction |
Exact documented embedding reduction. |
batch_size |
Positive whole-number batch size. |
device |
Currently exactly |
cache_dir |
Caller-owned cache root. |
allow_download |
Explicit first-download consent. |
offline |
Whether all network access is forbidden. |
Stable dimensions are promised only for one exact model, revision, and preprocessing contract. The output is not a clinical prediction and does not establish fairness, causal invariance, or domain invariance.
A path-free, serializable physio_foundation_embedding.
arr <- array(stats::rnorm(400 * 2 * 2), dim = c(400, 2, 2)) pe <- PhysioExperiment::PhysioExperiment( assays = list(raw = arr), colData = S4Vectors::DataFrame(label = c("C3", "C4"), unit = "uV"), samplingRate = 200 ) # Needs a pinned revision, the expected manifest hash, a caller-managed # Python env, and (on first use) explicit download consent. emb <- foundationEmbed( pe, model = "moment", revision = "411e288267f82cce86296dbe4d6c8bc533cc162f", manifest_sha256 = strrep("0", 64), # replace with the real manifest hash allow_download = TRUE )arr <- array(stats::rnorm(400 * 2 * 2), dim = c(400, 2, 2)) pe <- PhysioExperiment::PhysioExperiment( assays = list(raw = arr), colData = S4Vectors::DataFrame(label = c("C3", "C4"), unit = "uV"), samplingRate = 200 ) # Needs a pinned revision, the expected manifest hash, a caller-managed # Python env, and (on first use) explicit download consent. emb <- foundationEmbed( pe, model = "moment", revision = "411e288267f82cce86296dbe4d6c8bc533cc162f", manifest_sha256 = strrep("0", 64), # replace with the real manifest hash allow_download = TRUE )
The fitted model is cloned before requires_grad is changed. Exact matching
is the default; prefix matching is component-aware.
freezeLayers( model, trainable = NULL, frozen = NULL, match = c("exact", "prefix"), strict = TRUE )freezeLayers( model, trainable = NULL, frozen = NULL, match = c("exact", "prefix"), strict = TRUE )
model |
A fitted |
trainable, frozen
|
Optional unique exact parameter names or prefixes. |
match |
Exact selection mode. |
strict |
Whether unmatched rules are errors. |
A plain physio_transfer_model.
arr <- array(stats::rnorm(50 * 2 * 6), dim = c(50, 2, 6)) pe <- PhysioExperiment::PhysioExperiment( assays = list(raw = arr), colData = S4Vectors::DataFrame(label = c("C3", "C4")), samplingRate = 100 ) # Needs the optional torch and luz backends. if (requireNamespace("torch", quietly = TRUE) && requireNamespace("luz", quietly = TRUE)) { train <- peDataset( pe, targets = rep(c("a", "b"), 3), task = "classification", class_levels = c("a", "b") ) fit <- trainModel(train, model = "cnn1d", epochs = 1L) frozen <- freezeLayers(fit) frozen$freeze_manifest }arr <- array(stats::rnorm(50 * 2 * 6), dim = c(50, 2, 6)) pe <- PhysioExperiment::PhysioExperiment( assays = list(raw = arr), colData = S4Vectors::DataFrame(label = c("C3", "C4")), samplingRate = 100 ) # Needs the optional torch and luz backends. if (requireNamespace("torch", quietly = TRUE) && requireNamespace("luz", quietly = TRUE)) { train <- peDataset( pe, targets = rep(c("a", "b"), 3), task = "classification", class_levels = c("a", "b") ) fit <- trainModel(train, model = "cnn1d", epochs = 1L) frozen <- freezeLayers(fit) frozen$freeze_manifest }
Validates a graph against its canonical, hash-bound PhysioML model card and returns raw persistent bytes rather than a live Python runtime session.
importONNX( path, metadata_path = paste0(path, ".json"), providers = "CPUExecutionProvider", verify = TRUE )importONNX( path, metadata_path = paste0(path, ".json"), providers = "CPUExecutionProvider", verify = TRUE )
path |
Path to an ONNX graph. |
metadata_path |
Path to its canonical JSON model card. |
providers |
Execution provider; currently CPU only. |
verify |
Whether to run the ONNX checker and graph/card introspection. |
A persistent physio_onnx_model.
# Reads a governed graph plus its canonical JSON model card (ONNX Runtime). path <- tempfile(fileext = ".onnx") # `path` and paste0(path, ".json") are produced by exportONNX(). model <- importONNX(path)# Reads a governed graph plus its canonical JSON model card (ONNX Runtime). path <- tempfile(fileext = ".onnx") # `path` and paste0(path, ".json") are produced by exportONNX(). model <- importONNX(path)
Uses aeon.transformations.collection.convolution_based.MiniRocket.
A fitted model records the realized feature width because aeon rounds the
requested kernel count according to the MiniRocket kernel family.
minirocket( x, model = NULL, assay_name = NULL, channels = NULL, cases = NULL, n_kernels = 10000L, seed = 1L, deterministic = TRUE, backend = "aeon" )minirocket( x, model = NULL, assay_name = NULL, channels = NULL, cases = NULL, n_kernels = 10000L, seed = 1L, deterministic = TRUE, backend = "aeon" )
x |
A |
model |
|
assay_name, channels, cases
|
Input selection; see |
n_kernels |
One finite whole number of kernels. |
seed |
One whole-number backend seed in |
deterministic |
One non-missing logical. |
backend |
Exactly |
A physio_rocket_transform; see rocket().
Dempster A, Schmidt DF, Webb GI (2021). MiniRocket: A Very Fast (Almost) Deterministic Transform for Time Series Classification. doi:10.1145/3447548.3467231
arr <- array(stats::rnorm(60 * 2 * 4), dim = c(60, 2, 4)) pe <- PhysioExperiment::PhysioExperiment( assays = list(raw = arr), colData = S4Vectors::DataFrame(label = c("C3", "C4")), samplingRate = 100 ) # The transform needs a caller-managed Python environment with NumPy and aeon. fit <- minirocket(pe, n_kernels = 84) dim(fit$features)arr <- array(stats::rnorm(60 * 2 * 4), dim = c(60, 2, 4)) pe <- PhysioExperiment::PhysioExperiment( assays = list(raw = arr), colData = S4Vectors::DataFrame(label = c("C3", "C4")), samplingRate = 100 ) # The transform needs a caller-managed Python environment with NumPy and aeon. fit <- minirocket(pe, n_kernels = 84) dim(fit$features)
Materializes a validated raw ONNX payload only for the current call, disables provider fallback, and reuses the shared prediction formatter.
onnxPredict( model, newdata, batch_size = 64L, type = c("class", "probability", "response", "logit"), providers = "CPUExecutionProvider" )onnxPredict( model, newdata, batch_size = 64L, type = c("class", "probability", "response", "logit"), providers = "CPUExecutionProvider" )
model |
A validated |
newdata |
A compatible |
batch_size |
Positive whole-number inference batch size. |
type |
Exact output type. |
providers |
Execution provider; currently CPU only. |
The same identity-preserving output shapes as predictModel().
# `model` is from importONNX(); `newdata` is a matching peDataset() (CPU ORT). onnxPredict(model, newdata, type = "class")# `model` is from importONNX(); `newdata` is a matching peDataset() (CPU ORT). onnxPredict(model, newdata, type = "class")
Converts a PhysioExperiment assay to fixed channel-by-time items. Split
cases before calling this function, fit normalization on training cases
only, and pass normalization_stats to validation and prediction datasets.
Class tensors are zero-based torch_long; input and regression tensors are
torch_float32. A one-item batch always retains its batch dimension.
peDataset( x, targets = NULL, assay_name = NULL, cases = NULL, channels = NULL, window_samples = NULL, stride_samples = NULL, normalization = c("none", "zscore", "robust"), normalization_stats = NULL, task = c("classification", "regression"), class_levels = NULL, dtype = "float32" )peDataset( x, targets = NULL, assay_name = NULL, cases = NULL, channels = NULL, window_samples = NULL, stride_samples = NULL, normalization = c("none", "zscore", "robust"), normalization_stats = NULL, task = c("classification", "regression"), class_levels = NULL, dtype = "float32" )
x |
A |
targets |
Optional one-per-selected-case target vector. |
assay_name, cases, channels
|
Exact assay and identity selections. |
window_samples, stride_samples
|
Optional complete-window dimensions. |
normalization |
Exact normalization method. |
normalization_stats |
Frozen statistics from a training dataset. |
task |
Exact task name. |
class_levels |
Optional ordered classification labels. |
dtype |
Currently exactly |
A physio_torch_dataset.
# Prepare the input offline: a time x channel x case assay with channel labels. arr <- array(stats::rnorm(50 * 2 * 6), dim = c(50, 2, 6)) pe <- PhysioExperiment::PhysioExperiment( assays = list(raw = arr), colData = S4Vectors::DataFrame(label = c("C3", "C4")), samplingRate = 100 ) # Building the Dataset itself needs the optional torch backend. if (requireNamespace("torch", quietly = TRUE)) { ds <- peDataset( pe, targets = rep(c("rest", "task"), 3), task = "classification", class_levels = c("rest", "task") ) }# Prepare the input offline: a time x channel x case assay with channel labels. arr <- array(stats::rnorm(50 * 2 * 6), dim = c(50, 2, 6)) pe <- PhysioExperiment::PhysioExperiment( assays = list(raw = arr), colData = S4Vectors::DataFrame(label = c("C3", "C4")), samplingRate = 100 ) # Building the Dataset itself needs the optional torch backend. if (requireNamespace("torch", quietly = TRUE)) { ds <- peDataset( pe, targets = rep(c("rest", "task"), 3), task = "classification", class_levels = c("rest", "task") ) }
Builds compact EEGNet, CNN1D, causal TCN, or unidirectional/bidirectional LSTM modules. Classification models return logits; regression models return raw values. Input is always batch by channel by time.
peModel( architecture = c("eegnet", "cnn1d", "tcn", "lstm"), n_channels, n_time, n_outputs, task = c("classification", "regression"), sampling_rate = NULL, dropout = 0.5, hidden = 32L, seed = 1L, ... )peModel( architecture = c("eegnet", "cnn1d", "tcn", "lstm"), n_channels, n_time, n_outputs, task = c("classification", "regression"), sampling_rate = NULL, dropout = 0.5, hidden = 32L, seed = 1L, ... )
architecture |
Exact architecture name. |
n_channels, n_time, n_outputs
|
Positive whole dimensions. |
task |
Exact task name. |
sampling_rate |
Optional positive sampling rate. |
dropout |
Dropout probability in |
|
Positive hidden width. |
|
seed |
CPU initialization seed. |
... |
Architecture-specific named settings. |
A physio_torch_module.
# Requires the optional torch backend. if (requireNamespace("torch", quietly = TRUE)) { model <- peModel( architecture = "cnn1d", n_channels = 2, n_time = 50, n_outputs = 2, task = "classification" ) }# Requires the optional torch backend. if (requireNamespace("torch", quietly = TRUE)) { model <- peModel( architecture = "cnn1d", n_channels = 2, n_time = 50, n_outputs = 2, task = "classification" ) }
Adapts catch22(), rocket(), or minirocket() output without adding an
outcome or changing the feature transform. For convolution methods, pass a
model fitted only on training cases when transforming validation/test cases.
peReducedFeatures( x, method = c("catch22", "rocket", "minirocket"), model = NULL, assay_name = NULL, channels = NULL, cases = NULL, ... )peReducedFeatures( x, method = c("catch22", "rocket", "minirocket"), model = NULL, assay_name = NULL, channels = NULL, cases = NULL, ... )
x |
A |
method |
Exactly one of |
model |
|
assay_name, channels, cases
|
Input selection; see |
... |
Method-specific arguments. |
A numeric matrix with class physio_feature_matrix. Attributes
preserve exact case identity, feature provenance, typed diagnostics, and
the fitted model when applicable.
arr <- array(stats::rnorm(40 * 2 * 3), dim = c(40, 2, 3)) pe <- PhysioExperiment::PhysioExperiment( assays = list(raw = arr), colData = S4Vectors::DataFrame(label = c("C3", "C4")), samplingRate = 100 ) # catch22 features need the optional Rcatch22 backend. if (requireNamespace("Rcatch22", quietly = TRUE)) { features <- peReducedFeatures(pe, method = "catch22") dim(features) }arr <- array(stats::rnorm(40 * 2 * 3), dim = c(40, 2, 3)) pe <- PhysioExperiment::PhysioExperiment( assays = list(raw = arr), colData = S4Vectors::DataFrame(label = c("C3", "C4")), samplingRate = 100 ) # catch22 features need the optional Rcatch22 backend. if (requireNamespace("Rcatch22", quietly = TRUE)) { features <- peReducedFeatures(pe, method = "catch22") dim(features) }
Inference uses evaluation mode and disabled gradients. The Dataset must exactly match the training channel, time, task, class, dtype, and frozen normalization contracts.
predictModel( model, newdata, batch_size = 64L, type = c("class", "probability", "response", "logit"), num_workers = 0L )predictModel( model, newdata, batch_size = 64L, type = c("class", "probability", "response", "logit"), num_workers = 0L )
model |
A fitted |
newdata |
A compatible target-free or targeted Dataset. |
batch_size |
Positive whole-number inference batch size. |
type |
Exact output type. |
num_workers |
Currently exactly zero. |
A numeric matrix or identity-preserving data frame.
arr <- array(stats::rnorm(50 * 2 * 6), dim = c(50, 2, 6)) pe <- PhysioExperiment::PhysioExperiment( assays = list(raw = arr), colData = S4Vectors::DataFrame(label = c("C3", "C4")), samplingRate = 100 ) # Needs the optional torch and luz backends. if (requireNamespace("torch", quietly = TRUE) && requireNamespace("luz", quietly = TRUE)) { train <- peDataset( pe, targets = rep(c("a", "b"), 3), task = "classification", class_levels = c("a", "b") ) fit <- trainModel(train, model = "cnn1d", epochs = 1L) predictModel(fit, train, type = "class") }arr <- array(stats::rnorm(50 * 2 * 6), dim = c(50, 2, 6)) pe <- PhysioExperiment::PhysioExperiment( assays = list(raw = arr), colData = S4Vectors::DataFrame(label = c("C3", "C4")), samplingRate = 100 ) # Needs the optional torch and luz backends. if (requireNamespace("torch", quietly = TRUE) && requireNamespace("luz", quietly = TRUE)) { train <- peDataset( pe, targets = rep(c("a", "b"), 3), task = "classification", class_levels = c("a", "b") ) fit <- trainModel(train, model = "cnn1d", epochs = 1L) predictModel(fit, train, type = "class") }
Uses aeon.transformations.collection.convolution_based.Rocket through an
optional, caller-configured reticulate backend.
With model = NULL, fits only on the selected cases and returns a reusable
persistent model. With a model, validates the complete input contract and
transforms without refitting.
rocket( x, model = NULL, assay_name = NULL, channels = NULL, cases = NULL, n_kernels = 10000L, seed = 1L, normalize = TRUE, backend = "aeon" )rocket( x, model = NULL, assay_name = NULL, channels = NULL, cases = NULL, n_kernels = 10000L, seed = 1L, normalize = TRUE, backend = "aeon" )
x |
A |
model |
|
assay_name, channels, cases
|
Input selection; see |
n_kernels |
One finite whole number of kernels. |
seed |
One whole-number backend seed in |
normalize |
One non-missing logical passed to aeon's |
backend |
Exactly |
Input assays are time x channel or time x channel x case and must contain finite, equal-length series of at least nine samples. The fitted model binds exact channel labels/order and time length. Requested kernel count and realized feature width are recorded separately because backend transforms may adjust the width.
Models persist the backend with Python pickle in a hashed raw vector. A matching SHA-256 detects corruption but does not make deserialization safe: only reuse model objects from trusted sources. PhysioML validates class, metadata, hash, input identity, and backend version before unpickling.
A physio_rocket_transform containing a finite case-by-feature
matrix, exact case identities, a persistent fitted model, settings, and
typed diagnostics.
Dempster A, Petitjean F, Webb GI (2020). ROCKET: Exceptionally fast and accurate time series classification using random convolutional kernels. Data Mining and Knowledge Discovery, 34, 1454-1495. doi:10.1007/s10618-020-00701-z
arr <- array(stats::rnorm(60 * 2 * 4), dim = c(60, 2, 4)) pe <- PhysioExperiment::PhysioExperiment( assays = list(raw = arr), colData = S4Vectors::DataFrame(label = c("C3", "C4")), samplingRate = 100 ) # The transform needs a caller-managed Python environment with NumPy and aeon. fit <- rocket(pe, n_kernels = 50) dim(fit$features)arr <- array(stats::rnorm(60 * 2 * 4), dim = c(60, 2, 4)) pe <- PhysioExperiment::PhysioExperiment( assays = list(raw = arr), colData = S4Vectors::DataFrame(label = c("C3", "C4")), samplingRate = 100 ) # The transform needs a caller-managed Python environment with NumPy and aeon. fit <- rocket(pe, n_kernels = 50) dim(fit$features)
The caller supplies case-disjoint training and validation Datasets.
When subject metadata is attached with withCaseData(), both datasets must
carry it and subjects must also be disjoint. Legacy unannotated inputs retain
case-only checking; missing metadata does not establish subject separation.
Validation must reuse training normalization statistics. CPU execution,
no worker processes, and deterministic caller-state restoration are enforced
in this implementation.
trainModel( train, valid = NULL, model = c("eegnet", "cnn1d", "tcn", "lstm"), epochs = 20L, batch_size = 32L, learning_rate = 0.001, weight_decay = 0, callbacks = NULL, seed = 1L, device = "cpu", num_workers = 0L, verbose = FALSE, ... )trainModel( train, valid = NULL, model = c("eegnet", "cnn1d", "tcn", "lstm"), epochs = 20L, batch_size = 32L, learning_rate = 0.001, weight_decay = 0, callbacks = NULL, seed = 1L, device = "cpu", num_workers = 0L, verbose = FALSE, ... )
train, valid
|
Targeted |
model |
Exact architecture name or a |
epochs, batch_size
|
Positive whole-number training settings. |
learning_rate |
Positive Adam learning rate. |
weight_decay |
Non-negative Adam weight decay. |
callbacks |
NULL or a list of luz callback instances. |
seed |
Whole-number CPU seed. |
device |
Currently exactly |
num_workers |
Currently exactly zero. |
verbose |
Whether luz prints progress. |
... |
Architecture settings when |
A physio_dl_model.
arr <- array(stats::rnorm(50 * 2 * 6), dim = c(50, 2, 6)) pe <- PhysioExperiment::PhysioExperiment( assays = list(raw = arr), colData = S4Vectors::DataFrame(label = c("C3", "C4")), samplingRate = 100 ) # Training needs the optional torch and luz backends. if (requireNamespace("torch", quietly = TRUE) && requireNamespace("luz", quietly = TRUE)) { train <- peDataset( pe, targets = rep(c("a", "b"), 3), task = "classification", class_levels = c("a", "b") ) fit <- trainModel(train, model = "cnn1d", epochs = 1L) }arr <- array(stats::rnorm(50 * 2 * 6), dim = c(50, 2, 6)) pe <- PhysioExperiment::PhysioExperiment( assays = list(raw = arr), colData = S4Vectors::DataFrame(label = c("C3", "C4")), samplingRate = 100 ) # Training needs the optional torch and luz backends. if (requireNamespace("torch", quietly = TRUE) && requireNamespace("luz", quietly = TRUE)) { train <- peDataset( pe, targets = rep(c("a", "b"), 3), task = "classification", class_levels = c("a", "b") ) fit <- trainModel(train, model = "cnn1d", epochs = 1L) }
Checks explicit identifiers only; this does not audit upstream preprocessing fit scopes, verify biological identity, or prevent leakage in external model software unless called before fitting. No backend is needed.
validateSubjectSplit(train, valid)validateSubjectSplit(train, valid)
train, valid
|
Case identity data frames as in |
Invisibly TRUE, or an error for shared cases or subjects, invalid
labels, or inconsistent participant aliases.
train <- data.frame(case_id = c("c1", "c2"), subject_id = c("s1", "s2")) valid <- data.frame(case_id = c("c3", "c4"), subject_id = c("s3", "s4")) validateSubjectSplit(train, valid)train <- data.frame(case_id = c("c1", "c2"), subject_id = c("s1", "s2")) valid <- data.frame(case_id = c("c3", "c4"), subject_id = c("s3", "s4")) validateSubjectSplit(train, valid)
Establishes a case-to-subject mapping without inferring subjects from case names. Row order is reconciled by exact case ID. A cycle is a case, not an independent subject. Use cohort-derived subject/session keys when available.
withCaseData(x, case_data)withCaseData(x, case_data)
x |
A |
case_data |
Data frame with unique |
The input with validated identity metadata. Experiments store it in
metadata(x)$ml_case_data; matrices store it in attribute case_data.
PhysioML input transforms and datasets preserve this information. Ordinary
external matrix manipulation is not guaranteed to preserve attributes;
reattach the corresponding table after subsetting feature rows.
validateSubjectSplit(), peDataset(), peReducedFeatures()
# Attach subject identity to a case-by-feature matrix. features <- matrix( stats::rnorm(8), nrow = 2, dimnames = list(c("c1", "c2"), c("a", "b", "c", "d")) ) case_data <- data.frame(case_id = c("c1", "c2"), subject_id = c("s1", "s2")) labelled <- withCaseData(features, case_data) attr(labelled, "case_data")# Attach subject identity to a case-by-feature matrix. features <- matrix( stats::rnorm(8), nrow = 2, dimnames = list(c("c1", "c2"), c("a", "b", "c", "d")) ) case_data <- data.frame(case_id = c("c1", "c2"), subject_id = c("s1", "s2")) labelled <- withCaseData(features, case_data) attr(labelled, "case_data")