Arquivos
braindecode/docs/notebooks/BBCI_Data_Trialwise.ipynb
T
Robin Tibor Schirrmeister b0f186e3e0 some change to notebookdocs
2018-08-27 14:21:22 +02:00

355 linhas
9.6 KiB
Plaintext

{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true,
"nbsphinx": "hidden"
},
"outputs": [],
"source": [
"%load_ext autoreload\n",
"%autoreload 2\n",
"import os\n",
"os.sys.path.insert(0, '/home/schirrmr/braindecode/code/braindecode/')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Read and Decode BBCI Data"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This tutorial shows how to read and decode BBCI data."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Setup logging to see outputs"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"import logging\n",
"import sys\n",
"logging.basicConfig(format='%(asctime)s %(levelname)s : %(message)s',\n",
" level=logging.DEBUG, stream=sys.stdout)\n",
"log = logging.getLogger()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Load and preprocess data"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"First set the filename and the sensors you want to load. If you set\n",
"\n",
"```python\n",
"load_sensor_names=None\n",
"```\n",
"\n",
"or just remove the parameter from the function call, all sensors will be loaded."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from braindecode.datasets.bbci import BBCIDataset\n",
"train_filename = '/home/schirrmr/data/BBCI-without-last-runs/BhNoMoSc1S001R01_ds10_1-12.BBCI.mat'\n",
"cnt = BBCIDataset(train_filename, load_sensor_names=['C3', 'CPz', 'C4']).load()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Preprocessing on continous data"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"First remove the stimulus channel, than apply any preprocessing you like. There are some very few directions available from Braindecode, such as resample_cnt. But you can apply any function on the chan x time matrix of the mne raw object (`cnt` in the code) by calling `mne_apply` with two arguments:\n",
"\n",
"1. Your function (2d-array-> 2darray), that transforms the channel x timesteps data array\n",
"2. the Raw data object from mne itself"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from braindecode.mne_ext.signalproc import resample_cnt, mne_apply\n",
"from braindecode.datautil.signalproc import exponential_running_standardize\n",
"# Remove stimulus channel\n",
"cnt = cnt.drop_channels(['STI 014'])\n",
"cnt = resample_cnt(cnt, 250)\n",
"# mne apply will apply the function to the data (a 2d-numpy-array)\n",
"# have to transpose data back and forth, since\n",
"# exponential_running_standardize expects time x chans order\n",
"# while mne object has chans x time order\n",
"cnt = mne_apply(lambda a: exponential_running_standardize(\n",
" a.T, init_block_size=1000,factor_new=0.001, eps=1e-4).T,\n",
" cnt)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Transform to epoched dataset "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Braindecode supplies the `create_signal_target_from_raw_mne` function, which will transform the mne raw object into a `SignalAndTarget` object for use in Braindecode.\n",
"`name_to_code` should be an `OrderedDict` that maps class names to either one or a list of marker codes for that class."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from braindecode.datautil.trial_segment import create_signal_target_from_raw_mne\n",
"from collections import OrderedDict\n",
"# can also give lists of marker codes in case a class has multiple marker codes...\n",
"name_to_code = OrderedDict([('Right', 1), ('Left', 2), ('Rest', 3), ('Feet', 4)])\n",
"segment_ival_ms = [-500,4000]\n",
"\n",
"train_set = create_signal_target_from_raw_mne(cnt, name_to_code, segment_ival_ms)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Same for test set"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"scrolled": false
},
"outputs": [],
"source": [
"test_filename = '/home/schirrmr/data/BBCI-only-last-runs/BhNoMoSc1S001R13_ds10_1-2BBCI.mat'\n",
"cnt = BBCIDataset(test_filename, load_sensor_names=['C3', 'CPz', 'C4']).load()\n",
"# Remove stimulus channel\n",
"cnt = cnt.drop_channels(['STI 014'])\n",
"cnt = resample_cnt(cnt, 250)\n",
"cnt = mne_apply(lambda a: exponential_running_standardize(\n",
" a.T, init_block_size=1000,factor_new=0.001, eps=1e-4).T,\n",
" cnt)\n",
"test_set = create_signal_target_from_raw_mne(cnt, name_to_code, segment_ival_ms)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<div class=\"alert alert-info\">\n",
"\n",
"In case of start and stop markers, provide a `name_to_stop_codes` dictionary (same as for the start codes in this example) as a final argument to `create_signal_target_from_raw_mne`. See [Read and Decode BBCI Data with Start-Stop-Markers Tutorial](BBCI_Data_Start_Stop.html)\n",
"\n",
"\n",
"</div>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Split off a validation set."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"from braindecode.datautil.splitters import split_into_two_sets\n",
"\n",
"train_set, valid_set = split_into_two_sets(train_set, first_set_fraction=0.8)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Create the model"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"from braindecode.models.shallow_fbcsp import ShallowFBCSPNet\n",
"from torch import nn\n",
"from braindecode.torch_ext.util import set_random_seeds\n",
"\n",
"# Set if you want to use GPU\n",
"# You can also use torch.cuda.is_available() to determine if cuda is available on your machine.\n",
"cuda = True\n",
"set_random_seeds(seed=20170629, cuda=cuda)\n",
"\n",
"\n",
"# This will determine how many crops are processed in parallel\n",
"input_time_length = train_set.X.shape[2]\n",
"in_chans = 3\n",
"n_classes = 4\n",
"# final_conv_length determines the size of the receptive field of the ConvNet\n",
"model = ShallowFBCSPNet(in_chans=in_chans, n_classes=n_classes, input_time_length=input_time_length,\n",
" final_conv_length='auto').create_network()\n",
"\n",
"if cuda:\n",
" model.cuda()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Setup optimizer and iterator"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"from torch import optim\n",
"import numpy as np\n",
"\n",
"optimizer = optim.Adam(model.parameters())\n",
"\n",
"\n",
"from braindecode.datautil.iterators import BalancedBatchSizeIterator\n",
"iterator = BalancedBatchSizeIterator(batch_size=32)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Setup Monitors, Loss function, Stop Criteria"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"from braindecode.experiments.experiment import Experiment\n",
"from braindecode.experiments.monitors import RuntimeMonitor, LossMonitor, CroppedTrialMisclassMonitor, MisclassMonitor\n",
"from braindecode.experiments.stopcriteria import MaxEpochs\n",
"import torch.nn.functional as F\n",
"import torch as th\n",
"from braindecode.torch_ext.modules import Expression\n",
"\n",
"\n",
"loss_function = F.nll_loss\n",
"\n",
"model_constraint = None\n",
"monitors = [LossMonitor(), MisclassMonitor(col_suffix='misclass'), \n",
" RuntimeMonitor(),]\n",
"stop_criterion = MaxEpochs(20)\n",
"exp = Experiment(model, train_set, valid_set, test_set, iterator, loss_function, optimizer, model_constraint,\n",
" monitors, stop_criterion, remember_best_column='valid_misclass',\n",
" run_after_early_stop=True, batch_modifier=None, cuda=cuda)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Run experiment"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"scrolled": false
},
"outputs": [],
"source": [
"exp.run()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We arrive around 26%, exact value depending on stars :))"
]
}
],
"metadata": {
"celltoolbar": "Edit Metadata",
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"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.6.6"
}
},
"nbformat": 4,
"nbformat_minor": 2
}