eegproc.deep_learning.cross_validation.calibration module
Subject-calibration cross-validation entry point.
- eegproc.deep_learning.cross_validation.calibration.subject_calibration_cv(model_builder_function, feature_array, label_array, subject_id_array, trial_id_array, fixed_config=None, source_epochs=100, source_batch_size=64, calibration_epochs=20, calibration_batch_size=6, *, pretrained_model=None, calibration_trials=6, calibration_folds=3, calibration_levels=None, calibration_selection_shots=None, calibration_learning_rate=0.0001, calibration_optimizer='adamw', calibration_weight_decay=0.0, calibration_seed=42, stratify_calibration=True, allow_overlapping_calibration_folds=False, validation_subjects_per_fold=0, validation_seed=42, early_stopping_patience=None, early_stopping_min_delta=0.0, early_stopping_monitor='val_loss', early_stopping_mode='auto', restore_best_weights=True, evaluation_level='trial', metrics=('accuracy', 'f1', 'precision', 'recall', 'macro_f1', 'macro_precision', 'macro_recall', 'balanced_accuracy', 'roc_auc', 'brier_score', 'ece'), ece_bins=15, decision_threshold=0.5, prediction_diagnostics_thresholds=None, prediction_diagnostics=False, prediction_diagnostics_metric='accuracy', prediction_diagnostics_every_n_epochs=1, prediction_diagnostics_max_samples=256, prediction_diagnostics_threshold_tolerance=0.01, prediction_diagnostics_seed=42, n_prediction_latent_samples=0, latent_sampling_seed=None, log_predictions=True, log_variational_intervals=False, n_uncertainty_samples=30, ci_level=0.95, source_use_class_weight=False, calibration_use_class_weight=False, source_fit_kwargs=None, calibration_fit_kwargs=None, calibration_verbose=False, calibration_print_every_n_epochs=1, verbose=0, n_jobs=1, gpu_ids=None, cpus_per_worker=None, max_subjects=None, target_subjects=None, source_model_output_dir=None)[source]
Strict LOSO pretraining followed by one or more calibration levels.
Pass exactly one of
model_builder_functionandpretrained_model. The pretrained path accepts one already-loaded, target-specific LOSO model, requires one explicittarget_subjectsentry, and skips source fitting.For each target subject, a fresh subject-independent source model is first trained using the other subjects. When
validation_subjects_per_foldis positive, a seeded subset of those source subjects is excluded from gradient updates and used only for source checkpoint selection. The target subject is never used to construct, optimize, or select that source model. This is important for models that learn data-dependent adjacency: the fourtraining_*arrays contain only gradient-training source subjects, so its fixed mutual-information adjacency remains training-only.The source model is evaluated zero-shot on all target trials once. Pass
calibration_levels=((3, 6), (6, 3), ...)to request(shots, folds)pairs. If omitted, the legacycalibration_trials/calibration_foldspair is used. The same source checkpoint is restored for every level and fold; it is never retrained between calibration levels. Exact partitions are used whenshots * foldsequals the retained trial count, otherwise seeded repeated holdouts evaluate on every non-calibration trial. For each fold:restore the exact source-pretrained weights;
evaluate zero-shot on the trials not used for calibration;
call
model.prepare_for_subject_calibration(...);fine-tune only the model-defined calibration parameters, printing reporting-only oracle predictions on every non-calibration trial after each epoch;
evaluate the calibrated model on the same held-out target trials.
When
source_model_output_diris provided, the exact source-trained 0-shot model for every LOSO target is saved there in native.kerasformat before calibration begins. Calibrated fold continuations are not saved. Load these source models withcompile=Falsebefore calling the model’s calibration preparation hook, which installs a fresh optimizer. Model-specific calibration settings may optionally keep reconstruction decoders trainable and add their weighted loss to the calibration objective.Thus the default DREAMER protocol remains 6 calibration trials + 12 evaluation trials repeated three times, while arbitrary valid shot/fold pairs can be evaluated in the same LOSO run.
model_builder_functioncontractIn addition to
fixed_configmodel kwargs, the builder must accept:training_features,training_labels,training_subject_ids, andtraining_trial_ids. The first of these is where v6 should estimate its training-only MI graph.prepare_for_subject_calibrationcontractThe returned model must implement:
model.prepare_for_subject_calibration( learning_rate=..., optimizer_name=..., weight_decay=..., )
The method owns the architecture-specific freezing policy and must compile a fresh optimizer. A typical policy freezes the shared representation layers — graph, spectral and temporal encoders, plus any subject-invariance machinery — while the classification head stays trainable; reconstruction decoders may also remain trainable when the model’s calibration settings request it.
Aggregation
Metrics are first averaged across folds within each subject and shot level, then across subjects. Calibration folds are never treated as independent subjects. JSON output retains every requested metric at every shot level; terminal output reports final mean accuracy, balanced accuracy, and Brier score for 0-shot and each calibrated level.
- type model_builder_function:
Optional[Callable[...,Model]]- param model_builder_function:
- type feature_array:
ndarray- param feature_array:
- type label_array:
ndarray- param label_array:
- type subject_id_array:
ndarray- param subject_id_array:
- type trial_id_array:
ndarray- param trial_id_array:
- type fixed_config:
dict|None, default:None- param fixed_config:
- type source_epochs:
int, default:100- param source_epochs:
- type source_batch_size:
int, default:64- param source_batch_size:
- type calibration_epochs:
int, default:20- param calibration_epochs:
- type calibration_batch_size:
int, default:6- param calibration_batch_size:
- type pretrained_model:
Model|None, default:None- param pretrained_model:
- type calibration_trials:
int, default:6- param calibration_trials:
- type calibration_folds:
int, default:3- param calibration_folds:
- type calibration_levels:
list[tuple[int,int]] |tuple[tuple[int,int],...] |None, default:None- param calibration_levels:
- type calibration_selection_shots:
int|None, default:None- param calibration_selection_shots:
- type calibration_learning_rate:
float, default:0.0001- param calibration_learning_rate:
- type calibration_optimizer:
str, default:'adamw'- param calibration_optimizer:
- type calibration_weight_decay:
float, default:0.0- param calibration_weight_decay:
- type calibration_seed:
int|None, default:42- param calibration_seed:
- type stratify_calibration:
bool, default:True- param stratify_calibration:
- type allow_overlapping_calibration_folds:
bool, default:False- param allow_overlapping_calibration_folds:
- type validation_subjects_per_fold:
int, default:0- param validation_subjects_per_fold:
- type validation_seed:
int|None, default:42- param validation_seed:
- type early_stopping_patience:
int|None, default:None- param early_stopping_patience:
- type early_stopping_min_delta:
float, default:0.0- param early_stopping_min_delta:
- type early_stopping_monitor:
str, default:'val_loss'- param early_stopping_monitor:
- type early_stopping_mode:
Literal['auto','min','max'], default:'auto'- param early_stopping_mode:
- type restore_best_weights:
bool, default:True- param restore_best_weights:
- type evaluation_level:
Literal['window','trial'], default:'trial'- param evaluation_level:
- type metrics:
list[str] |tuple[str,...], default:('accuracy', 'f1', 'precision', 'recall', 'macro_f1', 'macro_precision', 'macro_recall', 'balanced_accuracy', 'roc_auc', 'brier_score', 'ece')- param metrics:
- type ece_bins:
int, default:15- param ece_bins:
- type decision_threshold:
float, default:0.5- param decision_threshold:
- type prediction_diagnostics_thresholds:
list[float] |tuple[float,...] |None, default:None- param prediction_diagnostics_thresholds:
- type prediction_diagnostics:
bool, default:False- param prediction_diagnostics:
- type prediction_diagnostics_metric:
str, default:'accuracy'- param prediction_diagnostics_metric:
- type prediction_diagnostics_every_n_epochs:
int, default:1- param prediction_diagnostics_every_n_epochs:
- type prediction_diagnostics_max_samples:
int, default:256- param prediction_diagnostics_max_samples:
- type prediction_diagnostics_threshold_tolerance:
float, default:0.01- param prediction_diagnostics_threshold_tolerance:
- type prediction_diagnostics_seed:
int|None, default:42- param prediction_diagnostics_seed:
- type n_prediction_latent_samples:
int, default:0- param n_prediction_latent_samples:
- type latent_sampling_seed:
int|None, default:None- param latent_sampling_seed:
- type log_predictions:
bool, default:True- param log_predictions:
- type log_variational_intervals:
bool, default:False- param log_variational_intervals:
- type n_uncertainty_samples:
int, default:30- param n_uncertainty_samples:
- type ci_level:
float, default:0.95- param ci_level:
- type source_use_class_weight:
bool, default:False- param source_use_class_weight:
- type calibration_use_class_weight:
bool, default:False- param calibration_use_class_weight:
- type source_fit_kwargs:
dict|None, default:None- param source_fit_kwargs:
- type calibration_fit_kwargs:
dict|None, default:None- param calibration_fit_kwargs:
- type calibration_verbose:
bool, default:False- param calibration_verbose:
- type calibration_print_every_n_epochs:
int, default:1- param calibration_print_every_n_epochs:
- type verbose:
int, default:0- param verbose:
- type n_jobs:
int, default:1- param n_jobs:
- type gpu_ids:
list[int] |tuple[int,...] |None, default:None- param gpu_ids:
- type cpus_per_worker:
int|None, default:None- param cpus_per_worker:
- type max_subjects:
int|None, default:None- param max_subjects:
- type target_subjects:
list[int] |tuple[int,...] |None, default:None- param target_subjects:
- type source_model_output_dir:
str|PathLike[str] |None, default:None- param source_model_output_dir:
- rtype:
dict