Esempio n. 1
0
def test_bloom_lstm(compression_ratio, expected_mrr):

    random_state = np.random.RandomState(RANDOM_SEED)
    train, test = _get_synthetic_data(randomness=1e-03,
                                      num_interactions=20000,
                                      random_state=random_state)

    embedding = BloomEmbedding(train.num_items,
                               32,
                               compression_ratio=compression_ratio,
                               num_hash_functions=4)

    representation = LSTMNet(train.num_items,
                             embedding_dim=EMBEDDING_DIM,
                             item_embedding_layer=embedding)

    model = ImplicitSequenceModel(loss=LOSS,
                                  representation=representation,
                                  batch_size=BATCH_SIZE,
                                  learning_rate=1e-2,
                                  l2=1e-7,
                                  n_iter=NUM_EPOCHS * 5,
                                  random_state=random_state,
                                  use_cuda=CUDA)

    model.fit(train, verbose=VERBOSE)

    mrr = _evaluate(model, test)

    assert mrr.mean() > expected_mrr
Esempio n. 2
0
def build_sequence_model(hyperparameters, train, random_state):

    h = hyperparameters

    set_seed(42, CUDA)

    if h['compression_ratio'] < 1.0:
        item_embeddings = BloomEmbedding(
            train.num_items,
            h['embedding_dim'],
            compression_ratio=h['compression_ratio'],
            num_hash_functions=4,
            padding_idx=0)
    else:
        item_embeddings = ScaledEmbedding(train.num_items,
                                          h['embedding_dim'],
                                          padding_idx=0)

    network = LSTMNet(train.num_items,
                      h['embedding_dim'],
                      item_embedding_layer=item_embeddings)

    model = ImplicitSequenceModel(loss=h['loss'],
                                  n_iter=h['n_iter'],
                                  batch_size=h['batch_size'],
                                  learning_rate=h['learning_rate'],
                                  embedding_dim=h['embedding_dim'],
                                  l2=h['l2'],
                                  representation=network,
                                  use_cuda=CUDA,
                                  random_state=np.random.RandomState(42))

    return model
Esempio n. 3
0
    def _initialize(self, interactions):

        self._num_items = interactions.num_items

        if self._representation == 'pooling':
            self._net = PoolNet(self._num_items, self._embedding_dim, sparse=self._sparse)
        elif self._representation == 'cnn':
            self._net = CNNNet(self._num_items, self._embedding_dim, sparse=self._sparse)
        elif self._representation == 'lstm':
            self._net = LSTMNet(self._num_items, self._embedding_dim, sparse=self._sparse)
        elif self._representation == 'mixture':
            self._net = MixtureLSTMNet(self._num_items, self._embedding_dim, sparse=self._sparse)
        else:
            self._net = self._representation

        self._net = gpu(self._net, self._use_cuda)

        if self._optimizer_func is None:
            self._optimizer = optim.Adam(self._net.parameters(), weight_decay=self._l2, lr=self._learning_rate)
        else:
            self._optimizer = self._optimizer_func(self._net.parameters())

        if self._loss == 'pointwise':
            self._loss_func = pointwise_loss
        elif self._loss == 'bpr':
            self._loss_func = bpr_loss
        elif self._loss == 'hinge':
            self._loss_func = hinge_loss
        else:
            self._loss_func = adaptive_hinge_loss
