Exemple #1
0
def process_state(state):
    if type(state) is tuple or type(state) is list:

        if use_gpu():
            return tuple(s.cuda() for s in state)
        else:
            return tuple(s for s in state)
    else:
        return (state.cuda(),) if use_gpu() else (state,)
Exemple #2
0
def fit(model,
        train,
        test,
        num_boost_round=360,
        verbose_eval=1,
        export=False,
        training_params=None,
        export_params=None,
        **kwargs):
    if not use_gpu():
        print_errors('XGBoost can only be executed on a GPU for the moment',
                     do_exit=True)

    training_params = {} if training_params is None else training_params
    export_params = {} if export_params is None else export_params

    d_test = xgb.DMatrix(np.asarray(test.get_vectors()),
                         label=np.asarray(test.labels))

    if not validation_only:
        print_h1('Training: ' + special_parameters.setup_name)
        print_info("get vectors...")

        X = np.asarray(train.get_vectors())
        y = np.asarray(train.labels)

        d_train = xgb.DMatrix(X, label=y)

        gpu_id = first_device().index

        kwargs['verbosity'] = verbose_level()
        kwargs['gpu_id'] = gpu_id

        eval_list = [(d_test, 'eval'), (d_train, 'train')]

        print_info("fit model...")

        bst = xgb.train(kwargs,
                        d_train,
                        num_boost_round=num_boost_round,
                        verbose_eval=verbose_eval,
                        evals=eval_list,
                        xgb_model=model)

        print_info("Save model...")
        save_model(bst)

    else:
        bst = load_model()

    print_h1('Validation/Export: ' + special_parameters.setup_name)
    predictions = bst.predict(d_test, ntree_limit=bst.best_ntree_limit)
    res = validate(predictions,
                   np.array(test.labels),
                   training_params['metrics']
                   if 'metrics' in training_params else tuple(),
                   final=True)
    print_notification(res, end='')
    if export:
        export_results(test, predictions, **export_params)
def create_model(model_class, model_params=None, model_name='model'):
    """
    create and eventually load model
    :param model_name:
    :param model_class:
    :param model_params:
    :param model_name:
    :return:
    """

    model_params = {} if model_params is None else model_params

    model = model_class(**model_params)

    if special_parameters.load_model:  # recover from checkpoint
        _load_model(model, model_name)

    # configure usage on GPU
    if use_gpu():
        model.to(first_device())
        model = torch.nn.DataParallel(model, device_ids=all_devices())

    # print info about devices
    print_info('Device(s)): ' + str(device_description()))

    return model
    def __init__(self, prior, *args, **kwargs):
        super().__init__()
        # Variable(torch.from_numpy(np.log(self.prior)).float())

        # eventually set the prior on the GPU
        if use_gpu():
            self.prior = torch.from_numpy(np.log(prior)).float().cuda()
        else:
            self.prior = torch.from_numpy(np.log(prior)).float()

        self.criterion = nn.CrossEntropyLoss(*args, **kwargs)
    def loss(self, output, label):
        # constructing a one hot encoding structure
        one_hot = torch.zeros(size=output.size())

        # eventually put it on the GPU
        if use_gpu():
            one_hot = one_hot.cuda()

        # set the same number of dimension to label
        label = label.long().unsqueeze(1)

        # fill one_hot based on the label
        one_hot = one_hot.scatter_(1, label, 1.)
        return self.criterion(output.view(-1), one_hot.view(-1))
Exemple #6
0
def construct_action(epsilon, model_z, state, output_size):
    random_action = random.random() <= epsilon
    action_index = [
        torch.randint(output_size, torch.Size([]), dtype=torch.int)
        if random_action else torch.argmax(model_z(*state)[0])
    ][0]

    action = torch.zeros([output_size], dtype=torch.float32)

    if use_gpu():
        action = action.cuda()

    action[action_index] = 1

    return action
Exemple #7
0
def _optimization(model_z, batch, gamma, optimizer_, loss):
    """
    Optimizing the model for a random batch
    :param batch: the current batch that will be used to optimize the model
    :param model_z: the model to train
    :param gamma: the gamma value for the Q function
    :param optimizer_: the optimizer
    :param loss: the loss criterion
    :return: the loss value
    """
    model_z.train()

    # processing mini batches
    state_batch, action_batch, state_1_batch, reward_batch, finished_batch = batch

    state_batch = process_state(state_batch)

    state_1_batch = process_state(state_1_batch)

    # eventually combine state and reward so that the model can train on both

    if use_gpu():  # put on GPU if the user asked it
        action_batch = action_batch.cuda()
        reward_batch = reward_batch.cuda()
        finished_batch = finished_batch.cuda()
    output_1_batch = model_z(*state_1_batch)

    finished = finished_batch.unsqueeze(1).float()
    reward_batch = reward_batch.unsqueeze(1).float()

    # Bellman equation
    y_batch = reward_batch + gamma * torch.max(torch.mul(output_1_batch, 1 - finished), dim=1)[0].unsqueeze(1)
    y_batch = y_batch.detach()  # y_batch is not trainable as it is the target

    output = model_z(*state_batch)

    # if state and reward are combined to have more complex training procedures,
    # this line should be replaced with a loss function
    q_value = torch.sum(output * action_batch.float(), dim=1).unsqueeze(1)

    optimizer_.zero_grad()
    loss_value = loss(q_value, y_batch)

    loss_value.backward()
    optimizer_.step()

    return loss_value.item()
