コード例 #1
0
    def _create_robintibor_balanced_folds(self):
        """
        OLD BALANCED BATCHES ROUTINE
        ----------------------------
        Using robintibor ml routine
        """
        # getting pseudo-random folds
        folds = get_balanced_batches(n_trials=self.n_trials,
                                     rng=self.random_state,
                                     shuffle=self.shuffle,
                                     n_batches=self.n_folds)

        # train is everything except fold; test is fold indexes
        self.folds = [{
            'train': setdiff1d(arange(self.n_trials), fold),
            'valid': None,
            'test': fold
        } for fold in folds]

        # getting validation and reshaping train
        for idx, current_fold in enumerate(self.folds):
            self.folds[idx]['valid'] = \
                current_fold['train'][-self.validation_size:]
            self.folds[idx]['train'] = \
                current_fold['train'][:-self.validation_size]
コード例 #2
0
def split_into_train_test(dataset, n_folds, i_test_fold, rng=None):
    """
     Split datasets into folds, select one test fold and merge rest as train fold.

    Parameters
    ----------
    dataset: :class:`.SignalAndTarget`
    n_folds: int
        Number of folds to split dataset into.
    i_test_fold: int
        Index of the test fold (0-based)
    rng: `numpy.random.RandomState`, optional
        Random Generator for shuffling, None means no shuffling

    Returns
    -------
    reduced_set: :class:`.SignalAndTarget`
        Dataset with only examples selected.
    """
    n_trials = len(dataset.X)
    if n_trials < n_folds:
        raise ValueError("Less Trials: {:d} than folds: {:d}".format(
            n_trials, n_folds))
    shuffle = rng is not None
    folds = get_balanced_batches(n_trials, rng, shuffle, n_batches=n_folds)
    test_inds = folds[i_test_fold]
    all_inds = list(range(n_trials))
    train_inds = np.setdiff1d(all_inds, test_inds)
    assert np.intersect1d(train_inds, test_inds).size == 0
    assert np.array_equal(np.sort(np.union1d(train_inds, test_inds)), all_inds)

    train_set = select_examples(dataset, train_inds)
    test_set = select_examples(dataset, test_inds)
    return train_set, test_set
コード例 #3
0
    def split(
        self,
        X,
        y,
    ):
        if len(X) < self.n_folds:
            raise ValueError("Less Trials: {:d} than folds: {:d}".format(
                len(X), self.n_folds))
        folds = get_balanced_batches(len(X),
                                     self.rng,
                                     self.shuffle,
                                     n_batches=self.n_folds)
        test_inds = folds[self.i_test_fold]
        valid_inds = folds[self.i_test_fold - 1]
        all_inds = list(range(len(X)))
        train_inds = np.setdiff1d(all_inds, np.union1d(test_inds, valid_inds))
        assert np.intersect1d(train_inds, valid_inds).size == 0
        assert np.intersect1d(train_inds, test_inds).size == 0
        assert np.intersect1d(valid_inds, test_inds).size == 0
        assert np.array_equal(
            np.sort(np.union1d(train_inds, np.union1d(valid_inds, test_inds))),
            all_inds)

        train_set = create_set(X, y, train_inds)
        valid_set = create_set(X, y, valid_inds)
        test_set = create_set(X, y, test_inds)

        return train_set, valid_set, test_set
コード例 #4
0
def perturbation_correlation(pert_fn, diff_fn, pred_fn, n_layers, inputs, n_iterations,
                                                  batch_size=30,
                                                  seed=((2017, 7, 10))):
    """
    Calculates phase perturbation correlation for layers in network
    
    pred_fn: Function that returns a list of activations.
             Each entry in the list corresponds to the output of 1 layer in a network
    n_layers: Number of layers pred_fn returns activations for.
    inputs: Original inputs that are used for perturbation [B,X,T,1]
            Phase perturbations are sampled for each input individually, but applied to all X of that input
    n_iterations: Number of iterations of correlation computation. The higher the better
    batch_size: Number of inputs that are used for one forward pass. (Concatenated for all inputs)
    """
    rng = np.random.RandomState(seed)
    
    # Get batch indeces
    batch_inds = get_balanced_batches(
        n_trials=len(inputs), rng=rng, shuffle=False, batch_size=batch_size)
    
    # Calculate layer activations and reshape
    orig_preds = [pred_fn(inputs[inds])
                  for inds in batch_inds]
    orig_preds_layers = [np.concatenate([orig_preds[o][l] for o in range(len(orig_preds))])
                        for l in range(n_layers)]
    
    # Compute FFT of inputs
    fft_input = np.fft.rfft(inputs, n=inputs.shape[2], axis=2)
    amps = np.abs(fft_input)
    phases = np.angle(fft_input)
    
    pert_corrs = [0]*n_layers
    for i in range(n_iterations):
        #print('Iteration%d'%i)
        
        amps_pert,phases_pert,pert_vals = pert_fn(amps,phases,rng=rng)
        
        # Compute perturbed inputs
        fft_pert = amps_pert*np.exp(1j*phases_pert)
        inputs_pert = np.fft.irfft(fft_pert, n=inputs.shape[2], axis=2).astype(np.float32)
        
        # Calculate layer activations for perturbed inputs
        new_preds = [pred_fn(inputs_pert[inds])
                     for inds in batch_inds]
        new_preds_layers = [np.concatenate([new_preds[o][l] for o in range(len(new_preds))])
                        for l in range(n_layers)]
        
        for l in range(n_layers):
            # Calculate correlations of original and perturbed feature map activations
            preds_diff = diff_fn(orig_preds_layers[l][:,:,:,0],new_preds_layers[l][:,:,:,0])
            
            # Calculate feature map correlations with absolute phase perturbations
            pert_corrs_tmp = wrap_reshape_apply_fn(corr,
                                                   pert_vals[:,:,:,0],preds_diff,
                                                   axis_a=(0), axis_b=(0))
            pert_corrs[l] += pert_corrs_tmp
            
    pert_corrs = [pert_corrs[l]/n_iterations for l in range(n_layers)] #mean over iterations
    return pert_corrs
