def _loadFromFile(self, filename): # TODO: integrate this in saved file parameters somehow #n_filters_time=10 #filter_time_length=75 #n_filters_spat=5 #pool_time_length=60 #pool_time_stride=30 #in_chans = 15 #input_time_length = 3584 # final_conv_length = auto ensures we only get a single output in the time dimension self.model = ShallowFBCSPNet( in_chans=15, n_classes=2, input_time_length=3584, n_filters_time=10, filter_time_length=75, n_filters_spat=5, pool_time_length=60, pool_time_stride=30, final_conv_length='auto').create_network() # setup model for cuda if self.cuda: print("That's the new one") self.model.cuda() # load the saved network (makes it possible to run bottom form same starting point self.model.load_state_dict(torch.load("myModel.pth")) return
def create_shallow_net(in_chans, input_time_length): # receptive field size is determined by model architecture n_classes = 2 # ensure reproducibility by resetting lasagne/theano random generator lasagne.random.set_rng(RandomState(34734)) shallow_net = ShallowFBCSPNet(in_chans, input_time_length, n_classes, n_filters_time=40, filter_time_length=25, n_filters_spat=40, pool_time_length=75, pool_time_stride=15, final_dense_length=30, conv_nonlin=square, pool_mode='average_exc_pad', pool_nonlin=safe_log, split_first_layer=True, batch_norm=True, batch_norm_alpha=0.1, drop_prob=0.5) final_layer = shallow_net.get_layers()[-1] final_layer = ClipLayer(final_layer, 1e-4, 1 - 1e-4) return final_layer
def __init__(self, in_chans, n_classes, input_time_length): super(HybridNetModule, self).__init__() deep_model = Deep4Net( in_chans, n_classes, n_filters_time=20, n_filters_spat=30, n_filters_2=40, n_filters_3=50, n_filters_4=60, input_time_length=input_time_length, final_conv_length=2, ).create_network() shallow_model = ShallowFBCSPNet( in_chans, n_classes, input_time_length=input_time_length, n_filters_time=30, n_filters_spat=40, filter_time_length=28, final_conv_length=29, ).create_network() reduced_deep_model = nn.Sequential() for name, module in deep_model.named_children(): if name == "conv_classifier": new_conv_layer = nn.Conv2d( module.in_channels, 60, kernel_size=module.kernel_size, stride=module.stride, ) reduced_deep_model.add_module("deep_final_conv", new_conv_layer) break reduced_deep_model.add_module(name, module) reduced_shallow_model = nn.Sequential() for name, module in shallow_model.named_children(): if name == "conv_classifier": new_conv_layer = nn.Conv2d( module.in_channels, 40, kernel_size=module.kernel_size, stride=module.stride, ) reduced_shallow_model.add_module("shallow_final_conv", new_conv_layer) break reduced_shallow_model.add_module(name, module) to_dense_prediction_model(reduced_deep_model) to_dense_prediction_model(reduced_shallow_model) self.reduced_deep_model = reduced_deep_model self.reduced_shallow_model = reduced_shallow_model self.final_conv = nn.Conv2d(100, n_classes, kernel_size=(1, 1), stride=1)
def fit(self, X, y): # define a number of train/test trials nb_train_trials = int(np.floor(7/8*X.shape[0])) # split the dataset self.train_set = SignalAndTarget(X[:nb_train_trials], y=y[:nb_train_trials]) self.test_set = SignalAndTarget(X[nb_train_trials:], y=y[nb_train_trials:]) # number of classes and input channels n_classes = np.unique(y).size in_chans = self.train_set.X.shape[1] # final_conv_length = auto ensures we only get a single output in the time dimension self.model = ShallowFBCSPNet( in_chans=in_chans, n_classes=n_classes, input_time_length=self.train_set.X.shape[2], n_filters_time=self.n_filters_time, filter_time_length=self.filter_time_length, n_filters_spat=self.n_filters_spat, pool_time_length=self.pool_time_length, pool_time_stride=self.pool_time_stride, final_conv_length='auto' ).create_network() # setup model for cuda if self.cuda: self.model.cuda() # setup optimizer self.optimizer = optim.Adam(self.model.parameters()) # array that tracks results self.loss_rec = np.zeros((self.nb_epoch,2)) self.accuracy_rec = np.zeros((self.nb_epoch,2)) # run all epoch for i_epoch in range(self.nb_epoch): self._batchTrain(i_epoch, self.train_set) self._evalTraining(i_epoch, self.train_set, self.test_set) return self
def network_model(model, train_set, test_set, valid_set, n_chans, input_time_length, cuda): max_epochs = 30 max_increase_epochs = 10 batch_size = 64 init_block_size = 1000 set_random_seeds(seed=20190629, cuda=cuda) n_classes = 2 n_chans = n_chans input_time_length = input_time_length if model == 'deep': model = Deep4Net(n_chans, n_classes, input_time_length=input_time_length, final_conv_length='auto').create_network() elif model == 'shallow': model = ShallowFBCSPNet(n_chans, n_classes, input_time_length=input_time_length, final_conv_length='auto').create_network() if cuda: model.cuda() log.info("%s model: ".format(str(model))) optimizer = AdamW(model.parameters(), lr=0.00625, weight_decay=0) iterator = BalancedBatchSizeIterator(batch_size=batch_size) stop_criterion = Or([MaxEpochs(max_epochs), NoDecrease('valid_misclass', max_increase_epochs)]) monitors = [LossMonitor(), MisclassMonitor(), RuntimeMonitor()] model_constraint = None print(train_set.X.shape[0]) model_test = Experiment(model, train_set, valid_set, test_set, iterator=iterator, loss_function=F.nll_loss, optimizer=optimizer, model_constraint=model_constraint, monitors=monitors, stop_criterion=stop_criterion, remember_best_column='valid_misclass', run_after_early_stop=True, cuda=cuda) model_test.run() return model_test
def create_model(n_classes, input_time_length, in_chans=22): set_random_seeds(seed=20170629, cuda=cuda) # This will determine how many crops are processed in parallel # final_conv_length determines the size of the receptive field of the ConvNet model = ShallowFBCSPNet(in_chans=in_chans, n_classes=n_classes, input_time_length=input_time_length, final_conv_length=4, pool_time_length=20, pool_time_stride=5).create_network() to_dense_prediction_model(model) if cuda: model.cuda() return model
def __init__(self, targets=4, filters=40, channels=22, samples=1500, subjects=1, runs=None, **kwargs): super().__init__() self.base_model = ShallowFBCSPNet( channels, targets, samples, final_conv_length='auto').create_network()
def _loadFromFile(self, filename): # TODO: integrate this in saved file parameters somehow n_filters_time = 10 filter_time_length = 75 n_filters_spat = 5 pool_time_length = 60 pool_time_stride = 30 # final_conv_length = auto ensures we only get a single output in the time dimension self.model = ShallowFBCSPNet( in_chans=in_chans, n_classes=n_classes, input_time_length=train_set.X.shape[2], n_filters_time=n_filters_time, filter_time_length=filter_time_length, n_filters_spat=n_filters_spat, pool_time_length=pool_time_length, pool_time_stride=pool_time_stride, final_conv_length='auto').create_network() # load the saved network (makes it possible to run bottom form same starting point self.model.load_state_dict(torch.load("myModel.pth")) return
def create_shallow_model(in_chans, input_time_length, final_dense_length, n_classes): shallow_net = ShallowFBCSPNet(in_chans, input_time_length, n_classes, n_filters_time=40, filter_time_length=25, n_filters_spat=40, pool_time_length=75, pool_time_stride=15, final_dense_length=final_dense_length, conv_nonlin=square, pool_mode='average_exc_pad', pool_nonlin=safe_log, split_first_layer=True, batch_norm=True, batch_norm_alpha=0.1, drop_prob=0.5) return shallow_net
def build_cropped_model(model_name, n_chans, n_classes, config): # input_time_length: # will determine how many crops are processed in parallel # supercrop, number of crops taken through network together # final_conv_length: # will determine how many crops are processed in parallel # we manually set the length of the final convolution layer # to some length that makes the receptive field of the # ConvNet smaller than the number of samples in a trial cropped_input_time_length = config['cropped']['input_time_length'] final_conv_length_shallow = config['cropped']['final_conv_length_shallow'] final_conv_length_deep = config['cropped']['final_conv_length_deep'] if model_name == 'shallow': model = ShallowFBCSPNet(n_chans, n_classes, input_time_length=cropped_input_time_length, final_conv_length=final_conv_length_shallow) \ .create_network() elif model_name == 'deep': model = Deep4Net(n_chans, n_classes, input_time_length=cropped_input_time_length, final_conv_length=final_conv_length_deep) \ .create_network() to_dense_prediction_model(model) return model
def test_cropped_decoding(): import mne from mne.io import concatenate_raws # 5,6,7,10,13,14 are codes for executed and imagined hands/feet subject_id = 1 event_codes = [5, 6, 9, 10, 13, 14] # This will download the files if you don't have them yet, # and then return the paths to the files. physionet_paths = mne.datasets.eegbci.load_data(subject_id, event_codes) # Load each of the files parts = [mne.io.read_raw_edf(path, preload=True, stim_channel='auto', verbose='WARNING') for path in physionet_paths] # Concatenate them raw = concatenate_raws(parts) # Find the events in this dataset events = mne.find_events(raw, shortest_event=0, stim_channel='STI 014') # Use only EEG channels eeg_channel_inds = mne.pick_types(raw.info, meg=False, eeg=True, stim=False, eog=False, exclude='bads') # Extract trials, only using EEG channels epoched = mne.Epochs(raw, events, dict(hands=2, feet=3), tmin=1, tmax=4.1, proj=False, picks=eeg_channel_inds, baseline=None, preload=True) import numpy as np from braindecode.datautil.signal_target import SignalAndTarget # Convert data from volt to millivolt # Pytorch expects float32 for input and int64 for labels. X = (epoched.get_data() * 1e6).astype(np.float32) y = (epoched.events[:, 2] - 2).astype(np.int64) # 2,3 -> 0,1 train_set = SignalAndTarget(X[:60], y=y[:60]) test_set = SignalAndTarget(X[60:], y=y[60:]) from braindecode.models.shallow_fbcsp import ShallowFBCSPNet from torch import nn from braindecode.torch_ext.util import set_random_seeds from braindecode.models.util import to_dense_prediction_model # Set if you want to use GPU # You can also use torch.cuda.is_available() to determine if cuda is available on your machine. cuda = False set_random_seeds(seed=20170629, cuda=cuda) # This will determine how many crops are processed in parallel input_time_length = 450 n_classes = 2 in_chans = train_set.X.shape[1] # final_conv_length determines the size of the receptive field of the ConvNet model = ShallowFBCSPNet(in_chans=in_chans, n_classes=n_classes, input_time_length=input_time_length, final_conv_length=12).create_network() to_dense_prediction_model(model) if cuda: model.cuda() from torch import optim optimizer = optim.Adam(model.parameters()) from braindecode.torch_ext.util import np_to_var # determine output size test_input = np_to_var( np.ones((2, in_chans, input_time_length, 1), dtype=np.float32)) if cuda: test_input = test_input.cuda() out = model(test_input) n_preds_per_input = out.cpu().data.numpy().shape[2] print("{:d} predictions per input/trial".format(n_preds_per_input)) from braindecode.datautil.iterators import CropsFromTrialsIterator iterator = CropsFromTrialsIterator(batch_size=32, input_time_length=input_time_length, n_preds_per_input=n_preds_per_input) from braindecode.torch_ext.util import np_to_var, var_to_np import torch.nn.functional as F from numpy.random import RandomState import torch as th from braindecode.experiments.monitors import compute_preds_per_trial_from_crops rng = RandomState((2017, 6, 30)) losses = [] accuracies = [] for i_epoch in range(4): # Set model to training mode model.train() for batch_X, batch_y in iterator.get_batches(train_set, shuffle=False): net_in = np_to_var(batch_X) if cuda: net_in = net_in.cuda() net_target = np_to_var(batch_y) if cuda: net_target = net_target.cuda() # Remove gradients of last backward pass from all parameters optimizer.zero_grad() outputs = model(net_in) # Mean predictions across trial # Note that this will give identical gradients to computing # a per-prediction loss (at least for the combination of log softmax activation # and negative log likelihood loss which we are using here) outputs = th.mean(outputs, dim=2, keepdim=False) loss = F.nll_loss(outputs, net_target) loss.backward() optimizer.step() # Print some statistics each epoch model.eval() print("Epoch {:d}".format(i_epoch)) for setname, dataset in (('Train', train_set), ('Test', test_set)): # Collect all predictions and losses all_preds = [] all_losses = [] batch_sizes = [] for batch_X, batch_y in iterator.get_batches(dataset, shuffle=False): net_in = np_to_var(batch_X) if cuda: net_in = net_in.cuda() net_target = np_to_var(batch_y) if cuda: net_target = net_target.cuda() outputs = model(net_in) all_preds.append(var_to_np(outputs)) outputs = th.mean(outputs, dim=2, keepdim=False) loss = F.nll_loss(outputs, net_target) loss = float(var_to_np(loss)) all_losses.append(loss) batch_sizes.append(len(batch_X)) # Compute mean per-input loss loss = np.mean(np.array(all_losses) * np.array(batch_sizes) / np.mean(batch_sizes)) print("{:6s} Loss: {:.5f}".format(setname, loss)) losses.append(loss) # Assign the predictions to the trials preds_per_trial = compute_preds_per_trial_from_crops(all_preds, input_time_length, dataset.X) # preds per trial are now trials x classes x timesteps/predictions # Now mean across timesteps for each trial to get per-trial predictions meaned_preds_per_trial = np.array( [np.mean(p, axis=1) for p in preds_per_trial]) predicted_labels = np.argmax(meaned_preds_per_trial, axis=1) accuracy = np.mean(predicted_labels == dataset.y) accuracies.append(accuracy * 100) print("{:6s} Accuracy: {:.1f}%".format( setname, accuracy * 100)) np.testing.assert_allclose( np.array(losses), np.array([1.703004002571106, 1.6295261979103088, 0.71168938279151917, 0.70825588703155518, 0.58231228590011597, 0.60176041722297668, 0.46629951894283295, 0.51184913516044617]), rtol=1e-4, atol=1e-5) np.testing.assert_allclose( np.array(accuracies), np.array( [50.0, 46.666666666666664, 60.0, 53.333333333333336, 68.333333333333329, 66.666666666666657, 88.333333333333329, 83.333333333333343]), rtol=1e-4, atol=1e-5)
test_X = test_X.astype(np.float32) in_chan = db.signal_shape()[0] time_steps = db.signal_shape()[1] from braindecode.datautil.signal_target import SignalAndTarget train_set = SignalAndTarget(train_X, y=train_y) valid_set = SignalAndTarget(valid_X, y=valid_y) test_set = SignalAndTarget(test_X, y=valid_y) cuda = True batch_size = 60 max_epochs = 20000 max_increase_epochs = 360 model = ShallowFBCSPNet(in_chan, db.n_classes, input_time_length=time_steps, final_conv_length="auto").create_network() log.info("Model: \n{:s}".format(str(model))) optimizer = optim.Adam(model.parameters()) iterator = BalancedBatchSizeIterator(batch_size=batch_size) stop_criterion = Or([ MaxEpochs(max_epochs), NoDecrease("valid_misclass", max_increase_epochs), ]) monitors = [LossMonitor(), MisclassMonitor(), RuntimeMonitor()] model_constraint = MaxNormDefaultConstraint()
def run_exp(epoches, batch_size, subject_num, model_type, cuda, single_subject, single_subject_num): # ival = [-500, 4000] max_increase_epochs = 160 # Preprocessing X, y = loadSubjects(subject_num, single_subject, single_subject_num) X = X.astype(np.float32) y = y.astype(np.int64) X, y = shuffle(X, y) trial_length = X.shape[2] print("trial_length " + str(trial_length)) print("trying to run with {} sec trials ".format((trial_length - 1) / 256)) print("y") print(y) trainingSampleSize = int(len(X) * 0.6) valudationSampleSize = int(len(X) * 0.2) testSampleSize = int(len(X) * 0.2) print("INFO : Training sample size: {}".format(trainingSampleSize)) print("INFO : Validation sample size: {}".format(valudationSampleSize)) print("INFO : Test sample size: {}".format(testSampleSize)) train_set = SignalAndTarget(X[:trainingSampleSize], y=y[:trainingSampleSize]) valid_set = SignalAndTarget( X[trainingSampleSize:(trainingSampleSize + valudationSampleSize)], y=y[trainingSampleSize:(trainingSampleSize + valudationSampleSize)]) test_set = SignalAndTarget(X[(trainingSampleSize + valudationSampleSize):], y=y[(trainingSampleSize + valudationSampleSize):]) set_random_seeds(seed=20190706, cuda=cuda) n_classes = 3 n_chans = int(train_set.X.shape[1]) input_time_length = train_set.X.shape[2] if model_type == 'shallow': model = ShallowFBCSPNet(n_chans, n_classes, input_time_length=input_time_length, final_conv_length='auto').create_network() elif model_type == 'deep': model = Deep4Net(n_chans, n_classes, input_time_length=input_time_length, final_conv_length='auto').create_network() elif model_type == 'eegnet': model = EEGNetv4(n_chans, n_classes, input_time_length=input_time_length, final_conv_length='auto').create_network() if cuda: model.cuda() log.info("Model: \n{:s}".format(str(model))) optimizer = optim.Adam(model.parameters()) iterator = BalancedBatchSizeIterator(batch_size=batch_size) stop_criterion = Or([ MaxEpochs(max_epochs), NoDecrease('valid_misclass', max_increase_epochs) ]) monitors = [LossMonitor(), MisclassMonitor(), RuntimeMonitor()] model_constraint = MaxNormDefaultConstraint() exp = Experiment(model, train_set, valid_set, test_set, iterator=iterator, loss_function=F.nll_loss, optimizer=optimizer, model_constraint=model_constraint, monitors=monitors, stop_criterion=stop_criterion, remember_best_column='valid_misclass', run_after_early_stop=True, cuda=cuda) exp.run() # th.save(model, "models\{}-cropped-singleSubjectNum{}-{}sec-{}epoches-torch_model".format(model_type, single_subject_num, ((trial_length - 1) / 256), epoches)) return exp
def runModel(mode): cudnn.benchmark = True start = time.time() #mode = str(sys.argv[1]) #X,y,test_X,test_y = loadSubNormData(mode='all') #X,y,test_X,test_y = loadNEDCdata(mode=mode) #data = np.load('sessionsData/data%s-sessions.npy'%mode[:3]) #labels = np.load('sessionsData/labels%s-sessions.npy'%mode[:3]) data = np.load('data%s.npy' % mode[:3]) labels = np.load('labels%s.npy' % mode[:3]) X, y, test_X, test_y = splitDataRandom_Loaded(data, labels, mode) print('Mode - %s Total n: %d, Test n: %d' % (mode, len(y) + len(test_y), len(test_y))) #return 0 #X = addDataNoise(X,band=[1,4]) #test_X = addDataNoise(test_X,band=[1,4]) max_shape = np.max([list(x.shape) for x in X], axis=0) assert max_shape[1] == int(config.duration_recording_mins * config.sampling_freq * 60) n_classes = 2 n_recordings = None # set to an integer, if you want to restrict the set size sensor_types = ["EEG"] n_chans = 19 #21 max_recording_mins = 35 # exclude larger recordings from training set sec_to_cut = 60 # cut away at start of each recording duration_recording_mins = 5 #20 # how many minutes to use per recording test_recording_mins = 5 #20 max_abs_val = 800 # for clipping sampling_freq = 100 divisor = 10 # divide signal by this test_on_eval = True # teston evaluation set or on training set # in case of test on eval, n_folds and i_testfold determine # validation fold in training set for training until first stop n_folds = 10 i_test_fold = 9 shuffle = True model_name = 'linear' #'deep'#'shallow' 'linear' n_start_chans = 25 n_chan_factor = 2 # relevant for deep model only input_time_length = 6000 final_conv_length = 1 model_constraint = 'defaultnorm' init_lr = 1e-3 batch_size = 64 max_epochs = 35 # until first stop, the continue train on train+valid cuda = True # False if model_name == 'shallow': model = ShallowFBCSPNet( in_chans=n_chans, n_classes=n_classes, n_filters_time=n_start_chans, n_filters_spat=n_start_chans, input_time_length=input_time_length, final_conv_length=final_conv_length).create_network() elif model_name == 'deep': model = Deep4Net(n_chans, n_classes, n_filters_time=n_start_chans, n_filters_spat=n_start_chans, input_time_length=input_time_length, n_filters_2=int(n_start_chans * n_chan_factor), n_filters_3=int(n_start_chans * (n_chan_factor**2.0)), n_filters_4=int(n_start_chans * (n_chan_factor**3.0)), final_conv_length=final_conv_length, stride_before_pool=True).create_network() elif (model_name == 'deep_smac'): if model_name == 'deep_smac': do_batch_norm = False else: assert model_name == 'deep_smac_bnorm' do_batch_norm = True double_time_convs = False drop_prob = 0.244445 filter_length_2 = 12 filter_length_3 = 14 filter_length_4 = 12 filter_time_length = 21 final_conv_length = 1 first_nonlin = elu first_pool_mode = 'mean' first_pool_nonlin = identity later_nonlin = elu later_pool_mode = 'mean' later_pool_nonlin = identity n_filters_factor = 1.679066 n_filters_start = 32 pool_time_length = 1 pool_time_stride = 2 split_first_layer = True n_chan_factor = n_filters_factor n_start_chans = n_filters_start model = Deep4Net(n_chans, n_classes, n_filters_time=n_start_chans, n_filters_spat=n_start_chans, input_time_length=input_time_length, n_filters_2=int(n_start_chans * n_chan_factor), n_filters_3=int(n_start_chans * (n_chan_factor**2.0)), n_filters_4=int(n_start_chans * (n_chan_factor**3.0)), final_conv_length=final_conv_length, batch_norm=do_batch_norm, double_time_convs=double_time_convs, drop_prob=drop_prob, filter_length_2=filter_length_2, filter_length_3=filter_length_3, filter_length_4=filter_length_4, filter_time_length=filter_time_length, first_nonlin=first_nonlin, first_pool_mode=first_pool_mode, first_pool_nonlin=first_pool_nonlin, later_nonlin=later_nonlin, later_pool_mode=later_pool_mode, later_pool_nonlin=later_pool_nonlin, pool_time_length=pool_time_length, pool_time_stride=pool_time_stride, split_first_layer=split_first_layer, stride_before_pool=True).create_network() elif model_name == 'shallow_smac': conv_nonlin = identity do_batch_norm = True drop_prob = 0.328794 filter_time_length = 56 final_conv_length = 22 n_filters_spat = 73 n_filters_time = 24 pool_mode = 'max' pool_nonlin = identity pool_time_length = 84 pool_time_stride = 3 split_first_layer = True model = ShallowFBCSPNet( in_chans=n_chans, n_classes=n_classes, n_filters_time=n_filters_time, n_filters_spat=n_filters_spat, input_time_length=input_time_length, final_conv_length=final_conv_length, conv_nonlin=conv_nonlin, batch_norm=do_batch_norm, drop_prob=drop_prob, filter_time_length=filter_time_length, pool_mode=pool_mode, pool_nonlin=pool_nonlin, pool_time_length=pool_time_length, pool_time_stride=pool_time_stride, split_first_layer=split_first_layer, ).create_network() elif model_name == 'linear': model = nn.Sequential() model.add_module("conv_classifier", nn.Conv2d(n_chans, n_classes, (600, 1))) model.add_module('softmax', nn.LogSoftmax(dim=1)) model.add_module('squeeze', Expression(lambda x: x.squeeze(3))) else: assert False, "unknown model name {:s}".format(model_name) to_dense_prediction_model(model) if config.cuda: model.cuda() test_input = np_to_var( np.ones((2, config.n_chans, config.input_time_length, 1), dtype=np.float32)) if config.cuda: test_input = test_input.cuda() out = model(test_input) n_preds_per_input = out.cpu().data.numpy().shape[2] iterator = CropsFromTrialsIterator( batch_size=config.batch_size, input_time_length=config.input_time_length, n_preds_per_input=n_preds_per_input) #model.add_module('softmax', nn.LogSoftmax(dim=1)) model.eval() mode[2] = str(mode[2]) mode[3] = str(mode[3]) modelName = '-'.join(mode[:4]) #params = th.load('sessionsData/%sModel%s-sessions.pt'%(modelName,mode[4])) #params = th.load('%sModel%s.pt'%(modelName,mode[4])) params = th.load('linear/%sModel%s.pt' % (modelName, mode[4])) model.load_state_dict(params) if config.test_on_eval: #test_X, test_y = test_dataset.load() #test_X, test_y = loadNEDCdata(mode='eval') max_shape = np.max([list(x.shape) for x in test_X], axis=0) assert max_shape[1] == int(config.test_recording_mins * config.sampling_freq * 60) if not config.test_on_eval: splitter = TrainValidTestSplitter(config.n_folds, config.i_test_fold, shuffle=config.shuffle) train_set, valid_set, test_set = splitter.split(X, y) else: splitter = TrainValidSplitter(config.n_folds, i_valid_fold=config.i_test_fold, shuffle=config.shuffle) train_set, valid_set = splitter.split(X, y) test_set = SignalAndTarget(test_X, test_y) del test_X, test_y del X, y # shouldn't be necessary, but just to make sure datasets = OrderedDict( (('train', train_set), ('valid', valid_set), ('test', test_set))) for setname in ('train', 'valid', 'test'): #setname = 'test' #print("Compute predictions for {:s}...".format(setname)) dataset = datasets[setname] if config.cuda: preds_per_batch = [ var_to_np(model(np_to_var(b[0]).cuda())) for b in iterator.get_batches(dataset, shuffle=False) ] else: preds_per_batch = [ var_to_np(model(np_to_var(b[0]))) for b in iterator.get_batches(dataset, shuffle=False) ] preds_per_trial = compute_preds_per_trial( preds_per_batch, dataset, input_time_length=iterator.input_time_length, n_stride=iterator.n_preds_per_input) mean_preds_per_trial = [ np.mean(preds, axis=(0, 2)) for preds in preds_per_trial ] mean_preds_per_trial = np.array(mean_preds_per_trial) all_pred_labels = np.argmax(mean_preds_per_trial, axis=1).squeeze() all_target_labels = dataset.y acc_per_class = [] for i_class in range(n_classes): mask = all_target_labels == i_class acc = np.mean(all_pred_labels[mask] == all_target_labels[mask]) acc_per_class.append(acc) misclass = 1 - np.mean(acc_per_class) #print('Acc:{}, Class 0:{}, Class 1:{}'.format(np.mean(acc_per_class),acc_per_class[0],acc_per_class[1])) if setname == 'test': testResult = np.mean(acc_per_class) return testResult
class ShallowFBCSPNet_GeneralTrainer(BaseEstimator, ClassifierMixin): """ Initialize the parameters of the network Full list of parameters described in ref: https://robintibor.github.io/braindecode/source/braindecode.models.html """ def __init__(self, n_filters_time=10, filter_time_length=75, n_filters_spat=5, pool_time_length=60, pool_time_stride=30, nb_epoch=160): # init meta info self.cuda = torch.cuda.is_available() #set_random_seeds(seed=20180505, cuda=self.cuda) # TODO: Fix random seed set_random_seeds(seed=randint(1, 20180505), cuda=self.cuda) # TODO: Fix random seed # copy all network parameters self.n_filters_time = n_filters_time self.filter_time_length = filter_time_length self.n_filters_spat = n_filters_spat self.pool_time_length = pool_time_length self.pool_time_stride = pool_time_stride self.nb_epoch = nb_epoch return """ Fit the network Params: X, data array in the format (...) y, labels ref: http://danielhnyk.cz/creating-your-own-estimator-scikit-learn/ """ def fit(self, X, y): # define a number of train/test trials nb_train_trials = int(np.floor(7 / 8 * X.shape[0])) # split the dataset train_set = SignalAndTarget(X[:nb_train_trials], y=y[:nb_train_trials]) test_set = SignalAndTarget(X[nb_train_trials:], y=y[nb_train_trials:]) # number of classes and input channels n_classes = np.unique(y).size in_chans = train_set.X.shape[1] # final_conv_length = auto ensures we only get a single output in the time dimension self.model = ShallowFBCSPNet( in_chans=in_chans, n_classes=n_classes, input_time_length=train_set.X.shape[2], n_filters_time=self.n_filters_time, filter_time_length=self.filter_time_length, n_filters_spat=self.n_filters_spat, pool_time_length=self.pool_time_length, pool_time_stride=self.pool_time_stride, final_conv_length='auto').create_network() # setup model for cuda if self.cuda: self.model.cuda() # setup optimizer self.optimizer = optim.Adam(self.model.parameters()) # random generator self.rng = RandomState(None) # array that tracks results self.loss_rec = np.zeros((self.nb_epoch, 2)) self.accuracy_rec = np.zeros((self.nb_epoch, 2)) # run all epoch for i_epoch in range(self.nb_epoch): self._batchTrain(i_epoch, train_set) self._evalTraining(i_epoch, train_set, test_set) return self """ Training iteration, train the network on the train_set Params: i_epoch, current epoch iteration train_set, training set """ def _batchTrain(self, i_epoch, train_set): # get a set of balanced batches i_trials_in_batch = get_balanced_batches(len(train_set.X), self.rng, shuffle=True, batch_size=32) # Set model to training mode self.model.train() # go through all batches for i_trials in i_trials_in_batch: # Have to add empty fourth dimension to X batch_X = train_set.X[i_trials][:, :, :, None] batch_y = train_set.y[i_trials] net_in = np_to_var(batch_X) net_target = np_to_var(batch_y) # if cuda, copy to cuda memory if self.cuda: net_in = net_in.cuda() net_target = net_target.cuda() # Remove gradients of last backward pass from all parameters self.optimizer.zero_grad() # Compute outputs of the network outputs = self.model(net_in) # Compute the loss loss = F.nll_loss(outputs, net_target) # Do the backpropagation loss.backward() # Update parameters with the optimizer self.optimizer.step() return """ Evaluation iteration, computes the performance the network Params: i_epoch, current epoch iteration train_set, training set """ def _evalTraining(self, i_epoch, train_set, test_set): # Print some statistics each epoch self.model.eval() print("Epoch {:d}".format(i_epoch)) sets = {'Train': 0, 'Test': 1} # run evaluation on both train and test sets for setname, dataset in (('Train', train_set), ('Test', test_set)): # get balanced sets i_trials_in_batch = get_balanced_batches(len(dataset.X), self.rng, batch_size=32, shuffle=False) outputs = [] net_targets = [] # for all trials in set for i_trials in i_trials_in_batch: # adapt datasets batch_X = dataset.X[i_trials][:, :, :, None] batch_y = dataset.y[i_trials] # apply some conversion net_in = np_to_var(batch_X) net_target = np_to_var(batch_y) # convert if self.cuda: net_in = net_in.cuda() net_target = net_target.cuda() net_target = var_to_np(net_target) output = var_to_np(self.model(net_in)) outputs.append(output) net_targets.append(net_target) net_targets = np_to_var(np.concatenate(net_targets)) outputs = np_to_var(np.concatenate(outputs)) loss = F.nll_loss(outputs, net_targets) print("{:6s} Loss: {:.5f}".format(setname, float(var_to_np(loss)))) self.loss_rec[i_epoch, sets[setname]] = var_to_np(loss) predicted_labels = np.argmax(var_to_np(outputs), axis=1) accuracy = np.mean(dataset.y == predicted_labels) print("{:6s} Accuracy: {:.1f}%".format(setname, accuracy * 100)) self.accuracy_rec[i_epoch, sets[setname]] = accuracy return def predict(self, X): self.model.eval() #i_trials_in_batch = get_balanced_batches(len(X), self.rng, batch_size=32, shuffle=False) outputs = [] for i_trials in i_trials_in_batch: batch_X = dataset.X[i_trials][:, :, :, None] net_in = np_to_var(batch_X) if self.cuda: net_in = net_in.cuda() output = var_to_np(self.model(net_in)) outputs.append(output) return outputs
def test_trialwise_decoding(): import mne from mne.io import concatenate_raws # 5,6,7,10,13,14 are codes for executed and imagined hands/feet subject_id = 1 event_codes = [5, 6, 9, 10, 13, 14] # This will download the files if you don't have them yet, # and then return the paths to the files. physionet_paths = mne.datasets.eegbci.load_data(subject_id, event_codes) # Load each of the files parts = [ mne.io.read_raw_edf(path, preload=True, stim_channel='auto', verbose='WARNING') for path in physionet_paths ] # Concatenate them raw = concatenate_raws(parts) # Find the events in this dataset events = mne.find_events(raw, shortest_event=0, stim_channel='STI 014') # Use only EEG channels eeg_channel_inds = mne.pick_types(raw.info, meg=False, eeg=True, stim=False, eog=False, exclude='bads') # Extract trials, only using EEG channels epoched = mne.Epochs(raw, events, dict(hands=2, feet=3), tmin=1, tmax=4.1, proj=False, picks=eeg_channel_inds, baseline=None, preload=True) import numpy as np # Convert data from volt to millivolt # Pytorch expects float32 for input and int64 for labels. X = (epoched.get_data() * 1e6).astype(np.float32) y = (epoched.events[:, 2] - 2).astype(np.int64) # 2,3 -> 0,1 from braindecode.datautil.signal_target import SignalAndTarget train_set = SignalAndTarget(X[:60], y=y[:60]) test_set = SignalAndTarget(X[60:], y=y[60:]) from braindecode.models.shallow_fbcsp import ShallowFBCSPNet from torch import nn from braindecode.torch_ext.util import set_random_seeds # Set if you want to use GPU # You can also use torch.cuda.is_available() to determine if cuda is available on your machine. cuda = False set_random_seeds(seed=20170629, cuda=cuda) n_classes = 2 in_chans = train_set.X.shape[1] # final_conv_length = auto ensures we only get a single output in the time dimension model = ShallowFBCSPNet(in_chans=in_chans, n_classes=n_classes, input_time_length=train_set.X.shape[2], final_conv_length='auto').create_network() if cuda: model.cuda() from torch import optim optimizer = optim.Adam(model.parameters()) from braindecode.torch_ext.util import np_to_var, var_to_np from braindecode.datautil.iterators import get_balanced_batches import torch.nn.functional as F from numpy.random import RandomState rng = RandomState((2017, 6, 30)) losses = [] accuracies = [] for i_epoch in range(6): i_trials_in_batch = get_balanced_batches(len(train_set.X), rng, shuffle=True, batch_size=30) # Set model to training mode model.train() for i_trials in i_trials_in_batch: # Have to add empty fourth dimension to X batch_X = train_set.X[i_trials][:, :, :, None] batch_y = train_set.y[i_trials] net_in = np_to_var(batch_X) if cuda: net_in = net_in.cuda() net_target = np_to_var(batch_y) if cuda: net_target = net_target.cuda() # Remove gradients of last backward pass from all parameters optimizer.zero_grad() # Compute outputs of the network outputs = model(net_in) # Compute the loss loss = F.nll_loss(outputs, net_target) # Do the backpropagation loss.backward() # Update parameters with the optimizer optimizer.step() # Print some statistics each epoch model.eval() print("Epoch {:d}".format(i_epoch)) for setname, dataset in (('Train', train_set), ('Test', test_set)): # Here, we will use the entire dataset at once, which is still possible # for such smaller datasets. Otherwise we would have to use batches. net_in = np_to_var(dataset.X[:, :, :, None]) if cuda: net_in = net_in.cuda() net_target = np_to_var(dataset.y) if cuda: net_target = net_target.cuda() outputs = model(net_in) loss = F.nll_loss(outputs, net_target) losses.append(float(var_to_np(loss))) print("{:6s} Loss: {:.5f}".format(setname, float(var_to_np(loss)))) predicted_labels = np.argmax(var_to_np(outputs), axis=1) accuracy = np.mean(dataset.y == predicted_labels) accuracies.append(accuracy * 100) print("{:6s} Accuracy: {:.1f}%".format(setname, accuracy * 100)) np.testing.assert_allclose(np.array(losses), np.array([ 1.1775966882705688, 1.2602351903915405, 0.7068756818771362, 0.9367912411689758, 0.394258975982666, 0.6598362326622009, 0.3359280526638031, 0.656258761882782, 0.2790488004684448, 0.6104397177696228, 0.27319177985191345, 0.5949864983558655 ]), rtol=1e-4, atol=1e-5) np.testing.assert_allclose(np.array(accuracies), np.array([ 51.666666666666671, 53.333333333333336, 63.333333333333329, 56.666666666666664, 86.666666666666671, 66.666666666666657, 90.0, 63.333333333333329, 96.666666666666671, 56.666666666666664, 96.666666666666671, 66.666666666666657 ]), rtol=1e-4, atol=1e-5)
def run_exp( data_folders, n_recordings, sensor_types, n_chans, max_recording_mins, sec_to_cut, duration_recording_mins, test_recording_mins, max_abs_val, sampling_freq, divisor, test_on_eval, n_folds, i_test_fold, shuffle, model_name, n_start_chans, n_chan_factor, input_time_length, final_conv_length, model_constraint, init_lr, batch_size, max_epochs, cuda, ): import torch.backends.cudnn as cudnn cudnn.benchmark = True preproc_functions = [] preproc_functions.append(lambda data, fs: ( data[:, int(sec_to_cut * fs):-int(sec_to_cut * fs)], fs)) preproc_functions.append(lambda data, fs: (data[:, :int( duration_recording_mins * 60 * fs)], fs)) if max_abs_val is not None: preproc_functions.append( lambda data, fs: (np.clip(data, -max_abs_val, max_abs_val), fs)) preproc_functions.append(lambda data, fs: (resampy.resample( data, fs, sampling_freq, axis=1, filter='kaiser_fast'), sampling_freq)) if divisor is not None: preproc_functions.append(lambda data, fs: (data / divisor, fs)) dataset = DiagnosisSet(n_recordings=n_recordings, max_recording_mins=max_recording_mins, preproc_functions=preproc_functions, data_folders=data_folders, train_or_eval='train', sensor_types=sensor_types) if test_on_eval: if test_recording_mins is None: test_recording_mins = duration_recording_mins test_preproc_functions = copy(preproc_functions) test_preproc_functions[1] = lambda data, fs: (data[:, :int( test_recording_mins * 60 * fs)], fs) test_dataset = DiagnosisSet(n_recordings=n_recordings, max_recording_mins=None, preproc_functions=test_preproc_functions, data_folders=data_folders, train_or_eval='eval', sensor_types=sensor_types) X, y = dataset.load() max_shape = np.max([list(x.shape) for x in X], axis=0) assert max_shape[1] == int(duration_recording_mins * sampling_freq * 60) if test_on_eval: test_X, test_y = test_dataset.load() max_shape = np.max([list(x.shape) for x in test_X], axis=0) assert max_shape[1] == int(test_recording_mins * sampling_freq * 60) if not test_on_eval: splitter = TrainValidTestSplitter(n_folds, i_test_fold, shuffle=shuffle) train_set, valid_set, test_set = splitter.split(X, y) else: splitter = TrainValidSplitter(n_folds, i_valid_fold=i_test_fold, shuffle=shuffle) train_set, valid_set = splitter.split(X, y) test_set = SignalAndTarget(test_X, test_y) del test_X, test_y del X, y # shouldn't be necessary, but just to make sure set_random_seeds(seed=20170629, cuda=cuda) n_classes = 2 if model_name == 'shallow': model = ShallowFBCSPNet( in_chans=n_chans, n_classes=n_classes, n_filters_time=n_start_chans, n_filters_spat=n_start_chans, input_time_length=input_time_length, final_conv_length=final_conv_length).create_network() elif model_name == 'deep': model = Deep4Net(n_chans, n_classes, n_filters_time=n_start_chans, n_filters_spat=n_start_chans, input_time_length=input_time_length, n_filters_2=int(n_start_chans * n_chan_factor), n_filters_3=int(n_start_chans * (n_chan_factor**2.0)), n_filters_4=int(n_start_chans * (n_chan_factor**3.0)), final_conv_length=final_conv_length, stride_before_pool=True).create_network() elif (model_name == 'deep_smac'): if model_name == 'deep_smac': do_batch_norm = False else: assert model_name == 'deep_smac_bnorm' do_batch_norm = True double_time_convs = False drop_prob = 0.244445 filter_length_2 = 12 filter_length_3 = 14 filter_length_4 = 12 filter_time_length = 21 final_conv_length = 1 first_nonlin = elu first_pool_mode = 'mean' first_pool_nonlin = identity later_nonlin = elu later_pool_mode = 'mean' later_pool_nonlin = identity n_filters_factor = 1.679066 n_filters_start = 32 pool_time_length = 1 pool_time_stride = 2 split_first_layer = True n_chan_factor = n_filters_factor n_start_chans = n_filters_start model = Deep4Net(n_chans, n_classes, n_filters_time=n_start_chans, n_filters_spat=n_start_chans, input_time_length=input_time_length, n_filters_2=int(n_start_chans * n_chan_factor), n_filters_3=int(n_start_chans * (n_chan_factor**2.0)), n_filters_4=int(n_start_chans * (n_chan_factor**3.0)), final_conv_length=final_conv_length, batch_norm=do_batch_norm, double_time_convs=double_time_convs, drop_prob=drop_prob, filter_length_2=filter_length_2, filter_length_3=filter_length_3, filter_length_4=filter_length_4, filter_time_length=filter_time_length, first_nonlin=first_nonlin, first_pool_mode=first_pool_mode, first_pool_nonlin=first_pool_nonlin, later_nonlin=later_nonlin, later_pool_mode=later_pool_mode, later_pool_nonlin=later_pool_nonlin, pool_time_length=pool_time_length, pool_time_stride=pool_time_stride, split_first_layer=split_first_layer, stride_before_pool=True).create_network() elif model_name == 'shallow_smac': conv_nonlin = identity do_batch_norm = True drop_prob = 0.328794 filter_time_length = 56 final_conv_length = 22 n_filters_spat = 73 n_filters_time = 24 pool_mode = 'max' pool_nonlin = identity pool_time_length = 84 pool_time_stride = 3 split_first_layer = True model = ShallowFBCSPNet( in_chans=n_chans, n_classes=n_classes, n_filters_time=n_filters_time, n_filters_spat=n_filters_spat, input_time_length=input_time_length, final_conv_length=final_conv_length, conv_nonlin=conv_nonlin, batch_norm=do_batch_norm, drop_prob=drop_prob, filter_time_length=filter_time_length, pool_mode=pool_mode, pool_nonlin=pool_nonlin, pool_time_length=pool_time_length, pool_time_stride=pool_time_stride, split_first_layer=split_first_layer, ).create_network() elif model_name == 'linear': model = nn.Sequential() model.add_module("conv_classifier", nn.Conv2d(n_chans, n_classes, (600, 1))) model.add_module('softmax', nn.LogSoftmax()) model.add_module('squeeze', Expression(lambda x: x.squeeze(3))) else: assert False, "unknown model name {:s}".format(model_name) to_dense_prediction_model(model) log.info("Model:\n{:s}".format(str(model))) if cuda: model.cuda() # determine output size test_input = np_to_var( np.ones((2, n_chans, input_time_length, 1), dtype=np.float32)) if cuda: test_input = test_input.cuda() log.info("In shape: {:s}".format(str(test_input.cpu().data.numpy().shape))) out = model(test_input) log.info("Out shape: {:s}".format(str(out.cpu().data.numpy().shape))) n_preds_per_input = out.cpu().data.numpy().shape[2] log.info("{:d} predictions per input/trial".format(n_preds_per_input)) iterator = CropsFromTrialsIterator(batch_size=batch_size, input_time_length=input_time_length, n_preds_per_input=n_preds_per_input) optimizer = optim.Adam(model.parameters(), lr=init_lr) loss_function = lambda preds, targets: F.nll_loss( th.mean(preds, dim=2, keepdim=False), targets) if model_constraint is not None: assert model_constraint == 'defaultnorm' model_constraint = MaxNormDefaultConstraint() monitors = [ LossMonitor(), MisclassMonitor(col_suffix='sample_misclass'), CroppedDiagnosisMonitor(input_time_length, n_preds_per_input), RuntimeMonitor(), ] stop_criterion = MaxEpochs(max_epochs) batch_modifier = None run_after_early_stop = True exp = Experiment(model, train_set, valid_set, test_set, iterator, loss_function, optimizer, model_constraint, monitors, stop_criterion, remember_best_column='valid_misclass', run_after_early_stop=run_after_early_stop, batch_modifier=batch_modifier, cuda=cuda) exp.run() return exp
# Create the model from braindecode.models.shallow_fbcsp import ShallowFBCSPNet from braindecode.models.deep4 import Deep4Net from braindecode.torch_ext.util import set_random_seeds set_random_seeds(seed=20170629, cuda=cuda) in_chans = train_set.X.shape[1] print("INFO : in_chans: {}".format(in_chans)) np.set_printoptions(suppress=True, threshold=np.inf) # final_conv_length = auto ensures we only get a single output in the time dimension if train_type == 'trialwise': input_time_length = train_set.X.shape[2] if model_type == 'shallow': model = ShallowFBCSPNet(in_chans=in_chans, n_classes=n_classes, input_time_length=input_time_length, final_conv_length='auto') else: model = Deep4Net(in_chans=in_chans, n_classes=n_classes, input_time_length=input_time_length, final_conv_length='auto') else: # cropped if model_type == 'shallow': model = ShallowFBCSPNet(in_chans=in_chans, n_classes=n_classes, input_time_length=None, final_conv_length=1) else: model = Deep4Net(in_chans=in_chans, n_classes=n_classes, input_time_length=None, final_conv_length=1) if cuda:
def run_exp(test_on_eval, sensor_types, n_chans, max_recording_mins, test_recording_mins, n_recordings, sec_to_cut_at_start, sec_to_cut_at_end, duration_recording_mins, max_abs_val, clip_before_resample, sampling_freq, divisor, n_folds, i_test_fold, shuffle, merge_train_valid, model_name, n_start_chans, n_chan_factor, input_time_length, final_conv_length, stride_before_pool, optimizer, learning_rate, weight_decay, scheduler, model_constraint, batch_size, max_epochs, log_dir, only_return_exp, np_th_seed): cuda = True if ('smac' in model_name) and (input_time_length is None): input_time_length = 12000 fix_input_length_for_smac = True else: fix_input_length_for_smac = False set_random_seeds(seed=np_th_seed, cuda=cuda) n_classes = 2 if model_name == 'shallow': model = ShallowFBCSPNet( in_chans=n_chans, n_classes=n_classes, n_filters_time=n_start_chans, n_filters_spat=n_start_chans, input_time_length=input_time_length, final_conv_length=final_conv_length).create_network() elif model_name == 'deep': model = Deep4Net( n_chans, n_classes, n_filters_time=n_start_chans, n_filters_spat=n_start_chans, input_time_length=input_time_length, n_filters_2=int(n_start_chans * n_chan_factor), n_filters_3=int(n_start_chans * (n_chan_factor**2.0)), n_filters_4=int(n_start_chans * (n_chan_factor**3.0)), final_conv_length=final_conv_length, stride_before_pool=stride_before_pool).create_network() elif (model_name == 'deep_smac') or (model_name == 'deep_smac_bnorm'): if model_name == 'deep_smac': do_batch_norm = False else: assert model_name == 'deep_smac_bnorm' do_batch_norm = True double_time_convs = False drop_prob = 0.244445 filter_length_2 = 12 filter_length_3 = 14 filter_length_4 = 12 filter_time_length = 21 final_conv_length = 1 first_nonlin = elu first_pool_mode = 'mean' first_pool_nonlin = identity later_nonlin = elu later_pool_mode = 'mean' later_pool_nonlin = identity n_filters_factor = 1.679066 n_filters_start = 32 pool_time_length = 1 pool_time_stride = 2 split_first_layer = True n_chan_factor = n_filters_factor n_start_chans = n_filters_start model = Deep4Net(n_chans, n_classes, n_filters_time=n_start_chans, n_filters_spat=n_start_chans, input_time_length=input_time_length, n_filters_2=int(n_start_chans * n_chan_factor), n_filters_3=int(n_start_chans * (n_chan_factor**2.0)), n_filters_4=int(n_start_chans * (n_chan_factor**3.0)), final_conv_length=final_conv_length, batch_norm=do_batch_norm, double_time_convs=double_time_convs, drop_prob=drop_prob, filter_length_2=filter_length_2, filter_length_3=filter_length_3, filter_length_4=filter_length_4, filter_time_length=filter_time_length, first_nonlin=first_nonlin, first_pool_mode=first_pool_mode, first_pool_nonlin=first_pool_nonlin, later_nonlin=later_nonlin, later_pool_mode=later_pool_mode, later_pool_nonlin=later_pool_nonlin, pool_time_length=pool_time_length, pool_time_stride=pool_time_stride, split_first_layer=split_first_layer, stride_before_pool=True).create_network() elif model_name == 'shallow_smac': conv_nonlin = identity do_batch_norm = True drop_prob = 0.328794 filter_time_length = 56 final_conv_length = 22 n_filters_spat = 73 n_filters_time = 24 pool_mode = 'max' pool_nonlin = identity pool_time_length = 84 pool_time_stride = 3 split_first_layer = True model = ShallowFBCSPNet( in_chans=n_chans, n_classes=n_classes, n_filters_time=n_filters_time, n_filters_spat=n_filters_spat, input_time_length=input_time_length, final_conv_length=final_conv_length, conv_nonlin=conv_nonlin, batch_norm=do_batch_norm, drop_prob=drop_prob, filter_time_length=filter_time_length, pool_mode=pool_mode, pool_nonlin=pool_nonlin, pool_time_length=pool_time_length, pool_time_stride=pool_time_stride, split_first_layer=split_first_layer, ).create_network() elif model_name == 'deep_smac_new': from torch.nn.functional import elu, relu, relu6, tanh from braindecode.torch_ext.functions import identity, square, safe_log n_filters_factor = 1.9532637176784269 n_filters_start = 61 deep_kwargs = { "batch_norm": False, "double_time_convs": False, "drop_prob": 0.3622676569047184, "filter_length_2": 9, "filter_length_3": 6, "filter_length_4": 10, "filter_time_length": 17, "final_conv_length": 5, "first_nonlin": elu, "first_pool_mode": "max", "first_pool_nonlin": identity, "later_nonlin": relu6, "later_pool_mode": "max", "later_pool_nonlin": identity, "n_filters_time": n_filters_start, "n_filters_spat": n_filters_start, "n_filters_2": int(n_filters_start * n_filters_factor), "n_filters_3": int(n_filters_start * (n_filters_factor**2.0)), "n_filters_4": int(n_filters_start * (n_filters_factor**3.0)), "pool_time_length": 1, "pool_time_stride": 4, "split_first_layer": True, "stride_before_pool": True, } model = Deep4Net(n_chans, n_classes, input_time_length=input_time_length, **deep_kwargs).create_network() elif model_name == 'shallow_smac_new': from torch.nn.functional import elu, relu, relu6, tanh from braindecode.torch_ext.functions import identity, square, safe_log shallow_kwargs = { "conv_nonlin": square, "batch_norm": True, "drop_prob": 0.10198630723385381, "filter_time_length": 51, "final_conv_length": 1, "n_filters_spat": 200, "n_filters_time": 76, "pool_mode": "max", "pool_nonlin": safe_log, "pool_time_length": 139, "pool_time_stride": 49, "split_first_layer": True, } model = ShallowFBCSPNet(in_chans=n_chans, n_classes=n_classes, input_time_length=input_time_length, **shallow_kwargs).create_network() elif model_name == 'linear': model = nn.Sequential() model.add_module("conv_classifier", nn.Conv2d(n_chans, n_classes, (600, 1))) model.add_module('softmax', nn.LogSoftmax()) model.add_module('squeeze', Expression(lambda x: x.squeeze(3))) elif model_name == '3path': virtual_chan_1x1_conv = True mean_across_features = False drop_prob = 0.5 n_start_filters = 10 early_bnorm = False n_classifier_filters = 100 later_kernel_len = 5 extra_conv_stride = 4 # dont forget to reset n_preds_per_blabla model = create_multi_start_path_net( in_chans=n_chans, virtual_chan_1x1_conv=virtual_chan_1x1_conv, n_start_filters=n_start_filters, early_bnorm=early_bnorm, later_kernel_len=later_kernel_len, extra_conv_stride=extra_conv_stride, mean_across_features=mean_across_features, n_classifier_filters=n_classifier_filters, drop_prob=drop_prob) else: assert False, "unknown model name {:s}".format(model_name) if not model_name == '3path': to_dense_prediction_model(model) log.info("Model:\n{:s}".format(str(model))) time_cut_off_sec = np.inf start_time = time.time() # fix input time length in case of smac models if fix_input_length_for_smac: assert ('smac' in model_name) and (input_time_length == 12000) if cuda: model.cuda() test_input = np_to_var( np.ones((2, n_chans, input_time_length, 1), dtype=np.float32)) if cuda: test_input = test_input.cuda() try: out = model(test_input) except: raise ValueError("Model receptive field too large...") n_preds_per_input = out.cpu().data.numpy().shape[2] n_receptive_field = input_time_length - n_preds_per_input input_time_length = 2 * n_receptive_field exp = common.run_exp( max_recording_mins, n_recordings, sec_to_cut_at_start, sec_to_cut_at_end, duration_recording_mins, max_abs_val, clip_before_resample, sampling_freq, divisor, n_folds, i_test_fold, shuffle, merge_train_valid, model, input_time_length, optimizer, learning_rate, weight_decay, scheduler, model_constraint, batch_size, max_epochs, only_return_exp, time_cut_off_sec, start_time, test_on_eval, test_recording_mins, sensor_types, log_dir, np_th_seed, ) return exp
def run_exp(data_folder, subject_id, low_cut_hz, model, cuda): ival = [-500, 4000] input_time_length = 1000 max_epochs = 800 max_increase_epochs = 80 batch_size = 60 high_cut_hz = 38 factor_new = 1e-3 init_block_size = 1000 valid_set_fraction = 0.2 train_filename = 'A{:02d}T.gdf'.format(subject_id) test_filename = 'A{:02d}E.gdf'.format(subject_id) train_filepath = os.path.join(data_folder, train_filename) test_filepath = os.path.join(data_folder, test_filename) train_label_filepath = train_filepath.replace('.gdf', '.mat') test_label_filepath = test_filepath.replace('.gdf', '.mat') train_loader = BCICompetition4Set2A(train_filepath, labels_filename=train_label_filepath) test_loader = BCICompetition4Set2A(test_filepath, labels_filename=test_label_filepath) train_cnt = train_loader.load() test_cnt = test_loader.load() # Preprocessing train_cnt = train_cnt.drop_channels( ['STI 014', 'EOG-left', 'EOG-central', 'EOG-right']) assert len(train_cnt.ch_names) == 22 # lets convert to millvolt for numerical stability of next operations train_cnt = mne_apply(lambda a: a * 1e6, train_cnt) train_cnt = mne_apply( lambda a: bandpass_cnt(a, low_cut_hz, high_cut_hz, train_cnt.info['sfreq'], filt_order=3, axis=1), train_cnt) train_cnt = mne_apply( lambda a: exponential_running_standardize(a.T, factor_new=factor_new, init_block_size= init_block_size, eps=1e-4).T, train_cnt) test_cnt = test_cnt.drop_channels( ['STI 014', 'EOG-left', 'EOG-central', 'EOG-right']) assert len(test_cnt.ch_names) == 22 test_cnt = mne_apply(lambda a: a * 1e6, test_cnt) test_cnt = mne_apply( lambda a: bandpass_cnt(a, low_cut_hz, high_cut_hz, test_cnt.info['sfreq'], filt_order=3, axis=1), test_cnt) test_cnt = mne_apply( lambda a: exponential_running_standardize(a.T, factor_new=factor_new, init_block_size= init_block_size, eps=1e-4).T, test_cnt) marker_def = OrderedDict([('Left Hand', [1]), ( 'Right Hand', [2], ), ('Foot', [3]), ('Tongue', [4])]) train_set = create_signal_target_from_raw_mne(train_cnt, marker_def, ival) test_set = create_signal_target_from_raw_mne(test_cnt, marker_def, ival) train_set, valid_set = split_into_two_sets(train_set, first_set_fraction=1 - valid_set_fraction) set_random_seeds(seed=20190706, cuda=cuda) n_classes = 4 n_chans = int(train_set.X.shape[1]) if model == 'shallow': model = ShallowFBCSPNet(n_chans, n_classes, input_time_length=input_time_length, final_conv_length=30).create_network() elif model == 'deep': model = Deep4Net(n_chans, n_classes, input_time_length=input_time_length, final_conv_length=2).create_network() to_dense_prediction_model(model) if cuda: model.cuda() log.info("Model: \n{:s}".format(str(model))) dummy_input = np_to_var(train_set.X[:1, :, :, None]) if cuda: dummy_input = dummy_input.cuda() out = model(dummy_input) n_preds_per_input = out.cpu().data.numpy().shape[2] optimizer = optim.Adam(model.parameters()) iterator = CropsFromTrialsIterator(batch_size=batch_size, input_time_length=input_time_length, n_preds_per_input=n_preds_per_input) stop_criterion = Or([ MaxEpochs(max_epochs), NoDecrease('valid_misclass', max_increase_epochs) ]) monitors = [ LossMonitor(), MisclassMonitor(col_suffix='sample_misclass'), CroppedTrialMisclassMonitor(input_time_length=input_time_length), RuntimeMonitor() ] model_constraint = MaxNormDefaultConstraint() loss_function = lambda preds, targets: F.nll_loss( th.mean(preds, dim=2, keepdim=False), targets) exp = Experiment(model, train_set, valid_set, test_set, iterator=iterator, loss_function=loss_function, optimizer=optimizer, model_constraint=model_constraint, monitors=monitors, stop_criterion=stop_criterion, remember_best_column='valid_misclass', run_after_early_stop=True, cuda=cuda) exp.run() return exp
from braindecode.models.deep4 import Deep4Net from braindecode.torch_ext.util import set_random_seeds # Set if you want to use GPU # You can also use torch.cuda.is_available() to determine if cuda is available on your machine. cuda = False set_random_seeds(seed=20170629, cuda=cuda) n_classes = 3 in_chans = train_set.X.shape[1] print("INFO : in_chans: {}".format(in_chans)) print("INFO : input_time_length: {}".format(train_set.X.shape[2])) # final_conv_length = auto ensures we only get a single output in the time dimension if model_type == 'shallow': model = ShallowFBCSPNet(in_chans=in_chans, n_classes=n_classes, input_time_length=train_set.X.shape[2], final_conv_length='auto') else: model = Deep4Net(in_chans=in_chans, n_classes=n_classes, input_time_length=train_set.X.shape[2], final_conv_length='auto') path_to_classifier = "torchModelsCrossSubjects\{}-{}-52subjects-2.5sec-800epoches-torch_model".format( model_type, train_type) if cuda: model.cuda() from braindecode.torch_ext.optimizers import AdamW import torch.nn.functional as F if model_type == 'shallow':
def run_exp_on_high_gamma_dataset(train_filename, test_filename, low_cut_hz, model_name, max_epochs, max_increase_epochs, np_th_seed, debug): train_set, valid_set, test_set = load_train_valid_test( train_filename=train_filename, test_filename=test_filename, low_cut_hz=low_cut_hz, debug=debug) if debug: max_epochs = 4 set_random_seeds(np_th_seed, cuda=True) #torch.backends.cudnn.benchmark = True# sometimes crashes? n_classes = int(np.max(train_set.y) + 1) n_chans = int(train_set.X.shape[1]) input_time_length = 1000 if model_name == 'deep': model = Deep4Net(n_chans, n_classes, input_time_length=input_time_length, final_conv_length=2).create_network() elif model_name == 'shallow': model = ShallowFBCSPNet(n_chans, n_classes, input_time_length=input_time_length, final_conv_length=30).create_network() to_dense_prediction_model(model) model.cuda() model.eval() out = model(np_to_var(train_set.X[:1, :, :input_time_length, None]).cuda()) n_preds_per_input = out.cpu().data.numpy().shape[2] optimizer = optim.Adam(model.parameters(), weight_decay=0, lr=1e-3) iterator = CropsFromTrialsIterator(batch_size=60, input_time_length=input_time_length, n_preds_per_input=n_preds_per_input, seed=np_th_seed) monitors = [ LossMonitor(), MisclassMonitor(col_suffix='sample_misclass'), CroppedTrialMisclassMonitor(input_time_length=input_time_length), RuntimeMonitor() ] model_constraint = MaxNormDefaultConstraint() loss_function = lambda preds, targets: F.nll_loss(th.mean(preds, dim=2), targets) run_after_early_stop = True do_early_stop = True remember_best_column = 'valid_misclass' stop_criterion = Or([ MaxEpochs(max_epochs), NoDecrease('valid_misclass', max_increase_epochs) ]) exp = Experiment(model, train_set, valid_set, test_set, iterator=iterator, loss_function=loss_function, optimizer=optimizer, model_constraint=model_constraint, monitors=monitors, stop_criterion=stop_criterion, remember_best_column=remember_best_column, run_after_early_stop=run_after_early_stop, cuda=True, do_early_stop=do_early_stop) exp.run() return exp
def test_trialwise_decoding(): # 5,6,7,10,13,14 are codes for executed and imagined hands/feet subject_id = 1 event_codes = [5, 6, 9, 10, 13, 14] # event_codes = [6] # This will download the files if you don't have them yet, # and then return the paths to the files. physionet_paths = mne.datasets.eegbci.load_data(subject_id, event_codes) # Load each of the files parts = [ mne.io.read_raw_edf(path, preload=True, stim_channel='auto', verbose='WARNING') for path in physionet_paths ] # Concatenate them raw = concatenate_raws(parts) # Find the events in this dataset # events = mne.find_events(raw, shortest_event=0, stim_channel='STI 014') events, _ = mne.events_from_annotations(raw) # Extract trials, only using EEG channels eeg_channel_inds = mne.pick_types(raw.info, meg=False, eeg=True, stim=False, eog=False, exclude='bads') # Extract trials, only using EEG channels epoched = mne.Epochs(raw, events, dict(hands=2, feet=3), tmin=1, tmax=4.1, proj=False, picks=eeg_channel_inds, baseline=None, preload=True) # Convert data from volt to millivolt # Pytorch expects float32 for input and int64 for labels. # X:[90,64,497] X = (epoched.get_data() * 1e6).astype(np.float32) # y:[90] y = (epoched.events[:, 2] - 2).astype(np.int64) # 2,3 -> 0,1 # X_train:[60,64,497], y_train:[60] train_set = SignalAndTarget(X[:60], y=y[:60]) # X_test:[30,64,497], y_test:[30] test_set = SignalAndTarget(X[60:], y=y[60:]) # Set if you want to use GPU # You can also use torch.cuda.is_available() to determine if cuda is available on your machine. cuda = False set_random_seeds(seed=20170629, cuda=cuda) n_classes = 2 in_chans = train_set.X.shape[1] # final_conv_length = auto ensures we only get a single output in the time dimension # def __init__(self, in_chans=64, n_classes=2, input_time_length=497, n_filters_time=40, filter_time_length=25, n_filters_spat=40, pool_time_length=75, pool_time_stride=15, final_conv_length='auto, conv_nonlin=square, pool_mode="mean", pool_nonlin=safe_log, split_first_layer=True, batch_norm=True, batch_norm_alpha=0.1, drop_prob=0.5, ): # 感觉create_network()就是__init__的一部分, 现在改成用self.model调用了, 还是感觉不优雅, 主要是forward集成在nn.Sequential里面了 # 然后这个model的实际__init__不是ShallowFBCSPNet, 而是nn.Sequential, 感觉我更喜欢原来的定义方式, 这种方式看不到中间输出 # model = ShallowFBCSPNet(in_chans=in_chans, n_classes=n_classes, input_time_length=train_set.X.shape[2], final_conv_length='auto').create_network() #原来的 model = ShallowFBCSPNet(in_chans=in_chans, n_classes=n_classes, input_time_length=train_set.X.shape[2], final_conv_length='auto').model if cuda: model.cuda() optimizer = optim.Adam(model.parameters()) rng = RandomState((2017, 6, 30)) losses = [] accuracies = [] for i_epoch in range(6): i_trials_in_batch = get_balanced_batches(len(train_set.X), rng, shuffle=True, batch_size=10) # Set model to training mode model.train() for i_trials in i_trials_in_batch: # Have to add empty fourth dimension to X batch_X = train_set.X[i_trials][:, :, :, None] batch_y = train_set.y[i_trials] net_in = np_to_var(batch_X) if cuda: net_in = net_in.cuda() net_target = np_to_var(batch_y) if cuda: net_target = net_target.cuda() # Remove gradients of last backward pass from all parameters optimizer.zero_grad() # Compute outputs of the network #net_in: [10, 64, 497, 1]=[bsz, H_im, W_im, C_im] # outputs = model.forward(net_in) # model=Sequential( # (dimshuffle): Expression(expression=_transpose_time_to_spat) # (conv_time): Conv2d(1, 40, kernel_size=(25, 1), stride=(1, 1)) # (conv_spat): Conv2d(40, 40, kernel_size=(1, 64), stride=(1, 1), bias=False) # (bnorm): BatchNorm2d(40, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True) # (conv_nonlin): Expression(expression=square) # (pool): AvgPool2d(kernel_size=(75, 1), stride=(15, 1), padding=0) # (pool_nonlin): Expression(expression=safe_log) # (drop): Dropout(p=0.5) # (conv_classifier): Conv2d(40, 2, kernel_size=(27, 1), stride=(1, 1)) # (softmax): LogSoftmax() # (squeeze): Expression(expression=_squeeze_final_output) # ) # Compute the loss loss = F.nll_loss(outputs, net_target) # Do the backpropagation loss.backward() # Update parameters with the optimizer optimizer.step() # Print some statistics each epoch model.eval() print("Epoch {:d}".format(i_epoch)) for setname, dataset in (('Train', train_set), ('Test', test_set)): # Here, we will use the entire dataset at once, which is still possible # for such smaller datasets. Otherwise we would have to use batches. net_in = np_to_var(dataset.X[:, :, :, None]) if cuda: net_in = net_in.cuda() net_target = np_to_var(dataset.y) if cuda: net_target = net_target.cuda() outputs = model(net_in) loss = F.nll_loss(outputs, net_target) losses.append(float(var_to_np(loss))) print("{:6s} Loss: {:.5f}".format(setname, float(var_to_np(loss)))) predicted_labels = np.argmax(var_to_np(outputs), axis=1) accuracy = np.mean(dataset.y == predicted_labels) accuracies.append(accuracy * 100) print("{:6s} Accuracy: {:.1f}%".format(setname, accuracy * 100)) np.testing.assert_allclose(np.array(losses), np.array([ 1.1775966882705688, 1.2602351903915405, 0.7068756818771362, 0.9367912411689758, 0.394258975982666, 0.6598362326622009, 0.3359280526638031, 0.656258761882782, 0.2790488004684448, 0.6104397177696228, 0.27319177985191345, 0.5949864983558655 ]), rtol=1e-4, atol=1e-5) np.testing.assert_allclose(np.array(accuracies), np.array([ 51.666666666666671, 53.333333333333336, 63.333333333333329, 56.666666666666664, 86.666666666666671, 66.666666666666657, 90.0, 63.333333333333329, 96.666666666666671, 56.666666666666664, 96.666666666666671, 66.666666666666657 ]), rtol=1e-4, atol=1e-5)
def run_exp(data_folder, subject_id, low_cut_hz, model, cuda): ival = [-500, 4000] max_epochs = 1600 max_increase_epochs = 160 batch_size = 60 high_cut_hz = 38 factor_new = 1e-3 init_block_size = 1000 valid_set_fraction = 0.2 train_filename = "A{:02d}T.gdf".format(subject_id) test_filename = "A{:02d}E.gdf".format(subject_id) train_filepath = os.path.join(data_folder, train_filename) test_filepath = os.path.join(data_folder, test_filename) train_label_filepath = train_filepath.replace(".gdf", ".mat") test_label_filepath = test_filepath.replace(".gdf", ".mat") train_loader = BCICompetition4Set2A( train_filepath, labels_filename=train_label_filepath ) test_loader = BCICompetition4Set2A( test_filepath, labels_filename=test_label_filepath ) train_cnt = train_loader.load() test_cnt = test_loader.load() # Preprocessing train_cnt = train_cnt.drop_channels( ["EOG-left", "EOG-central", "EOG-right"] ) assert len(train_cnt.ch_names) == 22 # lets convert to millvolt for numerical stability of next operations train_cnt = mne_apply(lambda a: a * 1e6, train_cnt) train_cnt = mne_apply( lambda a: bandpass_cnt( a, low_cut_hz, high_cut_hz, train_cnt.info["sfreq"], filt_order=3, axis=1, ), train_cnt, ) train_cnt = mne_apply( lambda a: exponential_running_standardize( a.T, factor_new=factor_new, init_block_size=init_block_size, eps=1e-4, ).T, train_cnt, ) test_cnt = test_cnt.drop_channels(["EOG-left", "EOG-central", "EOG-right"]) assert len(test_cnt.ch_names) == 22 test_cnt = mne_apply(lambda a: a * 1e6, test_cnt) test_cnt = mne_apply( lambda a: bandpass_cnt( a, low_cut_hz, high_cut_hz, test_cnt.info["sfreq"], filt_order=3, axis=1, ), test_cnt, ) test_cnt = mne_apply( lambda a: exponential_running_standardize( a.T, factor_new=factor_new, init_block_size=init_block_size, eps=1e-4, ).T, test_cnt, ) marker_def = OrderedDict( [ ("Left Hand", [1]), ("Right Hand", [2]), ("Foot", [3]), ("Tongue", [4]), ] ) train_set = create_signal_target_from_raw_mne(train_cnt, marker_def, ival) test_set = create_signal_target_from_raw_mne(test_cnt, marker_def, ival) train_set, valid_set = split_into_two_sets( train_set, first_set_fraction=1 - valid_set_fraction ) set_random_seeds(seed=20190706, cuda=cuda) n_classes = 4 n_chans = int(train_set.X.shape[1]) input_time_length = train_set.X.shape[2] if model == "shallow": model = ShallowFBCSPNet( n_chans, n_classes, input_time_length=input_time_length, final_conv_length="auto", ).create_network() elif model == "deep": model = Deep4Net( n_chans, n_classes, input_time_length=input_time_length, final_conv_length="auto", ).create_network() if cuda: model.cuda() log.info("Model: \n{:s}".format(str(model))) optimizer = optim.Adam(model.parameters()) iterator = BalancedBatchSizeIterator(batch_size=batch_size) stop_criterion = Or( [ MaxEpochs(max_epochs), NoDecrease("valid_misclass", max_increase_epochs), ] ) monitors = [LossMonitor(), MisclassMonitor(), RuntimeMonitor()] model_constraint = MaxNormDefaultConstraint() exp = Experiment( model, train_set, valid_set, test_set, iterator=iterator, loss_function=F.nll_loss, optimizer=optimizer, model_constraint=model_constraint, monitors=monitors, stop_criterion=stop_criterion, remember_best_column="valid_misclass", run_after_early_stop=True, cuda=cuda, ) exp.run() return exp
def call_model(self): if self.model_type == 'shallow': model = ShallowFBCSPNet(in_chans=self.n_chans, n_classes=self.n_classes, input_time_length=self.input_time_length, n_filters_time=40, filter_time_length=25, n_filters_spat=40, pool_time_length=75, pool_time_stride=15, final_conv_length='auto', conv_nonlin=getattr( torch.nn.functional, self.activation), pool_mode='mean', pool_nonlin=safe_log, split_first_layer=True, batch_norm=True, batch_norm_alpha=0.1, drop_prob=0.1).create_network() elif self.model_type == 'deep': model = Deep4Net(in_chans=self.n_chans, n_classes=self.n_classes, input_time_length=self.input_time_length, final_conv_length='auto', n_filters_time=25, n_filters_spat=25, filter_time_length=10, pool_time_length=3, pool_time_stride=3, n_filters_2=50, filter_length_2=10, n_filters_3=100, filter_length_3=10, n_filters_4=200, filter_length_4=10, first_nonlin=getattr(torch.nn.functional, self.activation), first_pool_mode='max', first_pool_nonlin=safe_log, later_nonlin=self.getattr(torch.nn.functional, self.activation), later_pool_mode='max', later_pool_nonlin=safe_log, drop_prob=0.1, double_time_convs=False, split_first_layer=False, batch_norm=True, batch_norm_alpha=0.1, stride_before_pool=False).create_network() elif self.model_type == 'eegnet': model = EEGNetv4(in_chans=self.n_chans, n_classes=self.n_classes, final_conv_length='auto', input_time_length=self.input_time_length, pool_mode='mean', F1=16, D=2, F2=32, kernel_length=64, third_kernel_size=(8, 4), conv_nonlin=getattr(torch.nn.functional, self.activation), drop_prob=0.1).create_network() return model
def run_exp(max_recording_mins, n_recordings, sec_to_cut, duration_recording_mins, max_abs_val, shrink_val, sampling_freq, divisor, n_folds, i_test_fold, final_conv_length, model_constraint, batch_size, max_epochs, n_filters_time, n_filters_spat, filter_time_length, conv_nonlin, pool_time_length, pool_time_stride, pool_mode, pool_nonlin, split_first_layer, do_batch_norm, drop_prob, time_cut_off_sec, start_time, input_time_length, only_return_exp): kwargs = locals() for model_param in [ 'final_conv_length', 'n_filters_time', 'n_filters_spat', 'filter_time_length', 'conv_nonlin', 'pool_time_length', 'pool_time_stride', 'pool_mode', 'pool_nonlin', 'split_first_layer', 'do_batch_norm', 'drop_prob', ]: kwargs.pop(model_param) nonlin_dict = { 'elu': elu, 'relu': relu, 'relu6': relu6, 'tanh': tanh, 'square': square, 'identity': identity, 'log': safe_log, } assert input_time_length == 6000 # copy over from early seizure # make proper n_classes = 2 in_chans = 21 cuda = True set_random_seeds(seed=20170629, cuda=cuda) model = ShallowFBCSPNet(in_chans=in_chans, n_classes=n_classes, input_time_length=input_time_length, final_conv_length=final_conv_length, n_filters_time=n_filters_time, filter_time_length=filter_time_length, n_filters_spat=n_filters_spat, pool_time_length=pool_time_length, pool_time_stride=pool_time_stride, conv_nonlin=nonlin_dict[conv_nonlin], pool_mode=pool_mode, pool_nonlin=nonlin_dict[pool_nonlin], split_first_layer=split_first_layer, batch_norm=do_batch_norm, batch_norm_alpha=0.1, drop_prob=drop_prob).create_network() to_dense_prediction_model(model) if cuda: model.cuda() model.eval() test_input = np_to_var( np.ones((2, in_chans, input_time_length, 1), dtype=np.float32)) if cuda: test_input = test_input.cuda() try: out = model(test_input) except RuntimeError: raise ValueError("Model receptive field too large...") n_preds_per_input = out.cpu().data.numpy().shape[2] n_receptive_field = input_time_length - n_preds_per_input if n_receptive_field > 6000: raise ValueError("Model receptive field ({:d}) too large...".format( n_receptive_field)) # For future, here optionally add input time length instead model = ShallowFBCSPNet(in_chans=in_chans, n_classes=n_classes, input_time_length=input_time_length, final_conv_length=final_conv_length, n_filters_time=n_filters_time, filter_time_length=filter_time_length, n_filters_spat=n_filters_spat, pool_time_length=pool_time_length, pool_time_stride=pool_time_stride, conv_nonlin=nonlin_dict[conv_nonlin], pool_mode=pool_mode, pool_nonlin=nonlin_dict[pool_nonlin], split_first_layer=split_first_layer, batch_norm=do_batch_norm, batch_norm_alpha=0.1, drop_prob=drop_prob).create_network() return common.run_exp(model=model, **kwargs)
def run_exp(data_folder, session_id, subject_id, low_cut_hz, model, cuda): ival = [-500, 4000] max_epochs = 1600 max_increase_epochs = 160 batch_size = 10 high_cut_hz = 38 factor_new = 1e-3 init_block_size = 1000 valid_set_fraction = .2 ''' # BCIcompetition train_filename = 'A{:02d}T.gdf'.format(subject_id) test_filename = 'A{:02d}E.gdf'.format(subject_id) train_filepath = os.path.join(data_folder, train_filename) test_filepath = os.path.join(data_folder, test_filename) train_label_filepath = train_filepath.replace('.gdf', '.mat') test_label_filepath = test_filepath.replace('.gdf', '.mat') train_loader = BCICompetition4Set2A( train_filepath, labels_filename=train_label_filepath) test_loader = BCICompetition4Set2A( test_filepath, labels_filename=test_label_filepath) train_cnt = train_loader.load() test_cnt = test_loader.load() ''' # GIGAscience filename = 'sess{:02d}_subj{:02d}_EEG_MI.mat'.format( session_id, subject_id) filepath = os.path.join(data_folder, filename) train_variable = 'EEG_MI_train' test_variable = 'EEG_MI_test' train_loader = GIGAscience(filepath, train_variable) test_loader = GIGAscience(filepath, test_variable) train_cnt = train_loader.load() test_cnt = test_loader.load() # Preprocessing ''' channel ['Fp1', 'Fp2', 'F7', 'F3', 'Fz', 'F4', 'F8', 'FC5', 'FC1', 'FC2', 'FC6', 'T7', 'C3', 'Cz', 'C4', 'T8', 'TP9', 'CP5', 'CP1', 'CP2', 'CP6', 'TP10', 'P7', 'P3', 'Pz', 'P4', 'P8', 'PO9', 'O1', 'Oz', 'O2', 'PO10', 'FC3', 'FC4', 'C5', 'C1', 'C2', 'C6', 'CP3', 'CPz', 'CP4', 'P1', 'P2', 'POz', 'FT9', 'FTT9h', 'TTP7h', 'TP7', 'TPP9h', 'FT10', 'FTT10h', 'TPP8h', 'TP8', 'TPP10h', 'F9', 'F10', 'AF7', 'AF3', 'AF4', 'AF8', 'PO3', 'PO4'] ''' train_cnt = train_cnt.pick_channels([ 'FC5', 'FC3', 'FC1', 'Fz', 'FC2', 'FC4', 'FC6', 'C5', 'C3', 'C1', 'Cz', 'C2', 'C4', 'C6', 'CP5', 'CP3', 'CP1', 'CPz', 'CP2', 'CP4', 'CP6', 'Pz' ]) train_cnt, train_cnt.info['events'] = train_cnt.copy().resample( 250, npad='auto', events=train_cnt.info['events']) assert len(train_cnt.ch_names) == 22 # lets convert to millvolt for numerical stability of next operations train_cnt = mne_apply(lambda a: a * 1e6, train_cnt) train_cnt = mne_apply( lambda a: bandpass_cnt(a, low_cut_hz, high_cut_hz, train_cnt.info['sfreq'], filt_order=3, axis=1), train_cnt) train_cnt = mne_apply( lambda a: exponential_running_standardize(a.T, factor_new=factor_new, init_block_size= init_block_size, eps=1e-4).T, train_cnt) test_cnt = test_cnt.pick_channels([ 'FC5', 'FC3', 'FC1', 'Fz', 'FC2', 'FC4', 'FC6', 'C5', 'C3', 'C1', 'Cz', 'C2', 'C4', 'C6', 'CP5', 'CP3', 'CP1', 'CPz', 'CP2', 'CP4', 'CP6', 'Pz' ]) test_cnt, test_cnt.info['events'] = test_cnt.copy().resample( 250, npad='auto', events=test_cnt.info['events']) assert len(test_cnt.ch_names) == 22 test_cnt = mne_apply(lambda a: a * 1e6, test_cnt) test_cnt = mne_apply( lambda a: bandpass_cnt(a, low_cut_hz, high_cut_hz, test_cnt.info['sfreq'], filt_order=3, axis=1), test_cnt) test_cnt = mne_apply( lambda a: exponential_running_standardize(a.T, factor_new=factor_new, init_block_size= init_block_size, eps=1e-4).T, test_cnt) marker_def = OrderedDict([('Right Hand', [1]), ('Left Hand', [2])]) train_set = create_signal_target_from_raw_mne(train_cnt, marker_def, ival) test_set = create_signal_target_from_raw_mne(test_cnt, marker_def, ival) train_set, valid_set = split_into_two_sets(train_set, first_set_fraction=1 - valid_set_fraction) set_random_seeds(seed=20190706, cuda=cuda) n_classes = 2 n_chans = int(train_set.X.shape[1]) input_time_length = train_set.X.shape[2] if model == 'shallow': model = ShallowFBCSPNet(n_chans, n_classes, input_time_length=input_time_length, final_conv_length='auto').create_network() elif model == 'deep': model = Deep4Net(n_chans, n_classes, input_time_length=input_time_length, final_conv_length='auto').create_network() if cuda: model.cuda() log.info("Model: \n{:s}".format(str(model))) optimizer = optim.Adam(model.parameters()) iterator = BalancedBatchSizeIterator(batch_size=batch_size) stop_criterion = Or([ MaxEpochs(max_epochs), NoDecrease('valid_misclass', max_increase_epochs) ]) monitors = [LossMonitor(), MisclassMonitor(), RuntimeMonitor()] model_constraint = MaxNormDefaultConstraint() exp = Experiment(model, train_set, valid_set, test_set, iterator=iterator, loss_function=F.nll_loss, optimizer=optimizer, model_constraint=model_constraint, monitors=monitors, stop_criterion=stop_criterion, remember_best_column='valid_misclass', run_after_early_stop=True, cuda=cuda) exp.run() return exp
def run_exp(data_folder, subject_id, low_cut_hz, model, cuda): train_filename = 'A{:02d}T.gdf'.format(subject_id) test_filename = 'A{:02d}E.gdf'.format(subject_id) train_filepath = os.path.join(data_folder, train_filename) test_filepath = os.path.join(data_folder, test_filename) train_label_filepath = train_filepath.replace('.gdf', '.mat') test_label_filepath = test_filepath.replace('.gdf', '.mat') train_loader = BCICompetition4Set2A(train_filepath, labels_filename=train_label_filepath) test_loader = BCICompetition4Set2A(test_filepath, labels_filename=test_label_filepath) train_cnt = train_loader.load() test_cnt = test_loader.load() # Preprocessing train_cnt = train_cnt.drop_channels( ['STI 014', 'EOG-left', 'EOG-central', 'EOG-right']) assert len(train_cnt.ch_names) == 22 # lets convert to millvolt for numerical stability of next operations train_cnt = mne_apply(lambda a: a * 1e6, train_cnt) train_cnt = mne_apply( lambda a: bandpass_cnt( a, low_cut_hz, 38, train_cnt.info['sfreq'], filt_order=3, axis=1), train_cnt) train_cnt = mne_apply( lambda a: exponential_running_standardize( a.T, factor_new=1e-3, init_block_size=1000, eps=1e-4).T, train_cnt) test_cnt = test_cnt.drop_channels( ['STI 014', 'EOG-left', 'EOG-central', 'EOG-right']) assert len(test_cnt.ch_names) == 22 test_cnt = mne_apply(lambda a: a * 1e6, test_cnt) test_cnt = mne_apply( lambda a: bandpass_cnt( a, low_cut_hz, 38, test_cnt.info['sfreq'], filt_order=3, axis=1), test_cnt) test_cnt = mne_apply( lambda a: exponential_running_standardize( a.T, factor_new=1e-3, init_block_size=1000, eps=1e-4).T, test_cnt) marker_def = OrderedDict([('Left Hand', [1]), ( 'Right Hand', [2], ), ('Foot', [3]), ('Tongue', [4])]) ival = [-500, 4000] train_set = create_signal_target_from_raw_mne(train_cnt, marker_def, ival) test_set = create_signal_target_from_raw_mne(test_cnt, marker_def, ival) train_set, valid_set = split_into_two_sets(train_set, first_set_fraction=0.8) set_random_seeds(seed=20190706, cuda=cuda) n_classes = 4 n_chans = int(train_set.X.shape[1]) input_time_length = train_set.X.shape[2] if model == 'shallow': model = ShallowFBCSPNet(n_chans, n_classes, input_time_length=input_time_length, final_conv_length='auto').create_network() elif model == 'deep': model = Deep4Net(n_chans, n_classes, input_time_length=input_time_length, final_conv_length='auto').create_network() if cuda: model.cuda() log.info("Model: \n{:s}".format(str(model))) optimizer = optim.Adam(model.parameters()) iterator = BalancedBatchSizeIterator(batch_size=60) stop_criterion = Or([MaxEpochs(1600), NoDecrease('valid_misclass', 160)]) monitors = [LossMonitor(), MisclassMonitor(), RuntimeMonitor()] model_constraint = MaxNormDefaultConstraint() exp = Experiment(model, train_set, valid_set, test_set, iterator=iterator, loss_function=F.nll_loss, optimizer=optimizer, model_constraint=model_constraint, monitors=monitors, stop_criterion=stop_criterion, remember_best_column='valid_misclass', run_after_early_stop=True, cuda=cuda) exp.run() return exp
train_set = SignalAndTarget(train_X, y=train_y) test_set = SignalAndTarget(test_X, y=test_y) # Set if you want to use GPU # You can also use torch.cuda.is_available() to determine if cuda is available on your machine. cuda = True set_random_seeds(seed=20170629, cuda=cuda) # This will determine how many crops are processed in parallel input_time_length = train_set.X.shape[2] n_classes = 2 in_chans = train_set.X.shape[1] # final_conv_length determines the size of the receptive field of the ConvNet model = ShallowFBCSPNet(in_chans=in_chans, n_classes=n_classes, input_time_length=input_time_length, final_conv_length=12).create_network() model # model = Deep4Net(in_chans=in_chans, n_classes=n_classes, input_time_length=input_time_length, # final_conv_length=12).create_network() to_dense_prediction_model(model) if cuda: model.cuda() optimizer = optim.Adam(model.parameters()) # determine output size test_input = np_to_var(
cuda = torch.cuda.is_available() # cuda = False if cuda: device = "cuda" else: device = "cpu" set_random_seeds(seed=20190706, cuda=cuda) input_time_length = 1000 n_classes = 4 n_chans = 26 # TODO: should be 22 of course if model_name == "shallow": model = ShallowFBCSPNet( n_chans, n_classes, input_time_length=input_time_length, final_conv_length=30, ) elif model_name == "deep": model = Deep4Net( n_chans, n_classes, input_time_length=input_time_length, final_conv_length=2, ) to_dense_prediction_model(model) if cuda: model.cuda()