def test_bloom_pooling(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=2) representation = PoolNet(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
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
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))
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}