コード例 #5
0
    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
コード例 #6
0
 def get_batches(self, dataset, shuffle):
     n_trials = dataset.X.shape[0]
     batches = get_balanced_batches(n_trials,
                                    batch_size=self.batch_size,
                                    rng=self.rng,
                                    shuffle=shuffle)
     for batch_inds in batches:
         batch_X = dataset.X[batch_inds]
         batch_y = dataset.y[batch_inds]
         batch_X = turn_dataset_to_timefreq(batch_X)
         # add empty fourth dimension if necessary
         if batch_X.ndim == 3:
             batch_X = batch_X[:, :, :, None]
         yield (batch_X, batch_y)
コード例 #7
0
    def init_training_vars(self):
        self.filterbands = generate_filterbank(
            min_freq=self.min_freq,
            max_freq=self.max_freq, last_low_freq=self.last_low_freq, 
            low_width=self.low_width, low_overlap=self.low_overlap,
            high_width=self.high_width, high_overlap=self.high_overlap,
            low_bound=self.low_bound)
        assert filterbank_is_stable(
            self.filterbands, self.filt_order,
            self.cnt.info['sfreq']), (
                "Expect filter bank to be stable given filter order.")
        # check if number of selected features is not too large
        if self.n_selected_features is not None:
            n_spatial_filters = self.n_top_bottom_csp_filters
            if n_spatial_filters is None:
                n_spatial_filters = len(self.cnt.ch_names)
            n_max_features = len(self.filterbands) * n_spatial_filters
            assert n_max_features >= self.n_selected_features, (
                "Cannot select more features than will be originally created "
                "Originally: {:d}, requested: {:d}".format(
                    n_max_features, self.n_selected_features)
            )

        n_classes = len(self.name_to_start_codes)
        self.class_pairs = list(itertools.combinations(range(n_classes),2))
        # use only number of clean trials to split folds
        epo = create_signal_target_from_raw_mne(
            self.cnt, name_to_start_codes=self.name_to_start_codes,
            epoch_ival_ms=self.epoch_ival_ms,
            name_to_stop_codes=self.name_to_stop_codes)
        n_trials = len(epo.X)
        if self.restricted_n_trials is not None:
            if self.restricted_n_trials <= 1:
                n_trials = int(n_trials * self.restricted_n_trials)
            else:
                n_trials = min(n_trials, self.restricted_n_trials)
        rng = RandomState(903372376)
        folds = get_balanced_batches(n_trials, rng, self.shuffle,
                                     n_batches=self.n_folds)

        # remap to original indices in unclean set(!)
        # train is everything except fold
        # test is fold inds
        self.folds = [{'train': np.setdiff1d(np.arange(n_trials),fold),
             'test': fold}
                      for fold in folds]
        if self.only_last_fold:
            self.folds = self.folds[-1:]
コード例 #8
0
ファイル: deep4.py プロジェクト: kahartma/eeggan
    def get_batches(self, dataset, shuffle):
        n_trials = dataset.X.shape[0]
        batch_size_fake = int(np.ceil(self.batch_size * self.ratio))
        batch_size_real = self.batch_size - batch_size_fake
        batches = get_balanced_batches(n_trials,
                                       batch_size=batch_size_real,
                                       rng=self.rng,
                                       shuffle=shuffle)
        for batch_inds in batches:
            batch_X = dataset.X[batch_inds]
            batch_y = dataset.y[batch_inds]

            fake_X, fake_y = self.trial_generator(batch_size_fake)
            batch_X = np.concatenate((batch_X, fake_X))
            batch_y = np.concatenate((batch_y, fake_y))

            # add empty fourth dimension if necessary
            if batch_X.ndim == 3:
                batch_X = batch_X[:, :, :, None]
            yield (batch_X, batch_y)
コード例 #9
0
    def split(self, X, y):
        folds = get_balanced_batches(len(X),
                                     None,
                                     False,
                                     n_batches=self.n_folds)
        test_inds = folds[self.i_test_fold]
        valid_inds = folds[self.i_test_fold - 1]
        all_inds = list(range(len(X)))
        train_inds = np.setdiff1d(all_inds, np.union1d(test_inds, valid_inds))
        assert np.intersect1d(train_inds, valid_inds).size == 0
        assert np.intersect1d(train_inds, test_inds).size == 0
        assert np.intersect1d(valid_inds, test_inds).size == 0
        assert np.array_equal(
            np.sort(np.union1d(train_inds, np.union1d(valid_inds, test_inds))),
            all_inds)

        train_set = create_set(X, y, train_inds)
        valid_set = create_set(X, y, valid_inds)
        test_set = create_set(X, y, test_inds)

        return train_set, valid_set, test_set
コード例 #10
0
    def _get_batch_indeces(self, dataset, shuffle):
        # start always at first predictable sample, so
        # start at end of receptive field
        n_receptive_field = self.input_time_length - self.n_preds_per_input + 1
        i_trial_starts = [n_receptive_field - 1] * len(dataset.X)
        i_trial_stops = [trial.shape[1] for trial in dataset.X]

        # Check whether input lengths ok
        input_lens = i_trial_stops
        for i_trial, input_len in enumerate(input_lens):
            assert input_len >= self.input_time_length, (
                "Input length {:d} of trial {:d} is smaller than the "
                "input time length {:d}".format(input_len, i_trial,
                                                self.input_time_length))

        start_stop_blocks_per_trial = _compute_start_stop_block_inds(
            i_trial_starts,
            i_trial_stops,
            self.input_time_length,
            self.n_preds_per_input,
            check_preds_smaller_trial_len=self.check_preds_smaller_trial_len,
        )
        for i_trial, trial_blocks in enumerate(start_stop_blocks_per_trial):
            assert trial_blocks[0][0] == 0
            assert trial_blocks[-1][1] == i_trial_stops[i_trial]

        i_trial_start_stop_block = np.array([
            (i_trial, start, stop)
            for i_trial, block in enumerate(start_stop_blocks_per_trial)
            for start, stop in block
        ])

        batches = get_balanced_batches(
            n_trials=len(i_trial_start_stop_block),
            rng=self.rng,
            shuffle=shuffle,
            batch_size=self.batch_size,
        )

        return [i_trial_start_stop_block[batch_ind] for batch_ind in batches]