Esempio n. 4
0
    def objective(hyper):

        print(hyper)

        start = time.clock()

        if hyper['model']['type'] == 'lsh':
            num_hashes = int(hyper['model']['num_hash_functions'])
            num_layers = int(hyper['model']['num_layers'])
            nonlinearity = hyper['model']['nonlinearity']
            residual = hyper['model']['residual']
            embed = hyper['model']['embed']

            item_embeddings = LSHEmbedding(train.num_items,
                                           int(hyper['embedding_dim']),
                                           embed=embed,
                                           residual_connections=residual,
                                           nonlinearity=nonlinearity,
                                           num_layers=num_layers,
                                           num_hash_functions=num_hashes)
            item_embeddings.fit(train_nonsequence.tocsr().T)
        else:
            item_embeddings = ScaledEmbedding(train.num_items,
                                              int(hyper['embedding_dim']),
                                              padding_idx=0)

        network = LSTMNet(train.num_items,
                          int(hyper['embedding_dim']),
                          item_embedding_layer=item_embeddings)

        model = ImplicitSequenceModel(loss=hyper['loss'],
                                      n_iter=int(hyper['n_iter']),
                                      batch_size=int(hyper['batch_size']),
                                      learning_rate=hyper['learning_rate'],
                                      embedding_dim=int(
                                          hyper['embedding_dim']),
                                      l2=hyper['l2'],
                                      representation=network,
                                      use_cuda=CUDA,
                                      random_state=random_state)

        model.fit(train, verbose=True)

        elapsed = time.clock() - start

        print(model)

        validation_mrr = sequence_mrr_score(model, validation).mean()
        test_mrr = sequence_mrr_score(model, test).mean()

        print('MRR {} {}'.format(validation_mrr, test_mrr))

        return {
            'loss': -validation_mrr,
            'status': STATUS_OK,
            'validation_mrr': validation_mrr,
            'test_mrr': test_mrr,
            'elapsed': elapsed,
            'hyper': hyper
        }
Esempio n. 5
0
def sequence_model(num_embeddings, bloom):

    if bloom:
        item_embeddings = BloomEmbedding(num_embeddings, EMBEDDING_DIM, num_hash_functions=NUM_HASH_FUNCTIONS)
    else:
        item_embeddings = ScaledEmbedding(num_embeddings, EMBEDDING_DIM)

    network = LSTMNet(num_embeddings, EMBEDDING_DIM, item_embedding_layer=item_embeddings)

    model = ImplicitSequenceModel(
        loss='adaptive_hinge',
        n_iter=N_ITER,
        batch_size=512,
        learning_rate=1e-3,
        l2=1e-2,
        representation=network,
        use_cuda=CUDA)

    return model
Esempio n. 6
0
    def fit(self, interactions, verbose=False):
        """
        Fit the model.

        Parameters
        ----------

        interactions: :class:`spotlight.interactions.SequenceInteractions`
            The input sequence dataset.
        """

        sequences = interactions.sequences.astype(np.int64)

        self._num_items = interactions.num_items

        if self._representation == 'pooling':
            self._net = PoolNet(self._num_items,
                                self._embedding_dim,
                                sparse=self._sparse)
        elif self._representation == 'cnn':
            self._net = CNNNet(self._num_items,
                               self._embedding_dim,
                               sparse=self._sparse)
        elif self._representation == 'lstm':
            self._net = LSTMNet(self._num_items,
                                self._embedding_dim,
                                sparse=self._sparse)
        else:
            self._net = self._representation

        self._net = gpu(self._net, self._use_cuda)

        if self._optimizer is None:
            self._optimizer = optim.Adam(self._net.parameters(),
                                         weight_decay=self._l2,
                                         lr=self._learning_rate)

        if self._loss == 'pointwise':
            loss_fnc = pointwise_loss
        elif self._loss == 'bpr':
            loss_fnc = bpr_loss
        elif self._loss == 'hinge':
            loss_fnc = hinge_loss
        else:
            loss_fnc = adaptive_hinge_loss

        for epoch_num in range(self._n_iter):

            sequences = shuffle(sequences, random_state=self._random_state)

            sequences_tensor = gpu(torch.from_numpy(sequences), self._use_cuda)

            epoch_loss = 0.0

            for minibatch_num, batch_sequence in enumerate(
                    minibatch(sequences_tensor, batch_size=self._batch_size)):

                sequence_var = Variable(batch_sequence)

                user_representation, _ = self._net.user_representation(
                    sequence_var)

                positive_prediction = self._net(user_representation,
                                                sequence_var)

                if self._loss == 'adaptive_hinge':
                    negative_prediction = [
                        self._get_negative_prediction(sequence_var.size(),
                                                      user_representation)
                        for __ in range(5)
                    ]
                else:
                    negative_prediction = self._get_negative_prediction(
                        sequence_var.size(), user_representation)

                self._optimizer.zero_grad()

                loss = loss_fnc(positive_prediction,
                                negative_prediction,
                                mask=(sequence_var != PADDING_IDX))
                epoch_loss += loss.data[0]

                loss.backward()
                self._optimizer.step()

            epoch_loss /= minibatch_num + 1

            if verbose:
                print('Epoch {}: loss {}'.format(epoch_num, epoch_loss))