Exemple #8
0
def fit(model_z,
        train,
        test,
        val=None,
        training_params=None,
        predict_params=None,
        validation_params=None,
        export_params=None,
        optim_params=None,
        model_selection_params=None):
    """
    This function is the core of an experiment. It performs the ml procedure as well as the call to validation.
    :param training_params: parameters for the training procedure
    :param val: validation set
    :param test: the test set
    :param train: The training set
    :param optim_params:
    :param export_params:
    :param validation_params:
    :param predict_params:
    :param model_z: the model that should be trained
    :param model_selection_params:
    """
    # configuration

    training_params, predict_params, validation_params, export_params, optim_params, \
        cv_params = merge_dict_set(
            training_params, TRAINING_PARAMS,
            predict_params, PREDICT_PARAMS,
            validation_params, VALIDATION_PARAMS,
            export_params, EXPORT_PARAMS,
            optim_params, OPTIM_PARAMS,
            model_selection_params, MODEL_SELECTION_PARAMS
        )

    train_loader, test_loader, val_loader = _dataset_setup(
        train, test, val, **training_params)

    statistics_path = output_path('metric_statistics.dump')

    metrics_stats = Statistics(
        model_z, statistics_path, **
        cv_params) if cv_params.pop('cross_validation') else None

    validation_path = output_path('validation.txt')

    # training parameters
    optim = optim_params.pop('optimizer')
    iterations = training_params.pop('iterations')
    gamma = training_params.pop('gamma')
    loss = training_params.pop('loss')
    log_modulo = training_params.pop('log_modulo')
    val_modulo = training_params.pop('val_modulo')
    first_epoch = training_params.pop('first_epoch')

    # callbacks for ml tests
    vcallback = validation_params.pop(
        'vcallback') if 'vcallback' in validation_params else None

    if iterations is None:
        print_errors(
            'Iterations must be set',
            exception=TrainingConfigurationException('Iterations is None'))

    # before ml callback
    if vcallback is not None and special_parameters.train and first_epoch < max(
            iterations):
        init_callbacks(vcallback, val_modulo,
                       max(iterations) // val_modulo, train_loader.dataset,
                       model_z)

    max_iterations = max(iterations)

    if special_parameters.train and first_epoch < max(iterations):
        print_h1('Training: ' + special_parameters.setup_name)

        loss_logs = [] if first_epoch < 1 else load_loss('loss_train')

        loss_val_logs = [] if first_epoch < 1 else load_loss('loss_validation')

        opt = create_optimizer(model_z.parameters(), optim, optim_params)

        scheduler = MultiStepLR(opt, milestones=list(iterations), gamma=gamma)

        # number of batches in the ml
        epoch_size = len(train_loader)

        # one log per epoch if value is -1
        log_modulo = epoch_size if log_modulo == -1 else log_modulo

        epoch = 0
        for epoch in range(max_iterations):

            if epoch < first_epoch:
                # opt.step()
                _skip_step(scheduler, epoch)
                continue
            # saving epoch to enable restart
            export_epoch(epoch)
            model_z.train()

            # printing new epoch
            print_h2('-' * 5 + ' Epoch ' + str(epoch + 1) + '/' +
                     str(max_iterations) + ' (lr: ' + str(scheduler.get_lr()) +
                     ') ' + '-' * 5)

            running_loss = 0.0

            for idx, data in enumerate(train_loader):

                # get the inputs
                inputs, labels = data

                # wrap labels in Variable as input is managed through a decorator
                # labels = model_z.p_label(labels)
                if use_gpu():
                    labels = labels.cuda()

                # zero the parameter gradients
                opt.zero_grad()
                outputs = model_z(inputs)
                loss_value = loss(outputs, labels)
                loss_value.backward()

                opt.step()

                # print math
                running_loss += loss_value.item()
                if idx % log_modulo == log_modulo - 1:  # print every log_modulo mini-batches
                    print('[%d, %5d] loss: %.5f' %
                          (epoch + 1, idx + 1, running_loss / log_modulo))

                    # tensorboard support
                    add_scalar('Loss/train', running_loss / log_modulo)
                    loss_logs.append(running_loss / log_modulo)
                    running_loss = 0.0

            # end of epoch update of learning rate scheduler
            scheduler.step(epoch + 1)

            # saving the model and the current loss after each epoch
            save_checkpoint(model_z, optimizer=opt)

            # validation of the model
            if epoch % val_modulo == val_modulo - 1:
                validation_id = str(int((epoch + 1) / val_modulo))

                # validation call
                predictions, labels, loss_val = predict(
                    model_z, val_loader, loss, **predict_params)
                loss_val_logs.append(loss_val)

                res = '\n[validation_id:' + validation_id + ']\n' + validate(
                    predictions,
                    labels,
                    validation_id=validation_id,
                    statistics=metrics_stats,
                    **validation_params)

                # save statistics for robust cross validation
                if metrics_stats:
                    metrics_stats.save()

                print_notification(res)

                if special_parameters.mail == 2:
                    send_email(
                        'Results for XP ' + special_parameters.setup_name +
                        ' (epoch: ' + str(epoch + 1) + ')', res)
                if special_parameters.file:
                    save_file(
                        validation_path,
                        'Results for XP ' + special_parameters.setup_name +
                        ' (epoch: ' + str(epoch + 1) + ')', res)

                # checkpoint
                save_checkpoint(model_z,
                                optimizer=opt,
                                validation_id=validation_id)

                # callback
                if vcallback is not None:
                    run_callbacks(vcallback, (epoch + 1) // val_modulo)

            # save loss
            save_loss(
                {  # // log_modulo * log_modulo in case log_modulo does not divide epoch_size
                    'train': (loss_logs, log_modulo),
                    'validation':
                    (loss_val_logs,
                     epoch_size // log_modulo * log_modulo * val_modulo)
                },
                ylabel=str(loss))

        # saving last epoch
        export_epoch(epoch +
                     1)  # if --restart is set, the train will not be executed

        # callback
        if vcallback is not None:
            finish_callbacks(vcallback)

    # final validation
    if special_parameters.evaluate or special_parameters.export:
        print_h1('Validation/Export: ' + special_parameters.setup_name)
        if metrics_stats is not None:
            # change the parameter states of the model to best model
            metrics_stats.switch_to_best_model()

        predictions, labels, val_loss = predict(model_z,
                                                test_loader,
                                                loss,
                                                validation_size=-1,
                                                **predict_params)

        if special_parameters.evaluate:

            res = validate(predictions,
                           labels,
                           statistics=metrics_stats,
                           **validation_params,
                           final=True)

            print_notification(res, end='')

            if special_parameters.mail >= 1:
                send_email(
                    'Final results for XP ' + special_parameters.setup_name,
                    res)
            if special_parameters.file:
                save_file(
                    validation_path,
                    'Final results for XP ' + special_parameters.setup_name,
                    res)

        if special_parameters.export:
            export_results(test_loader.dataset, predictions, **export_params)

    return metrics_stats
def predict(model,
            loader,
            loss,
            export=False,
            filters=tuple(),
            validation_size=10000,
            compute_loss=False):
    """
        Give the prediction of the model on a test set
        :param compute_loss:
        :param filters: set some output to 0
        :param validation_size:
        :param model: the model
        :param loader: the test set loader
        :param loss: the loss function
        :param export: if False the predictions are not saved, otherwise the results are exported on file.
                       if export is true the loader must not be shuffled...
        :return: the arrays of predictions and corresponding labels
        """

    if len(loader) > _memory_overflow_size and (
            validation_size == -1 or validation_size > _memory_overflow_size):
        print_warning(
            '[predict] The dataset size is {}. Large datasets can cause memory '
            'overflow during standard prediction...'.format(len(loader)))

    with torch.no_grad():
        total = 0
        model.eval()

        y_preds = []
        y_labels = []
        running_loss = 0.0
        idx = 0
        if hasattr(model, 'last_sigmoid') and compute_loss:
            model.last_sigmoid = False
        elif hasattr(model, 'last_sigmoid'):
            model.last_sigmoid = True

        for idx, data in enumerate(loader):

            inputs, labels = data
            if use_gpu():
                labels = labels.cuda()
            # wrap them in Variable
            labels_variable = loss.output(labels)
            outputs = model(inputs)

            # if not test set
            if compute_loss and labels[0] != -1:
                loss_value = loss(outputs, labels)
                running_loss += loss_value.item()
            outputs = loss.output(outputs)

            total += labels_variable.size(0)

            y_preds.extend(outputs.data.tolist())
            y_labels.extend(labels_variable.data.tolist())

            if total >= validation_size != -1 and not export:
                break
        running_loss /= (idx + 1)  # normalizing the loss
        if compute_loss:
            print_info('Validation loss: ' + str(running_loss))
            add_scalar('Loss/Validation', running_loss)
        predictions, labels = np.asarray(y_preds), np.asarray(y_labels)

        # filtering some predicted labels
        for f in filters:
            f(predictions)

        # TODO filtering official labels

    return predictions, labels, running_loss