コード例 #11
0
    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)

        self.adjust_learning_rate(self.optimizer, i_epoch)

        # 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
コード例 #12
0
ファイル: filterbank.py プロジェクト: zhangys2019/fbcsp
    def cross_validate_lda(features):
        n_trials = features.X.shape[0]
        folds = get_balanced_batches(n_trials,
                                     rng=None,
                                     shuffle=False,
                                     n_batches=5)
        # make to train-test splits, fold is test part..
        folds = [(np.setdiff1d(np.arange(n_trials), fold), fold)
                 for fold in folds]
        test_accuracies = []
        for train_inds, test_inds in folds:
            train_features = select_trials(features, train_inds)
            test_features = select_trials(features, test_inds)
            clf = lda_train_scaled(train_features, shrink=True)
            test_out = lda_apply(test_features, clf)

            higher_class = np.max(test_features.y)
            true_0_1_labels_test = test_features.y == higher_class

            predicted_test = test_out >= 0
            test_accuracy = np.mean(true_0_1_labels_test == predicted_test)
            test_accuracies.append(test_accuracy)
        return np.mean(test_accuracies)
コード例 #13
0
    def get_batches(self, dataset, shuffle):
        n_trials = dataset.y['source'].shape[0]
        batches = get_balanced_batches(n_trials,
                                       batch_size=self.batch_size,
                                       rng=self.rng,
                                       shuffle=shuffle)
        for batch_inds in batches:
            batch_inds = np.array(batch_inds)
            batch_X = {
                'source': dataset.X['source'][batch_inds],
                'target': dataset.X['target'][batch_inds]
            }
            batch_y = {
                'source': dataset.y['source'][batch_inds],
                'target': dataset.y['target'][batch_inds]
            }

            # add empty fourth dimension if necessary
            if batch_X['source'].ndim == 3:
                batch_X['source'] = batch_X['source'][:, :, :, None]
            if batch_X['target'].ndim == 3:
                batch_X['target'] = batch_X['target'][:, :, :, None]

            yield (batch_X, batch_y)
コード例 #14
0
    def create_folds(self):
        if self.cross_subject_computation is True:
            # in case of cross-subject computation
            folds = [
                arange(self.cross_subject_object.subject_indexes[x][0],
                       self.cross_subject_object.subject_indexes[x][1])
                for x in range(len(self.cross_subject_object.subject_indexes))
            ]
            self.n_folds = len(folds)
            self.folds = [{
                'train': setdiff1d(arange(self.n_trials), fold),
                'test': fold
            } for fold in folds]
        elif self.load_fold_from_file is True:
            # in case of pre-batched computation
            self.folds = np.load(self.fold_file)['folds']
        elif self.n_folds == 0:
            self.n_folds = 1

            # creating schirrmeister fold
            all_idxs = np.array(range(len(self.clean_trial_mask)))
            self.folds = [{'train': all_idxs[:-160], 'test': all_idxs[-160:]}]
            self.folds[0]['train'] = self.folds[0]['train'][
                self.clean_trial_mask[:-160]]
            self.folds[0]['test'] = self.folds[0]['test'][
                self.clean_trial_mask[-160:]]
        else:
            # getting pseudo-random folds
            folds = get_balanced_batches(n_trials=self.n_trials,
                                         rng=self.random_state,
                                         shuffle=self.shuffle,
                                         n_batches=self.n_folds)
            self.folds = [{
                'train': setdiff1d(arange(self.n_trials), fold),
                'test': fold
            } for fold in folds]
コード例 #15
0
def compute_amplitude_prediction_correlations_voltage(pred_fn,
                                                      examples,
                                                      n_iterations,
                                                      perturb_fn=None,
                                                      batch_size=30,
                                                      seed=((2017, 7, 10))):
    """
    Changed function to calculate time-resolved voltage pertubations, and not frequency as original in compute_amplitude_prediction_correlations

    Perturb input amplitudes and compute correlation between amplitude
    perturbations and prediction changes when pushing perturbed input through
    the prediction function.    
    For more details, see [EEGDeepLearning]_.
    Parameters
    ----------
    pred_fn: function
    Function accepting an numpy input and returning prediction.
    examples: ndarray
    Numpy examples, first axis should be example axis.
    n_iterations: int
    Number of iterations to compute.
    perturb_fn: function, optional
    Function accepting amplitude array and random generator and returning
    perturbation. Default is Gaussian perturbation.
    batch_size: int, optional
    Batch size for computing predictions.
    seed: int, optional
    Random generator seed
    Returns
    -------
    amplitude_pred_corrs: ndarray
    Correlations between amplitude perturbations and prediction changes
    for all sensors and frequency bins.
    References
    ----------
    .. [EEGDeepLearning] Schirrmeister, R. T., Springenberg, J. T., Fiederer, L. D. J.,
    Glasstetter, M., Eggensperger, K., Tangermann, M., ... & Ball, T. (2017).
    Deep learning with convolutional neural networks for EEG decoding and
    visualization.
    arXiv preprint arXiv:1703.05051.
    """
    inds_per_batch = get_balanced_batches(n_trials=len(examples),
                                          rng=None,
                                          shuffle=False,
                                          batch_size=batch_size)
    log.info("Compute original predictions...")
    orig_preds = [
        pred_fn(examples[example_inds]) for example_inds in inds_per_batch
    ]
    orig_preds_arr = np.concatenate(orig_preds)
    rng = RandomState(seed)
    fft_input = np.fft.rfft(examples, axis=2)
    amps = np.abs(fft_input)
    phases = np.angle(fft_input)

    amp_pred_corrs = []
    for i_iteration in range(n_iterations):
        log.info("Iteration {:d}...".format(i_iteration))
        log.info("Sample perturbation...")
        #modified part start
        perturbation = rng.randn(*examples.shape)
        new_in = examples + perturbation
        #modified part end
        log.info("Compute new predictions...")
        new_in = new_in.astype('float32')
        new_preds = [
            pred_fn(new_in[example_inds]) for example_inds in inds_per_batch
        ]

        new_preds_arr = np.concatenate(new_preds)

        diff_preds = new_preds_arr - orig_preds_arr

        log.info("Compute correlation...")
        amp_pred_corr = wrap_reshape_apply_fn(corr,
                                              perturbation[:, :, :, 0],
                                              diff_preds,
                                              axis_a=(0, ),
                                              axis_b=(0))
        amp_pred_corrs.append(amp_pred_corr)
    return amp_pred_corrs
コード例 #16
0
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)
コード例 #17
0
def compute_amplitude_prediction_correlations_batchwise(
        pred_fn,
        examples,
        n_iterations,
        perturb_fn=gaussian_perturbation,
        batch_size=30,
        seed=((2017, 7, 10)),
        original_y=None,
):
    """
    Perturb input amplitudes and compute correlation between amplitude
    perturbations and prediction changes when pushing perturbed input through
    the prediction function.

    For more details, see [EEGDeepLearning]_.

    Parameters
    ----------
    pred_fn: function
        Function accepting an numpy input and returning prediction.
    examples: ndarray
        Numpy examples, first axis should be example axis.
    n_iterations: int
        Number of iterations to compute.
    perturb_fn: function, optional
        Function accepting amplitude array and random generator and returning
        perturbation. Default is Gaussian perturbation.
    batch_size: int, optional
        Batch size for computing predictions.
    seed: int, optional
        Random generator seed

    Returns
    -------
    amplitude_pred_corrs: ndarray
        Correlations between amplitude perturbations and prediction changes
        for all sensors and frequency bins.

    References
    ----------

    .. [EEGDeepLearning] Schirrmeister, R. T., Springenberg, J. T., Fiederer, L. D. J.,
       Glasstetter, M., Eggensperger, K., Tangermann, M., ... & Ball, T. (2017).
       Deep learning with convolutional neural networks for EEG decoding and
       visualization.
       arXiv preprint arXiv:1703.05051.
    """
    inds_per_batch = get_balanced_batches(n_trials=len(examples),
                                          rng=None,
                                          shuffle=False,
                                          batch_size=batch_size)
    log.info("Compute original predictions...")
    orig_preds = [
        pred_fn(examples[example_inds]) for example_inds in inds_per_batch
    ]
    orig_preds_arr = np.concatenate(orig_preds)
    if original_y is not None:
        orig_pred_labels = np.argmax(orig_preds_arr, axis=1)
        orig_accuracy = np.mean(orig_pred_labels == original_y)
        log.info("Original accuracy: {:.2f}...".format(orig_accuracy))
    amp_pred_corrs = []
    new_accuracies = []
    rng = RandomState(seed)
    for i_iteration in range(n_iterations):
        log.info("Iteration {:d}...".format(i_iteration))
        size_so_far = 0
        mean_perturb_so_far = None
        mean_pred_diff_so_far = None
        var_perturb_so_far = None
        var_pred_diff_so_far = None
        covariance_so_far = None
        all_new_pred_labels = []
        for example_inds in inds_per_batch:
            this_orig_preds = orig_preds_arr[example_inds]
            this_examples = examples[example_inds]
            fft_input = np.fft.rfft(this_examples, axis=2).astype(np.complex64)
            amps = np.abs(fft_input).astype(np.float32)
            phases = np.angle(fft_input).astype(np.float32)
            #log.info("Sample perturbation...")
            perturbation = perturb_fn(amps, rng).astype(np.float32)
            #log.info("Compute new amplitudes...")
            # do not allow perturbation to make amplitudes go below
            # zero
            perturbation = np.maximum(-amps, perturbation)
            new_amps = amps + perturbation
            new_amps = new_amps.astype(np.float32)
            #log.info("Compute new  complex inputs...")
            new_complex = _amplitude_phase_to_complex(new_amps, phases).astype(
                np.complex64)
            #log.info("Compute new real inputs...")
            new_in = np.fft.irfft(new_complex, axis=2).astype(np.float32)
            #log.info("Compute new predictions...")
            new_preds_arr = pred_fn(new_in)
            if original_y is not None:
                new_pred_labels = np.argmax(new_preds_arr, axis=1)
                all_new_pred_labels.append(new_pred_labels)
            diff_preds = new_preds_arr - this_orig_preds
            this_amp_pred_cov = wrap_reshape_apply_fn(cov,
                                                      perturbation[:, :, :, 0],
                                                      diff_preds,
                                                      axis_a=(0, ),
                                                      axis_b=(0))
            var_perturb = np.var(perturbation, axis=0, ddof=1)
            var_pred_diff = np.var(diff_preds, axis=0, ddof=1)
            mean_perturb = np.mean(perturbation, axis=0)
            mean_diff_pred = np.mean(diff_preds)
            if mean_perturb_so_far is None:
                mean_perturb_so_far = mean_perturb
                mean_pred_diff_so_far = mean_diff_pred
                covariance_so_far = this_amp_pred_cov
                var_perturb_so_far = var_perturb
                var_pred_diff_so_far = var_pred_diff
            else:
                covariance_so_far = combine_covs(covariance_so_far,
                                                 size_so_far,
                                                 mean_perturb_so_far,
                                                 mean_pred_diff_so_far,
                                                 this_amp_pred_cov,
                                                 len(example_inds),
                                                 mean_perturb, mean_diff_pred)
                var_perturb_so_far = combine_vars(
                    var_perturb_so_far,
                    size_so_far,
                    mean_perturb_so_far,
                    var_perturb,
                    len(example_inds),
                    mean_perturb,
                )
                var_pred_diff_so_far = combine_vars(
                    var_pred_diff_so_far,
                    size_so_far,
                    mean_pred_diff_so_far,
                    var_pred_diff,
                    len(example_inds),
                    mean_diff_pred,
                )
                next_size = size_so_far + len(example_inds)
                mean_perturb_so_far = (
                    (mean_perturb_so_far * size_so_far / float(next_size)) +
                    (mean_perturb * len(example_inds) / float(next_size)))
                mean_pred_diff_so_far = (
                    (mean_pred_diff_so_far * size_so_far / float(next_size)) +
                    (mean_diff_pred * len(example_inds) / float(next_size)))

            size_so_far += len(example_inds)

        all_new_pred_labels = np.concatenate(all_new_pred_labels)
        new_accuracy = np.mean(all_new_pred_labels == original_y)
        assert len(original_y) == len(all_new_pred_labels)
        log.info("New accuracy: {:.2f}...".format(new_accuracy))
        new_accuracies.append(new_accuracy)
        divisor = np.outer(np.sqrt(var_perturb_so_far),
                           np.sqrt(var_pred_diff_so_far)).reshape(
                               (var_perturb_so_far.shape +
                                var_pred_diff_so_far.shape)).squeeze()
        this_amp_pred_corr = covariance_so_far / divisor
        amp_pred_corrs.append(this_amp_pred_corr)
    if original_y is not None:
        return amp_pred_corrs, orig_accuracy, new_accuracies
    else:
        return amp_pred_corrs