Esempio n. 7
0
min_sequence_length = 10
max_sequence_length = 200
step_size = 1

train = train.to_sequence(max_sequence_length=max_sequence_length,
                          min_sequence_length=min_sequence_length,
                          step_size=step_size)
test = test.to_sequence(max_sequence_length=max_sequence_length,
                        min_sequence_length=min_sequence_length,
                        step_size=step_size)
validation = validation.to_sequence(max_sequence_length=max_sequence_length,
                                    min_sequence_length=min_sequence_length,
                                    step_size=step_size)

net = LSTMNet(len(set(item2idx)),
              embedding_dim=32,
              item_embedding_layer=None,
              sparse=False)
model = ImplicitSequenceModel(loss='adaptive_hinge',
                              representation=net,
                              batch_size=32,
                              learning_rate=0.01,
                              l2=10e-6,
                              n_iter=10,
                              use_cuda=False,
                              random_state=random_state)
model.fit(train, verbose=True)

test_mrr = sequence_mrr_score(model, test)
val_mrr = sequence_mrr_score(model, validation)
train_mrr = sequence_mrr_score(model, train)
Esempio n. 8
0
    def objective(hyper):

        print(hyper)

        start = time.clock()

        h = hyper['model']

        cls = ImplicitSequenceModel

        if h['type'] == 'pooling':
            representation = PoolNet(train.num_items,
                                     embedding_dim=int(h['embedding_dim']))
        elif h['type'] == 'lstm':
            representation = LSTMNet(train.num_items,
                                     embedding_dim=int(h['embedding_dim']))
        elif h['type'] == 'mixture':
            num_components = int(h['num_components'])
            embedding_dim = int(h['embedding_dim'])
            representation = MixtureLSTMNet(train.num_items,
                                            num_components=num_components,
                                            embedding_dim=embedding_dim)
        elif h['type'] == 'mixture2':
            num_components = int(h['num_components'])
            embedding_dim = int(h['embedding_dim'])
            representation = Mixture2LSTMNet(train.num_items,
                                             num_components=num_components,
                                             embedding_dim=embedding_dim)
        elif h['type'] == 'linear_mixture':
            num_components = int(h['num_components'])
            embedding_dim = int(h['embedding_dim'])
            representation = LinearMixtureLSTMNet(train.num_items,
                                                  num_components=num_components,
                                                  embedding_dim=embedding_dim)
        elif h['type'] == 'diversified_mixture_fixed':
            num_components = int(h['num_components'])
            embedding_dim = int(h['embedding_dim'])
            representation = DiversifiedMixtureLSTMNet(train.num_items,
                                                       num_components=num_components,
                                                       diversity_penalty=h['diversity_penalty'],
                                                       embedding_dim=embedding_dim)
            cls = DiversifiedImplicitSequenceModel
        else:
            raise ValueError('Unknown model type')

        model = cls(
            batch_size=int(h['batch_size']),
            loss=h['loss'],
            learning_rate=h['learning_rate'],
            l2=h['l2'],
            n_iter=int(h['n_iter']),
            representation=representation,
            use_cuda=CUDA,
            random_state=np.random.RandomState(42)
        )

        try:
            model.fit(train, verbose=True)
        except ValueError:
            elapsed = time.clock() - start
            return {'loss': 0.0,
                    'status': STATUS_FAIL,
                    'validation_mrr': 0.0,
                    'test_mrr': 0.0,
                    'elapsed': elapsed,
                    'hyper': h}

        elapsed = time.clock() - start

        print(model)

        validation_mrr = sequence_mrr_score(
            model,
            validation,
            exclude_preceding=True
        ).mean()
        test_mrr = sequence_mrr_score(
            model,
            test,
            exclude_preceding=True
        ).mean()

        print('MRR {} {}'.format(validation_mrr, test_mrr))

        if np.isnan(validation_mrr):
            status = STATUS_FAIL
        else:
            status = STATUS_OK

        return {'loss': -validation_mrr,
                'status': status,
                'validation_mrr': validation_mrr,
                'test_mrr': test_mrr,
                'elapsed': elapsed,
                'hyper': h}