Repository navigation
Cross-system transfer tutorial: masked-mean MDM with groups="device" (route metadata columns to pipelines) - #1305
Conversation
bruAristimunha
left a comment
There was a problem hiding this comment.
Thanks @qbarthelemy, the evaluation fits #1221 well, and the metadata routing of systems and the per-dataset result filtering are clean. A review round before it can go in (the branch also needs develop merged; it conflicts now):
Should fix
__init__:self.datasets = list(target_datasets)replaces the list afterBaseEvaluation.__init__has filtered it, so targets skip the paradigm check, and a target that is not indatasetsproduces no fold and returns an empty result without any message. Suggest validatingtarget_datasetsagainst the filteredself.systems(same code) and raising otherwise._load_dataloads every system in full on each call, ignoringsubjects, and is called once per target: leave-one-system-out on k systems does k full loads of all k datasets. Loading the systems once perprocess()(e.g. keep the concatenatedX, y, metadataon the instance for the duration of the run) avoids the k² reads._load_dataalso ignoresrun_pipes/process_pipeline: a pipeline that needsEpochs(TRCA, braindecode, ...) silently receives arrays, and a filter-bank paradigm gets a single band. Raising a clearValueErrorfor epoch-requiring pipelines (as done forpostprocess_pipeline) is enough for now.
Minor
- With
datasets=None, every dataset of the paradigm becomes a system and is loaded for each target; worth requiring explicitdatasetshere. - The
_process_parallelchange (keep only the current dataset's rows) also fixes duplicated rows for the other evaluations when datasets share a pipeline digest; it deserves its own Bugs entry inwhats_new.rst.
Happy to help with the develop merge once these are settled.
# Conflicts: # docs/source/whats_new.rst # moabb/tests/test_evaluations.py
…and epoch pipelines Review follow-ups: the systems were reloaded in full for every target (k^2 loads), a target_datasets entry outside datasets gave an empty result, and pipelines needing mne.Epochs silently received arrays.
|
@qbarthelemy I pushed two commits to your branch so this can go in: a merge of |
|
@qbarthelemy following the review here, we went the other way round: instead of a new evaluation, the existing API now covers cross-system transfer, and your example becomes a tutorial.
Once #1328 is in, I'd like to turn this PR into the tutorial: keep your example (union of channels, masks, masked-mean classifier vs. channel intersection), run it through |
# Conflicts: # docs/source/whats_new.rst # moabb/evaluations/utils.py # moabb/tests/test_evaluations.py
Review of NeuroTechX#1305 (Bruno): no new evaluation. The example now pools the devices in a CompoundDataset and holds out one device at a time with CrossSubjectEvaluation(cv_class=LeaveOneGroupOut, groups='device'), on the nested trials of NeuroTechX#1327 and the device column of NeuroTechX#1328. - remove CrossSystemEvaluation, its tests and extra_fit_params; - _evaluate_fold routes any metadata column of the training trials to the steps requesting it (set_fit_request(device=True)), replacing the cross-system-only 'systems' routing; - FakeDataset takes a device; - the example's ChannelUnion and MDMM read the device of each training trial and infer the held-out device, so every device can be the target; - keep the duplicated-results fix of process() and its test.
CrossSystemEvaluation|
@qbarthelemy as announced above (no objection after a day), I pushed bf93c3d to turn this into the tutorial: |
# Conflicts: # docs/source/whats_new.rst
|
Sorry, I’m often AFK on the weekends. |
Solve #1221 (as a tutorial, after review)
Cross-system transfer, where each system is an EEG device with its own montage and sampling rate, is handled by the existing API instead of a new evaluation class:
CompoundDataset;CrossSubjectEvaluation(cv_class=LeaveOneGroupOut, groups="device")holds out one device at a time, using thedevicemetadata column (Add dataset and device columns to the paradigm metadata (leave-one-device-out with groups="device") #1328). A device is not a dataset: one dataset can use several devices, several datasets can share one.This PR now contains
examples/how_to_benchmark/plot_cross_system_transfer_maskedmean.py: union of channels, mask matrices, minimum distance to masked Riemannian mean vs. zero-filled and channel-intersection MDM. The pipeline steps read the device of each training trial and infer the held-out device, so every device is the target in turn;_evaluate_fold: any metadata column of the training trials (device,dataset,subject...) is passed to the steps that request it withset_fit_request(<column>=True), only when requested;deviceargument forFakeDataset;process()returning results several times when datasets share a processing pipeline (found here, with its test).CrossSystemEvaluationand its cross-system-only routing are removed.Tests: metadata-column routing (requested / not requested), leave-one-device-out routing only the training devices, duplicated results; the tutorial runs end to end.
test_evaluations.py,test_paradigms.pyandtest_splits.pypass locally.@bruAristimunha @sylvchev @plcrodrigues