コード例 #18
0
ファイル: run.py プロジェクト: neuroidss/EEG-GAN
z_vars_im = rng.normal(0,1,size=(1000,n_z)).astype(np.float32)

for i_block in range(i_block_tmp,n_blocks):
    c = 0

    train_tmp = discriminator.model.downsample_to_block(Variable(torch.from_numpy(train).cuda(),volatile=True),discriminator.model.cur_block).data.cpu()

    for i_epoch in range(i_epoch_tmp,block_epochs[i_block]):
        i_epoch_tmp = 0

        if fade_alpha<1:
            fade_alpha += 1./rampup
            generator.model.alpha = fade_alpha
            discriminator.model.alpha = fade_alpha

        batches = get_balanced_batches(train.shape[0], rng, True, batch_size=n_batch)
        iters = int(len(batches)/n_critic)

        for it in range(iters):
            for i_critic in range(n_critic):
                train_batches = train_tmp[batches[it*n_critic+i_critic]]
                batch_real = Variable(train_batches,requires_grad=True).cuda()

                z_vars = rng.normal(0,1,size=(len(batches[it*n_critic+i_critic]),n_z)).astype(np.float32)
                z_vars = Variable(torch.from_numpy(z_vars),volatile=True).cuda()
                batch_fake = Variable(generator(z_vars).data,requires_grad=True).cuda()

                loss_d = discriminator.train_batch(batch_real,batch_fake)
                assert np.all(np.isfinite(loss_d))
            z_vars = rng.normal(0,1,size=(n_batch,n_z)).astype(np.float32)
            z_vars = Variable(torch.from_numpy(z_vars),requires_grad=True).cuda()
コード例 #19
0
def compute_amplitude_prediction_correlations(
        pred_fn,
        examples,
        n_iterations,
        perturb_fn=gaussian_perturbation,
        batch_size=30,
        seed=((2017, 7, 10)),
        original_y=None,
):
    """
    Perturb input amplitudes and compute correlation between amplitude
    perturbations and prediction changes when pushing perturbed input through
    the prediction function.

    For more details, see [EEGDeepLearning]_.

    Parameters
    ----------
    pred_fn: function
        Function accepting an numpy input and returning prediction.
    examples: ndarray
        Numpy examples, first axis should be example axis.
    n_iterations: int
        Number of iterations to compute.
    perturb_fn: function, optional
        Function accepting amplitude array and random generator and returning
        perturbation. Default is Gaussian perturbation.
    batch_size: int, optional
        Batch size for computing predictions.
    seed: int, optional
        Random generator seed

    Returns
    -------
    amplitude_pred_corrs: ndarray
        Correlations between amplitude perturbations and prediction changes
        for all sensors and frequency bins.

    References
    ----------

    .. [EEGDeepLearning] Schirrmeister, R. T., Springenberg, J. T., Fiederer, L. D. J.,
       Glasstetter, M., Eggensperger, K., Tangermann, M., ... & Ball, T. (2017).
       Deep learning with convolutional neural networks for EEG decoding and
       visualization.
       arXiv preprint arXiv:1703.05051.
    """
    inds_per_batch = get_balanced_batches(n_trials=len(examples),
                                          rng=None,
                                          shuffle=False,
                                          batch_size=batch_size)
    log.info("Compute original predictions...")
    orig_preds = [
        pred_fn(examples[example_inds]) for example_inds in inds_per_batch
    ]
    orig_preds_arr = np.concatenate(orig_preds)
    if original_y is not None:
        orig_pred_labels = np.argmax(orig_preds_arr, axis=1)
        orig_accuracy = np.mean(orig_pred_labels == original_y)
        log.info("Original accuracy: {:.2f}...".format(orig_accuracy))
    rng = RandomState(seed)
    fft_input = np.fft.rfft(examples, axis=2).astype(np.complex64)
    amps = np.abs(fft_input).astype(np.float32)
    phases = np.angle(fft_input).astype(np.float32)
    del fft_input

    amp_pred_corrs = []
    new_accuracies = []
    for i_iteration in range(n_iterations):
        log.info("Iteration {:d}...".format(i_iteration))
        log.info("Sample perturbation...")
        perturbation = perturb_fn(amps, rng).astype(np.float32)
        log.info("Compute new amplitudes...")
        # do not allow perturbation to make amplitudes go below
        # zero
        perturbation = np.maximum(-amps, perturbation)
        new_amps = amps + perturbation
        new_amps = new_amps.astype(np.float32)
        log.info("Compute new  complex inputs...")
        new_complex = _amplitude_phase_to_complex(new_amps,
                                                  phases).astype(np.complex64)
        log.info("Compute new real inputs...")
        new_in = np.fft.irfft(new_complex, axis=2).astype(np.float32)
        del new_complex, new_amps
        log.info("Compute new predictions...")
        new_preds = [
            pred_fn(new_in[example_inds]) for example_inds in inds_per_batch
        ]

        new_preds_arr = np.concatenate(new_preds)
        if original_y is not None:
            new_pred_labels = np.argmax(new_preds_arr, axis=1)
            new_accuracy = np.mean(new_pred_labels == original_y)
            log.info("New accuracy: {:.2f}...".format(new_accuracy))
            new_accuracies.append(new_accuracy)
        diff_preds = new_preds_arr - orig_preds_arr

        log.info("Compute correlation...")
        amp_pred_corr = wrap_reshape_apply_fn(corr,
                                              perturbation[:, :, :, 0],
                                              diff_preds,
                                              axis_a=(0, ),
                                              axis_b=(0))
        print("max corr", np.max(amp_pred_corr))
        print("min corr", np.min(amp_pred_corr))
        amp_pred_corrs.append(amp_pred_corr)
    if original_y is not None:
        return amp_pred_corrs, orig_accuracy, new_accuracies
    else:
        return amp_pred_corrs
コード例 #20
0
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]

    # 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.events_from_annotations(raw)
    # 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)

    # 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:])

    # 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()

    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=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([
                                   0.91796708, 1.2714895, 0.4999536,
                                   0.94365239, 0.39268905, 0.89928466,
                                   0.37648854, 0.8940345, 0.35774994,
                                   0.86749417, 0.35080773, 0.80767328
                               ]),
                               rtol=1e-4,
                               atol=1e-5)

    np.testing.assert_allclose(np.array(accuracies),
                               np.array([
                                   55., 63.33333333, 71.66666667, 63.33333333,
                                   81.66666667, 60., 78.33333333, 63.33333333,
                                   83.33333333, 66.66666667, 80., 66.66666667
                               ]),
                               rtol=1e-4,
                               atol=1e-5)
コード例 #21
0
def run_exp(max_recording_mins, n_recordings, sec_to_cut,
            duration_recording_mins, max_abs_val, max_min_threshold,
            max_min_expected, shrink_val, max_min_remove, batch_set_zero_val,
            batch_set_zero_test, sampling_freq, low_cut_hz, high_cut_hz,
            exp_demean, exp_standardize, moving_demean, moving_standardize,
            channel_demean, channel_standardize, divisor, n_folds, i_test_fold,
            model_name, input_time_length, final_conv_length, batch_size,
            max_epochs, only_return_exp):
    cuda = 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))
    if max_min_threshold is not None:
        preproc_functions.append(lambda data, fs: (clean_jumps(
            data, 200, max_min_threshold, max_min_expected, cuda), fs))
    if max_min_remove is not None:
        window_len = 200
        preproc_functions.append(lambda data, fs: (set_jumps_to_zero(
            data,
            window_len=window_len,
            threshold=max_min_remove,
            cuda=cuda,
            clip_min_max_to_zero=True), fs))

    if shrink_val is not None:
        preproc_functions.append(lambda data, fs: (shrink_spikes(
            data,
            shrink_val,
            1,
            9,
        ), fs))

    preproc_functions.append(lambda data, fs: (resampy.resample(
        data, fs, sampling_freq, axis=1, filter='kaiser_fast'), sampling_freq))
    preproc_functions.append(lambda data, fs: (bandpass_cnt(
        data, low_cut_hz, high_cut_hz, fs, filt_order=4, axis=1), fs))

    if exp_demean:
        preproc_functions.append(lambda data, fs: (exponential_running_demean(
            data.T, factor_new=0.001, init_block_size=100).T, fs))
    if exp_standardize:
        preproc_functions.append(
            lambda data, fs: (exponential_running_standardize(
                data.T, factor_new=0.001, init_block_size=100).T, fs))
    if moving_demean:
        preproc_functions.append(lambda data, fs: (padded_moving_demean(
            data, axis=1, n_window=201), fs))
    if moving_standardize:
        preproc_functions.append(lambda data, fs: (padded_moving_standardize(
            data, axis=1, n_window=201), fs))
    if channel_demean:
        preproc_functions.append(lambda data, fs: (demean(data, axis=1), fs))
    if channel_standardize:
        preproc_functions.append(lambda data, fs:
                                 (standardize(data, axis=1), fs))
    if divisor is not None:
        preproc_functions.append(lambda data, fs: (data / divisor, fs))

    all_file_names, labels = get_all_sorted_file_names_and_labels()
    lengths = np.load(
        '/home/schirrmr/code/auto-diagnosis/sorted-recording-lengths.npy')
    mask = lengths < max_recording_mins * 60
    cleaned_file_names = np.array(all_file_names)[mask]
    cleaned_labels = labels[mask]

    diffs_per_rec = np.load(
        '/home/schirrmr/code/auto-diagnosis/diffs_per_recording.npy')

    def create_set(inds):
        X = []
        for i in inds:
            log.info("Load {:s}".format(cleaned_file_names[i]))
            x = load_data(cleaned_file_names[i], preproc_functions)
            X.append(x)
        y = cleaned_labels[inds].astype(np.int64)
        return SignalAndTarget(X, y)

    if not only_return_exp:
        folds = get_balanced_batches(n_recordings,
                                     None,
                                     False,
                                     n_batches=n_folds)
        test_inds = folds[i_test_fold]
        valid_inds = folds[i_test_fold - 1]
        all_inds = list(range(n_recordings))
        train_inds = np.setdiff1d(all_inds, np.union1d(test_inds, valid_inds))

        rec_nr_sorted_by_diff = np.argsort(diffs_per_rec)[::-1]
        train_inds = rec_nr_sorted_by_diff[train_inds]
        valid_inds = rec_nr_sorted_by_diff[valid_inds]
        test_inds = rec_nr_sorted_by_diff[test_inds]

        train_set = create_set(train_inds)
        valid_set = create_set(valid_inds)
        test_set = create_set(test_inds)
    else:
        train_set = None
        valid_set = None
        test_set = None

    set_random_seeds(seed=20170629, cuda=cuda)
    # This will determine how many crops are processed in parallel
    n_classes = 2
    in_chans = 21
    if model_name == 'shallow':
        model = ShallowFBCSPNet(
            in_chans=in_chans,
            n_classes=n_classes,
            input_time_length=input_time_length,
            final_conv_length=final_conv_length).create_network()
    elif model_name == 'deep':
        model = Deep4Net(in_chans,
                         n_classes,
                         input_time_length=input_time_length,
                         final_conv_length=final_conv_length).create_network()

    optimizer = optim.Adam(model.parameters())
    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, 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]
    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)
    loss_function = lambda preds, targets: F.nll_loss(
        th.mean(preds, dim=2)[:, :, 0], targets)
    model_constraint = None
    monitors = [
        LossMonitor(),
        MisclassMonitor(col_suffix='sample_misclass'),
        CroppedTrialMisclassMonitor(input_time_length),
        RuntimeMonitor(),
    ]
    stop_criterion = MaxEpochs(max_epochs)
    batch_modifier = None
    if batch_set_zero_val is not None:
        batch_modifier = RemoveMinMaxDiff(batch_set_zero_val,
                                          clip_max_abs=True,
                                          set_zero=True)
    if (batch_set_zero_val is not None) and (batch_set_zero_test == True):
        iterator = ModifiedIterator(
            iterator,
            batch_modifier,
        )
        batch_modifier = None
    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=True,
                     batch_modifier=batch_modifier,
                     cuda=cuda)
    if not only_return_exp:
        exp.run()
    else:
        exp.dataset = None
        exp.splitter = None

    return exp
コード例 #22
0
ファイル: pair_data.py プロジェクト: poplar17/eeg_thesis
def split_paired_into_train_test(paired_dataset,
                                 n_folds,
                                 i_test_fold,
                                 n_classes,
                                 rng=None):
    # Indexing with lists faster than ndarrays:
    assert type(paired_dataset.X['source']) == list and \
           type(paired_dataset.X['source']) == list, \
           "Expected paired dataset X to be list containing ndarrays."

    n_trials = len(paired_dataset.X['source'])
    if n_trials < n_folds:
        raise ValueError("Less Trials: {:d} than folds: {:d}".format(
            n_trials, n_folds))

    train_indices = []
    test_indices = []

    source_y = paired_dataset.y['source']
    target_y = paired_dataset.y['target']

    n_possible_label_pairs = n_classes**2

    lists_of_indices_per_pair = [[] for _ in range(n_possible_label_pairs)]
    possible_label_pairs = []

    for i in range(n_classes):
        for j in range(n_classes):
            possible_label_pairs.append((i, j))

    # for i in range(source_y.shape[0]):
    for i in range(len(source_y)):
        src_label = source_y[i]
        tgt_label = target_y[i]
        idx = possible_label_pairs.index((src_label, tgt_label))
        lists_of_indices_per_pair[idx].append(i)

    for pair_list in lists_of_indices_per_pair:
        # pair_list = np.array(pair_list)
        n_list_trials = len(pair_list)
        shuffle = rng is not None
        folds = get_balanced_batches(n_list_trials,
                                     rng,
                                     shuffle,
                                     n_batches=n_folds)
        list_test_inds = folds[i_test_fold]
        list_all_inds = list(range(n_list_trials))
        list_train_inds = np.setdiff1d(list_all_inds, list_test_inds)
        assert np.intersect1d(list_train_inds, list_test_inds).size == 0
        assert np.array_equal(
            np.sort(np.union1d(list_train_inds, list_test_inds)),
            list_all_inds)
        # train_indices += pair_list[list_train_inds]
        # test_indices += pair_list[list_test_inds]
        train_indices += [pair_list[i] for i in list_train_inds]
        test_indices += [pair_list[i] for i in list_test_inds]

    # Because indices now sorted by label pairing, shuffle them:
    # np.random.shuffle(train_indices)
    # np.random.shuffle(test_indices)
    random.shuffle(train_indices)
    random.shuffle(test_indices)

    train_set = select_pairs_from_paired_dataset(paired_dataset, train_indices)
    test_set = select_pairs_from_paired_dataset(paired_dataset, test_indices)
    return train_set, test_set
