Last active
June 15, 2021 11:21
-
-
Save gemeinl/d64c014debb5f58e4feacb57a8656ed0 to your computer and use it in GitHub Desktop.
Braindecode with sci-kit learn pipeline chaining
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"cell_type": "code", | |
"execution_count": 1, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stderr", | |
"output_type": "stream", | |
"text": [ | |
"/home/gemeinl/anaconda3/envs/new_braindecode/lib/python3.7/site-packages/sklearn/utils/deprecation.py:144: FutureWarning: The sklearn.metrics.scorer module is deprecated in version 0.22 and will be removed in version 0.24. The corresponding classes / functions should instead be imported from sklearn.metrics. Anything that cannot be imported from sklearn.metrics is now part of the private API.\n", | |
" warnings.warn(message, FutureWarning)\n" | |
] | |
} | |
], | |
"source": [ | |
"import torch\n", | |
"from sklearn.pipeline import Pipeline\n", | |
"from skorch.callbacks import LRScheduler\n", | |
"from skorch.helper import predefined_split\n", | |
"from sklearn.base import TransformerMixin\n", | |
"\n", | |
"from braindecode import EEGClassifier\n", | |
"from braindecode.util import set_random_seeds\n", | |
"from braindecode.models import ShallowFBCSPNet\n", | |
"from braindecode.datautil.preprocess import exponential_moving_standardize\n", | |
"from braindecode.datasets.moabb import MOABBDataset\n", | |
"from braindecode.datautil.windowers import (\n", | |
" create_windows_from_events, create_fixed_length_windows)\n", | |
"from braindecode.datautil.preprocess import (\n", | |
" MNEPreproc, NumpyPreproc, preprocess)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 2, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"class Preprocessor(TransformerMixin):\n", | |
" def fit(self, X, y=None):\n", | |
" return self\n", | |
" \n", | |
"\n", | |
"class EventWindower(Preprocessor):\n", | |
" def __init__(self, *args, **kwargs):\n", | |
" self.args=args\n", | |
" self.kwargs=kwargs\n", | |
" \n", | |
" def transform(self, X):\n", | |
" return create_windows_from_events(\n", | |
" concat_ds=X, *self.args, **self.kwargs)\n", | |
" \n", | |
" \n", | |
"class FixedLengthWindower(Preprocessor):\n", | |
" def __init__(self, *args, **kwargs):\n", | |
" self.args=args\n", | |
" self.kwargs=kwargs\n", | |
" \n", | |
" def transform(self, X):\n", | |
" return create_fixed_length_windows(\n", | |
" concat_ds=X, *self.args, **self.kwargs)\n", | |
"\n", | |
" \n", | |
"class MNETransformer(Preprocessor):\n", | |
" def __init__(self, fn, **kwargs):\n", | |
" self.pre = MNEPreproc(fn=fn, **kwargs)\n", | |
" \n", | |
" def transform(self, X):\n", | |
" preprocess(X, [self.pre])\n", | |
" return X\n", | |
"\n", | |
" \n", | |
"class NumpyTransformer(Preprocessor):\n", | |
" def __init__(self, fn, **kwargs):\n", | |
" self.pre = NumpyPreproc(fn=fn, **kwargs)\n", | |
" \n", | |
" def transform(self, X):\n", | |
" preprocess(X, [self.pre])\n", | |
" return X" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 3, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"# Known from experimental design\n", | |
"sfreq = 250 \n", | |
"n_classes = 4\n", | |
"n_chans = 22\n", | |
"original_trial_duration = 4" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 4, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"# Preprocessing parameters\n", | |
"low_cut_hz = 4. # low cut frequency for filtering\n", | |
"high_cut_hz = 38. # high cut frequency for filtering\n", | |
"# Parameters for exponential moving standardization\n", | |
"factor_new = 1e-3\n", | |
"init_block_size = 1000\n", | |
"trial_start_offset_seconds = -0.5\n", | |
"# Calculate the trial start offset in samples.\n", | |
"trial_start_offset_samples = int(trial_start_offset_seconds * sfreq)\n", | |
"\n", | |
"\n", | |
"# Model parameters\n", | |
"seed = 20200220 # random seed to make results reproducible\n", | |
"input_window_samples = int(original_trial_duration * sfreq - trial_start_offset_samples)\n", | |
"\n", | |
"\n", | |
"# Training parameters\n", | |
"batch_size = 64\n", | |
"n_epochs = 4\n", | |
"# These values we found good for shallow network:\n", | |
"lr = 0.0625 * 0.01\n", | |
"weight_decay = 0\n", | |
"# For deep4 they should be:\n", | |
"# lr = 1 * 0.01\n", | |
"# weight_decay = 0.5 * 0.001" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"create a model" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 5, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"cuda = torch.cuda.is_available() # check if GPU is available, if True chooses to use it\n", | |
"device = 'cuda' if cuda else 'cpu'\n", | |
"if cuda:\n", | |
" torch.backends.cudnn.benchmark = True\n", | |
"\n", | |
"# Set random seed to be able to reproduce results\n", | |
"set_random_seeds(seed=seed, cuda=cuda)\n", | |
"\n", | |
"model = ShallowFBCSPNet(\n", | |
" n_chans,\n", | |
" n_classes,\n", | |
" input_window_samples=input_window_samples,\n", | |
" final_conv_length='auto',\n", | |
")\n", | |
"\n", | |
"# Send model to GPU\n", | |
"if cuda:\n", | |
" model.cuda()" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"chain all preprocessing steps as well as classifier in a pipeline" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 6, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"pipe = Pipeline([\n", | |
" (\"pick_channels\", MNETransformer(\n", | |
" fn='pick_types', \n", | |
" eeg=True, \n", | |
" meg=False, \n", | |
" stim=False)\n", | |
" ),\n", | |
" (\"convert_to_microvolts\", NumpyTransformer(\n", | |
" fn=lambda x: x * 1e6)\n", | |
" ),\n", | |
" (\"bandpass\", MNETransformer(\n", | |
" fn='filter', \n", | |
" l_freq=low_cut_hz, \n", | |
" h_freq=high_cut_hz)\n", | |
" ),\n", | |
" (\"standardize\", NumpyTransformer(\n", | |
" fn=exponential_moving_standardize, \n", | |
" factor_new=factor_new,\n", | |
" init_block_size=init_block_size)\n", | |
" ),\n", | |
" (\"create_compute_windows\", EventWindower(\n", | |
" trial_start_offset_samples=trial_start_offset_samples,\n", | |
" trial_stop_offset_samples=0, preload=True)\n", | |
" ),\n", | |
" (\"classifier\", EEGClassifier(\n", | |
" model,\n", | |
" criterion=torch.nn.NLLLoss,\n", | |
" optimizer=torch.optim.AdamW,\n", | |
" train_split=lambda X, y: (X.split(\"session\")[\"session_T\"], \n", | |
" X.split(\"session\")[\"session_E\"]),\n", | |
" optimizer__lr=lr,\n", | |
" optimizer__weight_decay=weight_decay,\n", | |
" batch_size=batch_size,\n", | |
" callbacks=[\n", | |
" \"accuracy\", \n", | |
" (\"lr_scheduler\", LRScheduler('CosineAnnealingLR', T_max=n_epochs - 1)),\n", | |
" ],\n", | |
" device=device)),\n", | |
"])" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"load some data" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 7, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"48 events found\n", | |
"Event IDs: [1 2 3 4]\n", | |
"48 events found\n", | |
"Event IDs: [1 2 3 4]\n", | |
"48 events found\n", | |
"Event IDs: [1 2 3 4]\n", | |
"48 events found\n", | |
"Event IDs: [1 2 3 4]\n", | |
"48 events found\n", | |
"Event IDs: [1 2 3 4]\n", | |
"48 events found\n", | |
"Event IDs: [1 2 3 4]\n", | |
"48 events found\n", | |
"Event IDs: [1 2 3 4]\n", | |
"48 events found\n", | |
"Event IDs: [1 2 3 4]\n", | |
"48 events found\n", | |
"Event IDs: [1 2 3 4]\n", | |
"48 events found\n", | |
"Event IDs: [1 2 3 4]\n", | |
"48 events found\n", | |
"Event IDs: [1 2 3 4]\n", | |
"48 events found\n", | |
"Event IDs: [1 2 3 4]\n" | |
] | |
} | |
], | |
"source": [ | |
"subject_id = 3\n", | |
"dataset = MOABBDataset(dataset_name=\"BNCI2014001\", subject_ids=[subject_id])\n", | |
"assert all([ds.raw.info['sfreq'] == sfreq for ds in dataset.datasets])" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"perform fit" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 8, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"Filtering raw data in 1 contiguous segment\n", | |
"Setting up band-pass filter from 4 - 38 Hz\n", | |
"\n", | |
"FIR filter parameters\n", | |
"---------------------\n", | |
"Designing a one-pass, zero-phase, non-causal bandpass filter:\n", | |
"- Windowed time-domain design (firwin) method\n", | |
"- Hamming window with 0.0194 passband ripple and 53 dB stopband attenuation\n", | |
"- Lower passband edge: 4.00\n", | |
"- Lower transition bandwidth: 2.00 Hz (-6 dB cutoff frequency: 3.00 Hz)\n", | |
"- Upper passband edge: 38.00 Hz\n", | |
"- Upper transition bandwidth: 9.50 Hz (-6 dB cutoff frequency: 42.75 Hz)\n", | |
"- Filter length: 413 samples (1.652 sec)\n", | |
"\n", | |
"Filtering raw data in 1 contiguous segment\n", | |
"Setting up band-pass filter from 4 - 38 Hz\n", | |
"\n", | |
"FIR filter parameters\n", | |
"---------------------\n", | |
"Designing a one-pass, zero-phase, non-causal bandpass filter:\n", | |
"- Windowed time-domain design (firwin) method\n", | |
"- Hamming window with 0.0194 passband ripple and 53 dB stopband attenuation\n", | |
"- Lower passband edge: 4.00\n", | |
"- Lower transition bandwidth: 2.00 Hz (-6 dB cutoff frequency: 3.00 Hz)\n", | |
"- Upper passband edge: 38.00 Hz\n", | |
"- Upper transition bandwidth: 9.50 Hz (-6 dB cutoff frequency: 42.75 Hz)\n", | |
"- Filter length: 413 samples (1.652 sec)\n", | |
"\n", | |
"Filtering raw data in 1 contiguous segment\n", | |
"Setting up band-pass filter from 4 - 38 Hz\n", | |
"\n", | |
"FIR filter parameters\n", | |
"---------------------\n", | |
"Designing a one-pass, zero-phase, non-causal bandpass filter:\n", | |
"- Windowed time-domain design (firwin) method\n", | |
"- Hamming window with 0.0194 passband ripple and 53 dB stopband attenuation\n", | |
"- Lower passband edge: 4.00\n", | |
"- Lower transition bandwidth: 2.00 Hz (-6 dB cutoff frequency: 3.00 Hz)\n", | |
"- Upper passband edge: 38.00 Hz\n", | |
"- Upper transition bandwidth: 9.50 Hz (-6 dB cutoff frequency: 42.75 Hz)\n", | |
"- Filter length: 413 samples (1.652 sec)\n", | |
"\n", | |
"Filtering raw data in 1 contiguous segment\n", | |
"Setting up band-pass filter from 4 - 38 Hz\n", | |
"\n", | |
"FIR filter parameters\n", | |
"---------------------\n", | |
"Designing a one-pass, zero-phase, non-causal bandpass filter:\n", | |
"- Windowed time-domain design (firwin) method\n", | |
"- Hamming window with 0.0194 passband ripple and 53 dB stopband attenuation\n", | |
"- Lower passband edge: 4.00\n", | |
"- Lower transition bandwidth: 2.00 Hz (-6 dB cutoff frequency: 3.00 Hz)\n", | |
"- Upper passband edge: 38.00 Hz\n", | |
"- Upper transition bandwidth: 9.50 Hz (-6 dB cutoff frequency: 42.75 Hz)\n", | |
"- Filter length: 413 samples (1.652 sec)\n", | |
"\n", | |
"Filtering raw data in 1 contiguous segment\n", | |
"Setting up band-pass filter from 4 - 38 Hz\n", | |
"\n", | |
"FIR filter parameters\n", | |
"---------------------\n", | |
"Designing a one-pass, zero-phase, non-causal bandpass filter:\n", | |
"- Windowed time-domain design (firwin) method\n", | |
"- Hamming window with 0.0194 passband ripple and 53 dB stopband attenuation\n", | |
"- Lower passband edge: 4.00\n", | |
"- Lower transition bandwidth: 2.00 Hz (-6 dB cutoff frequency: 3.00 Hz)\n", | |
"- Upper passband edge: 38.00 Hz\n", | |
"- Upper transition bandwidth: 9.50 Hz (-6 dB cutoff frequency: 42.75 Hz)\n", | |
"- Filter length: 413 samples (1.652 sec)\n", | |
"\n", | |
"Filtering raw data in 1 contiguous segment\n", | |
"Setting up band-pass filter from 4 - 38 Hz\n", | |
"\n", | |
"FIR filter parameters\n", | |
"---------------------\n", | |
"Designing a one-pass, zero-phase, non-causal bandpass filter:\n", | |
"- Windowed time-domain design (firwin) method\n", | |
"- Hamming window with 0.0194 passband ripple and 53 dB stopband attenuation\n", | |
"- Lower passband edge: 4.00\n", | |
"- Lower transition bandwidth: 2.00 Hz (-6 dB cutoff frequency: 3.00 Hz)\n", | |
"- Upper passband edge: 38.00 Hz\n", | |
"- Upper transition bandwidth: 9.50 Hz (-6 dB cutoff frequency: 42.75 Hz)\n", | |
"- Filter length: 413 samples (1.652 sec)\n", | |
"\n", | |
"Filtering raw data in 1 contiguous segment\n", | |
"Setting up band-pass filter from 4 - 38 Hz\n", | |
"\n", | |
"FIR filter parameters\n", | |
"---------------------\n", | |
"Designing a one-pass, zero-phase, non-causal bandpass filter:\n", | |
"- Windowed time-domain design (firwin) method\n", | |
"- Hamming window with 0.0194 passband ripple and 53 dB stopband attenuation\n", | |
"- Lower passband edge: 4.00\n", | |
"- Lower transition bandwidth: 2.00 Hz (-6 dB cutoff frequency: 3.00 Hz)\n", | |
"- Upper passband edge: 38.00 Hz\n", | |
"- Upper transition bandwidth: 9.50 Hz (-6 dB cutoff frequency: 42.75 Hz)\n", | |
"- Filter length: 413 samples (1.652 sec)\n", | |
"\n", | |
"Filtering raw data in 1 contiguous segment\n", | |
"Setting up band-pass filter from 4 - 38 Hz\n", | |
"\n", | |
"FIR filter parameters\n", | |
"---------------------\n", | |
"Designing a one-pass, zero-phase, non-causal bandpass filter:\n", | |
"- Windowed time-domain design (firwin) method\n", | |
"- Hamming window with 0.0194 passband ripple and 53 dB stopband attenuation\n", | |
"- Lower passband edge: 4.00\n", | |
"- Lower transition bandwidth: 2.00 Hz (-6 dB cutoff frequency: 3.00 Hz)\n", | |
"- Upper passband edge: 38.00 Hz\n", | |
"- Upper transition bandwidth: 9.50 Hz (-6 dB cutoff frequency: 42.75 Hz)\n", | |
"- Filter length: 413 samples (1.652 sec)\n", | |
"\n", | |
"Filtering raw data in 1 contiguous segment\n", | |
"Setting up band-pass filter from 4 - 38 Hz\n", | |
"\n", | |
"FIR filter parameters\n", | |
"---------------------\n", | |
"Designing a one-pass, zero-phase, non-causal bandpass filter:\n", | |
"- Windowed time-domain design (firwin) method\n", | |
"- Hamming window with 0.0194 passband ripple and 53 dB stopband attenuation\n", | |
"- Lower passband edge: 4.00\n", | |
"- Lower transition bandwidth: 2.00 Hz (-6 dB cutoff frequency: 3.00 Hz)\n", | |
"- Upper passband edge: 38.00 Hz\n", | |
"- Upper transition bandwidth: 9.50 Hz (-6 dB cutoff frequency: 42.75 Hz)\n", | |
"- Filter length: 413 samples (1.652 sec)\n", | |
"\n", | |
"Filtering raw data in 1 contiguous segment\n", | |
"Setting up band-pass filter from 4 - 38 Hz\n", | |
"\n", | |
"FIR filter parameters\n", | |
"---------------------\n", | |
"Designing a one-pass, zero-phase, non-causal bandpass filter:\n", | |
"- Windowed time-domain design (firwin) method\n", | |
"- Hamming window with 0.0194 passband ripple and 53 dB stopband attenuation\n", | |
"- Lower passband edge: 4.00\n", | |
"- Lower transition bandwidth: 2.00 Hz (-6 dB cutoff frequency: 3.00 Hz)\n", | |
"- Upper passband edge: 38.00 Hz\n", | |
"- Upper transition bandwidth: 9.50 Hz (-6 dB cutoff frequency: 42.75 Hz)\n", | |
"- Filter length: 413 samples (1.652 sec)\n", | |
"\n", | |
"Filtering raw data in 1 contiguous segment\n", | |
"Setting up band-pass filter from 4 - 38 Hz\n", | |
"\n", | |
"FIR filter parameters\n", | |
"---------------------\n", | |
"Designing a one-pass, zero-phase, non-causal bandpass filter:\n", | |
"- Windowed time-domain design (firwin) method\n", | |
"- Hamming window with 0.0194 passband ripple and 53 dB stopband attenuation\n", | |
"- Lower passband edge: 4.00\n", | |
"- Lower transition bandwidth: 2.00 Hz (-6 dB cutoff frequency: 3.00 Hz)\n", | |
"- Upper passband edge: 38.00 Hz\n", | |
"- Upper transition bandwidth: 9.50 Hz (-6 dB cutoff frequency: 42.75 Hz)\n", | |
"- Filter length: 413 samples (1.652 sec)\n", | |
"\n", | |
"Filtering raw data in 1 contiguous segment\n", | |
"Setting up band-pass filter from 4 - 38 Hz\n", | |
"\n", | |
"FIR filter parameters\n", | |
"---------------------\n", | |
"Designing a one-pass, zero-phase, non-causal bandpass filter:\n", | |
"- Windowed time-domain design (firwin) method\n", | |
"- Hamming window with 0.0194 passband ripple and 53 dB stopband attenuation\n", | |
"- Lower passband edge: 4.00\n", | |
"- Lower transition bandwidth: 2.00 Hz (-6 dB cutoff frequency: 3.00 Hz)\n", | |
"- Upper passband edge: 38.00 Hz\n", | |
"- Upper transition bandwidth: 9.50 Hz (-6 dB cutoff frequency: 42.75 Hz)\n", | |
"- Filter length: 413 samples (1.652 sec)\n", | |
"\n", | |
"Used Annotations descriptions: ['feet', 'left_hand', 'right_hand', 'tongue']\n", | |
"48 matching events found\n", | |
"No baseline correction applied\n", | |
"Adding metadata with 4 columns\n", | |
"0 projection items activated\n", | |
"Loading data for 48 events and 1125 original time points ...\n", | |
"0 bad epochs dropped\n", | |
"0 bad epochs dropped\n", | |
"Used Annotations descriptions: ['feet', 'left_hand', 'right_hand', 'tongue']\n", | |
"48 matching events found\n", | |
"No baseline correction applied\n", | |
"Adding metadata with 4 columns\n", | |
"0 projection items activated\n", | |
"Loading data for 48 events and 1125 original time points ...\n", | |
"0 bad epochs dropped\n", | |
"0 bad epochs dropped\n", | |
"Used Annotations descriptions: ['feet', 'left_hand', 'right_hand', 'tongue']\n", | |
"48 matching events found\n", | |
"No baseline correction applied\n", | |
"Adding metadata with 4 columns\n", | |
"0 projection items activated\n", | |
"Loading data for 48 events and 1125 original time points ...\n", | |
"0 bad epochs dropped\n", | |
"0 bad epochs dropped\n", | |
"Used Annotations descriptions: ['feet', 'left_hand', 'right_hand', 'tongue']\n", | |
"48 matching events found\n", | |
"No baseline correction applied\n", | |
"Adding metadata with 4 columns\n", | |
"0 projection items activated\n", | |
"Loading data for 48 events and 1125 original time points ...\n", | |
"0 bad epochs dropped\n", | |
"0 bad epochs dropped\n", | |
"Used Annotations descriptions: ['feet', 'left_hand', 'right_hand', 'tongue']\n", | |
"48 matching events found\n", | |
"No baseline correction applied\n", | |
"Adding metadata with 4 columns\n", | |
"0 projection items activated\n", | |
"Loading data for 48 events and 1125 original time points ...\n", | |
"0 bad epochs dropped\n", | |
"0 bad epochs dropped\n", | |
"Used Annotations descriptions: ['feet', 'left_hand', 'right_hand', 'tongue']\n", | |
"48 matching events found\n", | |
"No baseline correction applied\n", | |
"Adding metadata with 4 columns\n", | |
"0 projection items activated\n", | |
"Loading data for 48 events and 1125 original time points ...\n", | |
"0 bad epochs dropped\n", | |
"0 bad epochs dropped\n", | |
"Used Annotations descriptions: ['feet', 'left_hand', 'right_hand', 'tongue']\n", | |
"48 matching events found\n", | |
"No baseline correction applied\n", | |
"Adding metadata with 4 columns\n", | |
"0 projection items activated\n", | |
"Loading data for 48 events and 1125 original time points ...\n", | |
"0 bad epochs dropped\n", | |
"0 bad epochs dropped\n", | |
"Used Annotations descriptions: ['feet', 'left_hand', 'right_hand', 'tongue']\n", | |
"48 matching events found\n", | |
"No baseline correction applied\n", | |
"Adding metadata with 4 columns\n", | |
"0 projection items activated\n", | |
"Loading data for 48 events and 1125 original time points ...\n", | |
"0 bad epochs dropped\n", | |
"0 bad epochs dropped\n", | |
"Used Annotations descriptions: ['feet', 'left_hand', 'right_hand', 'tongue']\n", | |
"48 matching events found\n", | |
"No baseline correction applied\n", | |
"Adding metadata with 4 columns\n", | |
"0 projection items activated\n", | |
"Loading data for 48 events and 1125 original time points ...\n", | |
"0 bad epochs dropped\n", | |
"0 bad epochs dropped\n", | |
"Used Annotations descriptions: ['feet', 'left_hand', 'right_hand', 'tongue']\n", | |
"48 matching events found\n", | |
"No baseline correction applied\n", | |
"Adding metadata with 4 columns\n", | |
"0 projection items activated\n", | |
"Loading data for 48 events and 1125 original time points ...\n", | |
"0 bad epochs dropped\n", | |
"0 bad epochs dropped\n", | |
"Used Annotations descriptions: ['feet', 'left_hand', 'right_hand', 'tongue']\n", | |
"48 matching events found\n", | |
"No baseline correction applied\n", | |
"Adding metadata with 4 columns\n", | |
"0 projection items activated\n", | |
"Loading data for 48 events and 1125 original time points ...\n", | |
"0 bad epochs dropped\n", | |
"0 bad epochs dropped\n", | |
"Used Annotations descriptions: ['feet', 'left_hand', 'right_hand', 'tongue']\n", | |
"48 matching events found\n", | |
"No baseline correction applied\n", | |
"Adding metadata with 4 columns\n", | |
"0 projection items activated\n", | |
"Loading data for 48 events and 1125 original time points ...\n", | |
"0 bad epochs dropped\n", | |
"0 bad epochs dropped\n", | |
" epoch train_accuracy train_loss valid_accuracy valid_loss dur\n", | |
"------- ---------------- ------------ ---------------- ------------ ------\n", | |
" 1 \u001b[36m0.2500\u001b[0m \u001b[32m1.5919\u001b[0m \u001b[35m0.2500\u001b[0m \u001b[31m6.2938\u001b[0m 1.0413\n", | |
" 2 0.2500 \u001b[32m1.1950\u001b[0m 0.2500 7.2211 0.2248\n", | |
" 3 0.2500 \u001b[32m1.0809\u001b[0m 0.2500 \u001b[31m5.8693\u001b[0m 0.2272\n", | |
" 4 \u001b[36m0.2569\u001b[0m \u001b[32m1.0008\u001b[0m \u001b[35m0.2535\u001b[0m \u001b[31m4.5076\u001b[0m 0.2266\n" | |
] | |
} | |
], | |
"source": [ | |
"pipe = pipe.fit(dataset, classifier__epochs=n_epochs)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 9, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"image/png": "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\n", | |
"text/plain": [ | |
"<Figure size 576x216 with 2 Axes>" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"import matplotlib.pyplot as plt\n", | |
"from matplotlib.lines import Line2D\n", | |
"import pandas as pd\n", | |
"\n", | |
"# Extract loss and accuracy values for plotting from history object\n", | |
"results_columns = ['train_loss', 'valid_loss', 'train_accuracy', 'valid_accuracy']\n", | |
"df = pd.DataFrame(pipe.steps[-1][1].history[:, results_columns], columns=results_columns,\n", | |
" index=pipe.steps[-1][1].history[:, 'epoch'])\n", | |
"\n", | |
"# get percent of misclass for better visual comparison to loss\n", | |
"df = df.assign(train_misclass=100 - 100 * df.train_accuracy,\n", | |
" valid_misclass=100 - 100 * df.valid_accuracy)\n", | |
"\n", | |
"plt.style.use('seaborn')\n", | |
"fig, ax1 = plt.subplots(figsize=(8, 3))\n", | |
"df.loc[:, ['train_loss', 'valid_loss']].plot(\n", | |
" ax=ax1, style=['-', ':'], marker='o', color='tab:blue', legend=False, fontsize=14)\n", | |
"\n", | |
"ax1.tick_params(axis='y', labelcolor='tab:blue', labelsize=14)\n", | |
"ax1.set_ylabel(\"Loss\", color='tab:blue', fontsize=14)\n", | |
"\n", | |
"ax2 = ax1.twinx() # instantiate a second axes that shares the same x-axis\n", | |
"\n", | |
"df.loc[:, ['train_misclass', 'valid_misclass']].plot(\n", | |
" ax=ax2, style=['-', ':'], marker='o', color='tab:red', legend=False)\n", | |
"ax2.tick_params(axis='y', labelcolor='tab:red', labelsize=14)\n", | |
"ax2.set_ylabel(\"Misclassification Rate [%]\", color='tab:red', fontsize=14)\n", | |
"ax2.set_ylim(ax2.get_ylim()[0], 85) # make some room for legend\n", | |
"ax1.set_xlabel(\"Epoch\", fontsize=14)\n", | |
"\n", | |
"# where some data has already been plotted to ax\n", | |
"handles = []\n", | |
"handles.append(Line2D([0], [0], color='black', linewidth=1, linestyle='-', label='Train'))\n", | |
"handles.append(Line2D([0], [0], color='black', linewidth=1, linestyle=':', label='Valid'))\n", | |
"plt.legend(handles, [h.get_label() for h in handles], fontsize=14)\n", | |
"plt.tight_layout()" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"display_name": "new_braindecode", | |
"language": "python", | |
"name": "new_braindecode" | |
}, | |
"language_info": { | |
"codemirror_mode": { | |
"name": "ipython", | |
"version": 3 | |
}, | |
"file_extension": ".py", | |
"mimetype": "text/x-python", | |
"name": "python", | |
"nbconvert_exporter": "python", | |
"pygments_lexer": "ipython3", | |
"version": "3.7.6" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 2 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment