def test_model_from_keras(
        subject,
        batch_size=32,
        folder='/scratch/sem19h24/EEGNet_reformat/EEGnet/initialModels/'):
    """
    Import the keras model and test it

    Parameters:
        subject:    Number between 1 and 9
        batch_size: Batch Size to test the model
        folder:     Folder where the model files are found.

    returns: loss, accuracy
    """

    # Just use the default values and hope all dimensions are fine...
    model = EEGNet(activation='elu', constrain_w=False, permuted_flatten=True)
    model.load_model_params_from_keras(f"{folder}model{subject-1}_torch.npz")
    if t.cuda.is_available():
        model = model.cuda()

    print_summary(model, None, None, None)

    # get dataloader
    test_samples, test_labels = get_data(subject, training=False)
    test_loader = as_data_loader(test_samples,
                                 test_labels,
                                 batch_size=batch_size)

    # prepare loss function, no optimizer necessary
    loss_function = t.nn.CrossEntropyLoss()
    return _test_net(model, test_loader, loss_function, train=False)
示例#2
0
 def __init__(self):
     self.net = EEGNet().cuda()
     self.criterion = nn.BCELoss()
     self.optimizer = optim.Adam(self.net.parameters(), lr=0.001)
     self.scheduler = optim.lr_scheduler.StepLR(self.optimizer,
                                                step_size=20,
                                                gamma=0.5)
示例#3
0
class EEGNet_classifier():
    def __init__(self):
        self.net = EEGNet().cuda()
        self.criterion = nn.BCELoss()
        self.optimizer = optim.Adam(self.net.parameters(), lr=0.001)
        self.scheduler = optim.lr_scheduler.StepLR(self.optimizer,
                                                   step_size=20,
                                                   gamma=0.8)

    def fit(self, X, y, quiet=True):
        for epoch in range(200):
            running_loss = 0
            _skf = StratifiedKFold(n_splits=10, shuffle=True)
            for more, less in _skf.split(X, y):
                # Get data and labels
                inputs = torch.from_numpy(X[more])
                labels = torch.FloatTensor(np.array([y[more]]).T * 1.0)

                # Make sure positive and negative samples have the same number
                inputs = inputs[:torch.sum(labels).type(torch.int16) * 2]
                labels = labels[:torch.sum(labels).type(torch.int16) * 2]

                # wrap them in Variable
                inputs = Variable(inputs.cuda())
                labels = Variable(labels.cuda())

                # zero the parameter gradients
                self.optimizer.zero_grad()

                # forward + backward + optimize
                outputs = self.net(inputs)
                loss = self.criterion(outputs, labels)
                loss.backward()

                self.optimizer.step()

                running_loss += loss.data

            self.scheduler.step()

            if not quiet:
                # print(f'Epoch {epoch}: {running_loss}')
                if epoch % 10 == 0:
                    print(f'Epoch {epoch}: {running_loss}')

        print(f'Epoch {epoch}: {running_loss}')

    def predict(self, X):
        inputs = torch.from_numpy(X)
        inputs = Variable(inputs.cuda())
        return self.net(inputs)
def train_subject_specific_cv(subject,
                              n_splits=4,
                              epochs=500,
                              batch_size=32,
                              lr=0.001,
                              early_stopping=True,
                              silent=False,
                              plot=True,
                              **kwargs):
    """
    Trains a subject specific model for the given subject, using K-Fold Cross Validation

    Parameters:
     - subject:        Integer in the Range 1 <= subject <= 9
     - n_splits:       Number of splits for K-Fold CV
     - epochs:         Number of epochs to train
     - batch_size:     Batch Size
     - lr:             Learning Rate
     - early_stopping: bool, approximate the number of epochs to train the network for the subject.
     - silent:         bool, if True, generate no output, including progress bar
     - plot:           bool, if True, generates plots
     - kwargs:         remaining parameters are passed to the EEGnet model

    Returns: (models, metrics, epoch)
     - models:  List of t.nn.Module, size = [n_splits]
     - metrics: t.tensor, size=[1, 4], accuracy, precision, recall, f1, averaged over all splits
     - epoch:   integer, number of epochs determined by early_stopping. If early_stopping is not
                used, then this value will always be equal to the parameter epochs

    Notes:
     - Early Stopping: Uses early stopping to determine the best epoch to stop training for the
       given subject by averaging over the stopping epoch of all splits.
    """

    # load the raw data
    samples, labels = get_data(subject, training=True)
    samples, labels = as_tensor(samples, labels)

    # prepare the models
    models = [EEGNet(T=samples.shape[2], **kwargs) for _ in range(n_splits)]
    metrics = t.zeros((n_splits, 4))
    best_epoch = np.zeros(n_splits)

    # prepare KFold
    kfcv = KFoldCV(n_splits)
    split = 0

    # open the progress bar
    with tqdm(desc=f"Subject {subject} CV, split 1",
              total=n_splits * epochs,
              leave=False,
              unit='epoch',
              ascii=True,
              disable=silent) as pbar:
        # loop over all splits
        for split, indices in enumerate(kfcv.split(samples, labels)):
            # set the progress bar title
            pbar.set_description(f"Subject {subject} CV, split {split + 1}")

            # generate dataset
            train_idx, val_idx = indices
            train_ds = t.utils.data.TensorDataset(samples[train_idx],
                                                  labels[train_idx])
            val_ds = t.utils.data.TensorDataset(samples[val_idx],
                                                labels[val_idx])
            train_loader = t.utils.data.DataLoader(train_ds,
                                                   batch_size=batch_size,
                                                   shuffle=True)
            val_loader = t.utils.data.DataLoader(val_ds,
                                                 batch_size=batch_size,
                                                 shuffle=True)

            # prepare the model
            model = models[split]
            model.initialize_params()
            if t.cuda.is_available():
                model = model.cuda()

            # prepare loss function and optimizer
            loss_function = t.nn.CrossEntropyLoss()
            optimizer = t.optim.Adam(model.parameters(), lr=lr)

            model, split_metrics, split_epoch, _ = _train_net(
                subject,
                model,
                train_loader,
                val_loader,
                loss_function,
                optimizer,
                epochs=epochs,
                early_stopping=early_stopping,
                plot=plot,
                pbar=pbar)

            metrics[split, :] = split_metrics[0, :]
            best_epoch[split] = split_epoch

    # average all metrics
    metrics = metrics.mean(axis=0).reshape(1, 4)

    # print the result
    if not silent:
        print(
            f"Subje`ct {subject} CV: accuracy = {metrics[0, 0]}, at epoch {best_epoch.mean()} "
            + f"+- {best_epoch.std()}")
    return models, metrics, int(best_epoch.mean().round())
def train_subject_specific(subject,
                           epochs=500,
                           batch_size=32,
                           lr=0.001,
                           silent=False,
                           plot=True,
                           **kwargs):
    """
    Trains a subject specific model for the given subject

    Parameters:
     - subject:    Integer in the Range 1 <= subject <= 9
     - epochs:     Number of epochs to train
     - batch_size: Batch Size
     - lr:         Learning Rate
     - silent:     bool, if True, hide all output including the progress bar
     - plot:       bool, if True, generate plots
     - kwargs:     Remaining arguments passed to the EEGnet model

    Returns: (model, metrics)
     - model:   t.nn.Module, trained model
     - metrics: t.tensor, size=[1, 4], accuracy, precision, recall, f1
    """
    # load the data
    train_samples, train_labels = get_data(subject, training=True)
    test_samples, test_labels = get_data(subject, training=False)
    train_loader = as_data_loader(train_samples,
                                  train_labels,
                                  batch_size=batch_size)
    # test_loader = as_data_loader(test_samples, test_labels, batch_size=test_labels.shape[0])
    test_loader = as_data_loader(test_samples,
                                 test_labels,
                                 batch_size=batch_size)

    # prepare the model
    model = EEGNet(T=train_samples.shape[2], **kwargs)
    model.initialize_params()
    if t.cuda.is_available():
        model = model.cuda()

    # prepare loss function and optimizer
    loss_function = t.nn.CrossEntropyLoss()
    optimizer = t.optim.Adam(model.parameters(), lr=lr, eps=1e-7)
    scheduler = None

    # print the training setup
    print_summary(model, optimizer, loss_function, scheduler)

    # prepare progress bar
    with tqdm(desc=f"Subject {subject}",
              total=epochs,
              leave=False,
              disable=silent,
              unit='epoch',
              ascii=True) as pbar:

        # Early stopping is not allowed in this mode, because the testing data cannot be used for
        # training!
        model, metrics, _, history = _train_net(subject,
                                                model,
                                                train_loader,
                                                test_loader,
                                                loss_function,
                                                optimizer,
                                                scheduler=scheduler,
                                                epochs=epochs,
                                                early_stopping=False,
                                                plot=plot,
                                                pbar=pbar)

    if not silent:
        print(f"Subject {subject}: accuracy = {metrics[0, 0]}")
    return model, metrics, history
示例#6
0
import os
import sys
import pickle

# Computing -------------------------------------
import numpy as np
from sklearn.model_selection import StratifiedKFold

# Local tools -----------------------------------
sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'tools'))  # noqa
from MEG_worker import MEG_Worker

# EEG net ---------------------------------------
import torchsummary
from eegnet import torch, nn, EEGNet, optim, Variable, evaluate
net = EEGNet().cuda()
print(net.forward(Variable(torch.Tensor(np.random.rand(1, 1, 61,
                                                       272)).cuda())))
torchsummary.summary(net, input_size=(1, 61, 272))

# Init parameters -------------------------------
# Init results_folder
RESULTS_FOLDER = os.path.join('.', 'results_eegnet')

# Make sure RESULTS_FOLDER is not a file
assert (not os.path.isfile(RESULTS_FOLDER))

# Mkdir if RESULTS_FOLDER does not exist
if not os.path.exists(RESULTS_FOLDER):
    os.mkdir(RESULTS_FOLDER)