コード例 #23
0
def spectral_perturbation_correlation(pert_fn,
                                      diff_fn,
                                      pred_fn,
                                      n_layers,
                                      inputs,
                                      n_iterations,
                                      batch_size=30,
                                      seed=((2017, 7, 10))):
    """Calculates perturbation correlations for layers in network by perturbing either amplitudes or phases

    Parameters
    ----------
    pert_fn : function
        Function that perturbs spectral phase and amplitudes of inputs
    diff_fn : function
        Function that calculates difference between original and perturbed activations
    pred_fn : function
        Function that returns a list of activations.
        Each entry in the list corresponds to the output of 1 layer in a network
    n_layers : int
        Number of layers pred_fn returns activations for.
    inputs : numpy array
        Original inputs that are used for perturbation [B,X,T,1]
        Phase perturbations are sampled for each input individually, but applied to all X of that input
    n_iterations : int
        Number of iterations of correlation computation. The higher the better
    batch_size : int
        Number of inputs that are used for one forward pass. (Concatenated for all inputs)

    Returns
    -------
    pert_corrs : numpy array
        List of length n_layers containing average perturbation correlations over iterations
        L  x  CxFrxFi (Channels,Frequencies,Filters)
    """
    rng = np.random.RandomState(seed)

    # Get batch indeces
    batch_inds = get_balanced_batches(n_trials=len(inputs),
                                      rng=rng,
                                      shuffle=False,
                                      batch_size=batch_size)
    # Calculate layer activations and reshape
    log.info("Compute original predictions...")
    orig_preds = [pred_fn(inputs[inds]) for inds in batch_inds]
    use_shape = []
    for l in range(n_layers):
        tmp = list(orig_preds[0][l].shape)
        tmp.extend([1] * (4 - len(tmp)))
        tmp[0] = len(inputs)
        use_shape.append(tmp)
    orig_preds_layers = [
        np.concatenate([orig_preds[o][l]
                        for o in range(len(orig_preds))]).reshape(use_shape[l])
        for l in range(n_layers)
    ]

    # Compute FFT of inputs
    fft_input = np.fft.rfft(inputs, n=inputs.shape[2], axis=2)
    amps = np.abs(fft_input)
    phases = np.angle(fft_input)

    pert_corrs = [0] * n_layers
    for i in range(n_iterations):
        log.info("Iteration {:d}...".format(i))
        log.info("Sample perturbation...")
        amps_pert, phases_pert, pert_vals = pert_fn(amps, phases, rng=rng)

        # Compute perturbed inputs
        log.info("Compute perturbed complex inputs...")
        fft_pert = amps_pert * np.exp(1j * phases_pert)
        log.info("Compute perturbed real inputs...")
        inputs_pert = np.fft.irfft(fft_pert, n=inputs.shape[2],
                                   axis=2).astype(np.float32)

        # Calculate layer activations for perturbed inputs
        log.info("Compute new predictions...")
        new_preds = [pred_fn(inputs_pert[inds]) for inds in batch_inds]
        new_preds_layers = [
            np.concatenate([new_preds[o][l] for o in range(len(new_preds))
                            ]).reshape(use_shape[l]) for l in range(n_layers)
        ]

        for l in range(n_layers):
            log.info("Layer {:d}...".format(l))
            # Calculate difference of original and perturbed feature map activations
            log.info("Compute activation difference...")
            preds_diff = diff_fn(new_preds_layers[l][:, :, :, 0],
                                 orig_preds_layers[l][:, :, :, 0])

            # Calculate feature map differences with perturbations
            log.info("Compute correlation...")
            pert_corrs_tmp = wrap_reshape_apply_fn(corr,
                                                   pert_vals[:, :, :, 0],
                                                   preds_diff,
                                                   axis_a=(0, ),
                                                   axis_b=(0))
            pert_corrs[l] += pert_corrs_tmp

    pert_corrs = [pert_corrs[l] / n_iterations
                  for l in range(n_layers)]  #mean over iterations
    return pert_corrs
コード例 #24
0
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)
コード例 #25
0
def load_train_valid_test(train_filename,
                          test_filename,
                          n_folds,
                          i_test_fold,
                          valid_set_fraction,
                          use_validation_set,
                          low_cut_hz,
                          debug=False):
    # we loaded all sensors to always get same cleaning results independent of sensor selection
    # There is an inbuilt heuristic that tries to use only EEG channels and that definitely
    # works for datasets in our paper
    if test_filename is None:
        assert n_folds is not None
        assert i_test_fold is not None
        assert valid_set_fraction is None
    else:
        assert n_folds is None
        assert i_test_fold is None
        assert use_validation_set == (valid_set_fraction is not None)

    train_folder = '/home/schirrmr/data/BBCI-without-last-runs/'
    log.info("Loading train...")
    full_train_set = load_bbci_data(os.path.join(train_folder, train_filename),
                                    low_cut_hz=low_cut_hz,
                                    debug=debug)

    if test_filename is not None:
        test_folder = '/home/schirrmr/data/BBCI-only-last-runs/'
        log.info("Loading test...")
        test_set = load_bbci_data(os.path.join(test_folder, test_filename),
                                  low_cut_hz=low_cut_hz,
                                  debug=debug)
        if use_validation_set:
            assert valid_set_fraction is not None
            train_set, valid_set = split_into_two_sets(full_train_set,
                                                       valid_set_fraction)
        else:
            train_set = full_train_set
            valid_set = None

    # Split data
    if n_folds is not None:
        fold_inds = get_balanced_batches(len(full_train_set.X),
                                         None,
                                         shuffle=False,
                                         n_batches=n_folds)

        fold_sets = [
            select_examples(full_train_set, inds) for inds in fold_inds
        ]

        test_set = fold_sets[i_test_fold]
        train_folds = np.arange(n_folds)
        train_folds = np.setdiff1d(train_folds, [i_test_fold])
        if use_validation_set:
            i_valid_fold = (i_test_fold - 1) % n_folds
            train_folds = np.setdiff1d(train_folds, [i_valid_fold])
            valid_set = fold_sets[i_valid_fold]
            assert i_valid_fold not in train_folds
            assert i_test_fold != i_valid_fold
        else:
            valid_set = None

        assert i_test_fold not in train_folds

        train_fold_sets = [fold_sets[i] for i in train_folds]
        train_set = concatenate_sets(train_fold_sets)
        # Some checks
        if valid_set is None:
            assert len(train_set.X) + len(test_set.X) == len(full_train_set.X)
        else:
            assert len(train_set.X) + len(valid_set.X) + len(
                test_set.X) == len(full_train_set.X)

    log.info("Train set with {:4d} trials".format(len(train_set.X)))
    if valid_set is not None:
        log.info("Valid set with {:4d} trials".format(len(valid_set.X)))
    log.info("Test set with  {:4d} trials".format(len(test_set.X)))

    return train_set, valid_set, test_set
コード例 #26
0
    model.cuda()

from torch import optim

optimizer = optim.Adam(model.parameters())

# Training loop

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))
for i_epoch in range(30):
    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()