Exemple #1
0
    def __init__(self,
                embedding_size,
                user_total,
                item_total,
                ):
        super(BPRMF, self).__init__()
        self.embedding_size = embedding_size
        self.user_total = user_total
        self.item_total = item_total
        self.is_pretrained = False

        # init user and item embeddings
        user_weight = torch.FloatTensor(self.user_total, self.embedding_size)
        item_weight = torch.FloatTensor(self.item_total, self.embedding_size)
        nn.init.xavier_uniform(user_weight)
        nn.init.xavier_uniform(item_weight)
        # init user and item embeddings
        self.user_embeddings = nn.Embedding(self.user_total, self.embedding_size)
        self.item_embeddings = nn.Embedding(self.item_total, self.embedding_size)
        self.user_embeddings.weight = nn.Parameter(user_weight)
        self.item_embeddings.weight = nn.Parameter(item_weight)
        normalize_user_emb = F.normalize(self.user_embeddings.weight.data, p=2, dim=1)
        normalize_item_emb = F.normalize(self.item_embeddings.weight.data, p=2, dim=1)
        self.user_embeddings.weight.data = normalize_user_emb
        self.item_embeddings.weight.data = normalize_item_emb

        self.user_embeddings = to_gpu(self.user_embeddings)
        self.item_embeddings = to_gpu(self.item_embeddings)
Exemple #2
0
    def __init__(self,
                L1_flag,
                embedding_size,
                ent_total,
                rel_total
                ):
        super(TransEModel, self).__init__()
        self.L1_flag = L1_flag
        self.embedding_size = embedding_size
        self.ent_total = ent_total
        self.rel_total = rel_total
        self.is_pretrained = False

        ent_weight = torch.FloatTensor(self.ent_total, self.embedding_size)
        rel_weight = torch.FloatTensor(self.rel_total, self.embedding_size)
        nn.init.xavier_uniform(ent_weight)
        nn.init.xavier_uniform(rel_weight)
        # init user and item embeddings
        self.ent_embeddings = nn.Embedding(self.ent_total, self.embedding_size)
        self.rel_embeddings = nn.Embedding(self.rel_total, self.embedding_size)

        self.ent_embeddings.weight = nn.Parameter(ent_weight)
        self.rel_embeddings.weight = nn.Parameter(rel_weight)

        normalize_ent_emb = F.normalize(self.ent_embeddings.weight.data, p=2, dim=1)
        normalize_rel_emb = F.normalize(self.rel_embeddings.weight.data, p=2, dim=1)

        self.ent_embeddings.weight.data = normalize_ent_emb
        self.rel_embeddings.weight.data = normalize_rel_emb

        self.ent_embeddings = to_gpu(self.ent_embeddings)
        self.rel_embeddings = to_gpu(self.rel_embeddings)
Exemple #3
0
    def __init__(self, L1_flag, embedding_size, user_total, item_total,
                 preference_total, use_st_gumbel):
        super(TransUPModel, self).__init__()
        self.L1_flag = L1_flag
        self.embedding_size = embedding_size
        self.user_total = user_total
        self.item_total = item_total
        self.preference_total = preference_total
        self.is_pretrained = False
        self.use_st_gumbel = use_st_gumbel

        user_weight = torch.FloatTensor(self.user_total, self.embedding_size)
        item_weight = torch.FloatTensor(self.item_total, self.embedding_size)
        pref_weight = torch.FloatTensor(self.preference_total,
                                        self.embedding_size)
        norm_weight = torch.FloatTensor(self.preference_total,
                                        self.embedding_size)
        nn.init.xavier_uniform(user_weight)

        nn.init.xavier_uniform(item_weight)
        nn.init.xavier_uniform(pref_weight)
        nn.init.xavier_uniform(norm_weight)
        # init user and item embeddings
        self.user_embeddings = nn.Embedding(self.user_total,
                                            self.embedding_size)
        self.item_embeddings = nn.Embedding(self.item_total,
                                            self.embedding_size)
        self.user_embeddings.weight = nn.Parameter(user_weight)
        self.item_embeddings.weight = nn.Parameter(item_weight)
        normalize_user_emb = F.normalize(self.user_embeddings.weight.data,
                                         p=2,
                                         dim=1)
        normalize_item_emb = F.normalize(self.item_embeddings.weight.data,
                                         p=2,
                                         dim=1)
        self.user_embeddings.weight.data = normalize_user_emb
        self.item_embeddings.weight.data = normalize_item_emb
        # init preference parameters
        self.pref_embeddings = nn.Embedding(self.preference_total,
                                            self.embedding_size)
        self.pref_norm_embeddings = nn.Embedding(self.preference_total,
                                                 self.embedding_size)
        self.pref_embeddings.weight = nn.Parameter(pref_weight)
        self.pref_norm_embeddings.weight = nn.Parameter(norm_weight)
        normalize_pref_emb = F.normalize(self.pref_embeddings.weight.data,
                                         p=2,
                                         dim=1)
        normalize_norm_emb = F.normalize(self.pref_norm_embeddings.weight.data,
                                         p=2,
                                         dim=1)
        self.pref_embeddings.weight.data = normalize_pref_emb
        self.pref_norm_embeddings.weight.data = normalize_norm_emb

        self.user_embeddings = to_gpu(self.user_embeddings)
        self.item_embeddings = to_gpu(self.item_embeddings)
        self.pref_embeddings = to_gpu(self.pref_embeddings)
        self.pref_norm_embeddings = to_gpu(self.pref_norm_embeddings)
def evaluateRec(FLAGS, model, eval_iter, eval_dict, all_dicts, i_map, logger, eval_descending=True, is_report=False):
    # Evaluate
    total_batches = len(eval_iter)
    # processing bar
    pbar = tqdm(total=total_batches)
    pbar.set_description("Run Eval")

    all_i_var = None
    if FLAGS.share_embeddings:
        all_i_ids = [i_map[i] for i in range(len(i_map))]
        all_i_var = to_gpu(V(torch.LongTensor(all_i_ids)))

    model.eval()
    model.disable_grad()

    results = []
    for u_ids in eval_iter:
        u_var = to_gpu(V(torch.LongTensor(u_ids)))
        # batch * item
        scores = model.evaluateRec(u_var, all_i_ids=all_i_var)
        preds = zip(u_ids, scores.data.cpu().numpy())

        results.extend( evalRecProcess(list(preds), eval_dict, all_dicts=all_dicts, descending=eval_descending, num_processes=FLAGS.num_processes, topn=FLAGS.topn, queue_limit=FLAGS.max_queue) )

        pbar.update(1)
    pbar.close()

    performances = [result[:5] for result in results]

    f1, p, r, hit, ndcg = np.array(performances).mean(axis=0)

    logger.info("f1:{:.4f}, p:{:.4f}, r:{:.4f}, hit:{:.4f}, ndcg:{:.4f}, topn:{}.".format(f1, p, r, hit, ndcg, FLAGS.topn))

    if is_report:
        predict_tuples = [result[-1] for result in results]
        for pred_tuple in predict_tuples:
            u_id = pred_tuple[0]
            top_ids = pred_tuple[1]
            gold_ids = list(pred_tuple[2])
            if FLAGS.model_type in ["transup", "jtransup"]:
                for d in all_dicts:
                    gold_ids += list(d.get(u_id, set()))
                gold_ids += list(eval_dict.get(u_id, set()))
                
                u_var = to_gpu(V(torch.LongTensor([u_id])))
                i_var = to_gpu(V(torch.LongTensor(gold_ids)))

                probs, _, _ = model.reportPreference(u_var, i_var)
                max_rel_index = torch.max(probs, 1)[1]
                gold_strs = ",".join(["{}({})".format(ir[0], ir[1]) for ir in zip(gold_ids, max_rel_index.data.tolist())])
            else:
                gold_strs = ",".join([str(i) for i in gold_ids])
            logger.info("user:{}\tgold:{}\ttop:{}".format(u_id, gold_strs, ",".join([str(i) for i in top_ids])))
    model.enable_grad()
    return f1, p, r, hit, ndcg
Exemple #5
0
    def __init__(self, L1_flag, embedding_size, user_total, item_total,
                 entity_total, relation_total):
        super(CFKG, self).__init__()
        self.L1_flag = L1_flag
        self.embedding_size = embedding_size
        self.user_total = user_total
        self.item_total = item_total
        self.ent_total = entity_total
        # add buy relation between user and item
        self.rel_total = relation_total + 1
        self.is_pretrained = False

        # init user embeddings
        user_weight = torch.FloatTensor(self.user_total, self.embedding_size)
        nn.init.xavier_uniform(user_weight)

        self.user_embeddings = nn.Embedding(self.user_total,
                                            self.embedding_size)
        self.user_embeddings.weight = nn.Parameter(user_weight)
        normalize_user_emb = F.normalize(self.user_embeddings.weight.data,
                                         p=2,
                                         dim=1)
        self.user_embeddings.weight.data = normalize_user_emb
        self.user_embeddings = to_gpu(self.user_embeddings)

        # init entity and relation embeddings
        ent_weight = torch.FloatTensor(self.ent_total, self.embedding_size)
        rel_weight = torch.FloatTensor(self.rel_total, self.embedding_size)
        nn.init.xavier_uniform(ent_weight)
        nn.init.xavier_uniform(rel_weight)
        self.ent_embeddings = nn.Embedding(self.ent_total, self.embedding_size)
        self.rel_embeddings = nn.Embedding(self.rel_total, self.embedding_size)

        self.ent_embeddings.weight = nn.Parameter(ent_weight)
        self.rel_embeddings.weight = nn.Parameter(rel_weight)

        normalize_ent_emb = F.normalize(self.ent_embeddings.weight.data,
                                        p=2,
                                        dim=1)
        normalize_rel_emb = F.normalize(self.rel_embeddings.weight.data,
                                        p=2,
                                        dim=1)

        self.ent_embeddings.weight.data = normalize_ent_emb
        self.rel_embeddings.weight.data = normalize_rel_emb

        self.ent_embeddings = to_gpu(self.ent_embeddings)
        self.rel_embeddings = to_gpu(self.rel_embeddings)

        # share embedding
        self.item_embeddings = self.ent_embeddings
    def forward(self, ratings, triples, is_rec=True):

        if is_rec and ratings is not None:
            u_ids, i_ids = ratings

            e_ids = self.paddingItems(i_ids.data, self.ent_total - 1)
            e_var = to_gpu(V(torch.LongTensor(e_ids)))

            u_e = self.user_embeddings(u_ids)
            i_e = self.item_embeddings(i_ids)
            e_e = self.ent_embeddings(e_var)
            ie_e = i_e + e_e

            score = torch.bmm(u_e.unsqueeze(1), ie_e.unsqueeze(2)).squeeze()
        elif not is_rec and triples is not None:
            h, t, r = triples
            h_e = self.ent_embeddings(h)
            t_e = self.ent_embeddings(t)
            r_e = self.rel_embeddings(r)
            proj_e = self.proj_embeddings(r)

            proj_h_e = projection_transR_pytorch(h_e, proj_e)
            proj_t_e = projection_transR_pytorch(t_e, proj_e)

            if self.L1_flag:
                score = torch.sum(torch.abs(proj_h_e + r_e - proj_t_e), 1)
            else:
                score = torch.sum((proj_h_e + r_e - proj_t_e)**2, 1)
        else:
            raise NotImplementedError

        return score
Exemple #7
0
    def forward(self, ratings, triples, is_rec=True):

        if is_rec and ratings is not None:
            u_ids, i_ids = ratings
            batch_size = len(u_ids)

            u_e = self.user_embeddings(u_ids)
            i_e = self.item_embeddings(i_ids)

            buy_e = self.rel_embeddings(
                to_gpu(V(torch.LongTensor([self.rel_total - 1]))))
            buy_e_expand = buy_e.expand(batch_size, self.embedding_size)
            # L1 distance
            if self.L1_flag:
                score = torch.sum(torch.abs(u_e + buy_e_expand - i_e), 1)
            # L2 distance
            else:
                score = torch.sum((u_e + buy_e_expand - i_e)**2, 1)

        elif not is_rec and triples is not None:
            h, t, r = triples
            h_e = self.ent_embeddings(h)
            t_e = self.ent_embeddings(t)
            r_e = self.rel_embeddings(r)

            # L1 distance
            if self.L1_flag:
                score = torch.sum(torch.abs(h_e + r_e - t_e), 1)
            # L2 distance
            else:
                score = torch.sum((h_e + r_e - t_e)**2, 1)
        else:
            raise NotImplementedError

        return score
    def evaluateRec(self, u_ids, all_i_ids=None):
        batch_size = len(u_ids)
        all_i = self.item_embeddings(
            all_i_ids
        ) if all_i_ids is not None and self.is_share else self.item_embeddings.weight
        item_total, dim = all_i.size()

        u = self.user_embeddings(u_ids)
        # expand u and i to pair wise match, batch * item * dim
        u_e = u.expand(item_total, batch_size, dim).permute(1, 0, 2)

        i_e = all_i.expand(batch_size, item_total, dim)

        e_ids = self.paddingItems(
            all_i_ids.data if all_i_ids is not None else self.i_map,
            self.ent_total - 1)
        e_var = to_gpu(V(torch.LongTensor(e_ids)))
        e_e = self.ent_embeddings(e_var).expand(batch_size, item_total, dim)

        ie_e = i_e + e_e

        # batch * item * dim
        _, r_e, norm = self.getPreferences(u_e,
                                           ie_e,
                                           use_st_gumbel=self.use_st_gumbel)

        proj_u_e = projection_transH_pytorch(u_e, norm)
        proj_i_e = projection_transH_pytorch(ie_e, norm)

        # batch * item
        if self.L1_flag:
            score = torch.sum(torch.abs(proj_u_e + r_e - proj_i_e), 2)
        else:
            score = torch.sum((proj_u_e + r_e - proj_i_e)**2, 2)
        return score
Exemple #9
0
    def evaluateRec(self, u_ids, all_i_ids=None):
        batch_size = len(u_ids)
        all_i = self.item_embeddings(
            all_i_ids
        ) if all_i_ids is not None else self.item_embeddings.weight
        item_total, dim = all_i.size()
        # batch * dim
        u_e = self.user_embeddings(u_ids)
        # batch * item * dim
        u_e_expand = u_e.expand(item_total, batch_size, dim).permute(1, 0, 2)

        buy_e = self.rel_embeddings(
            to_gpu(V(torch.LongTensor([self.rel_total - 1]))))
        buy_e_expand = buy_e.expand(batch_size, item_total, dim)

        c_i_e = u_e_expand + buy_e_expand

        # batch * item * dim
        i_expand = all_i.expand(batch_size, item_total, dim)

        if self.L1_flag:
            score = torch.sum(torch.abs(c_i_e - i_expand), 2)
        else:
            score = torch.sum((c_i_e - i_expand)**2, 2)
        return score
    def __init__(self, L1_flag, embedding_size, ent_total, rel_total):
        super(TransRModel, self).__init__()
        self.L1_flag = L1_flag
        self.embedding_size = embedding_size
        self.ent_total = ent_total
        self.rel_total = rel_total
        self.is_pretrained = False
        self.max_entity_batch = 10

        ent_weight = torch.FloatTensor(self.ent_total, self.embedding_size)
        rel_weight = torch.FloatTensor(self.rel_total, self.embedding_size)
        proj_weight = torch.FloatTensor(
            self.rel_total, self.embedding_size * self.embedding_size)
        nn.init.xavier_uniform(ent_weight)
        nn.init.xavier_uniform(rel_weight)

        if self.is_pretrained:
            nn.init.eye(proj_weight)
            proj_weight = proj_weight.view(-1).expand(self.relation_total, -1)
        else:
            nn.init.xavier_uniform(proj_weight)

        # init user and item embeddings
        self.ent_embeddings = nn.Embedding(self.ent_total, self.embedding_size)
        self.rel_embeddings = nn.Embedding(self.rel_total, self.embedding_size)
        self.proj_embeddings = nn.Embedding(
            self.rel_total, self.embedding_size * self.embedding_size)

        self.ent_embeddings.weight = nn.Parameter(ent_weight)
        self.rel_embeddings.weight = nn.Parameter(rel_weight)
        self.proj_embeddings.weight = nn.Parameter(proj_weight)

        normalize_ent_emb = F.normalize(self.ent_embeddings.weight.data,
                                        p=2,
                                        dim=1)
        normalize_rel_emb = F.normalize(self.rel_embeddings.weight.data,
                                        p=2,
                                        dim=1)
        # normalize_proj_emb = F.normalize(self.proj_embeddings.weight.data, p=2, dim=1)

        self.ent_embeddings.weight.data = normalize_ent_emb
        self.rel_embeddings.weight.data = normalize_rel_emb
        # self.proj_embeddings.weight.data = normalize_proj_emb

        self.ent_embeddings = to_gpu(self.ent_embeddings)
        self.rel_embeddings = to_gpu(self.rel_embeddings)
        self.proj_embeddings = to_gpu(self.proj_embeddings)
    def reportPreference(self, u_id, i_ids):
        item_num = len(i_ids)
        # item * dim
        u_e = self.user_embeddings(u_id.expand(item_num))
        i_e = self.item_embeddings(i_ids)

        e_ids = self.paddingItems(i_ids.data, self.ent_total - 1)
        e_var = to_gpu(V(torch.LongTensor(e_ids)))
        e_e = self.ent_embeddings(e_var)
        ie_e = i_e + e_e

        return self.getPreferences(u_e, ie_e, use_st_gumbel=self.use_st_gumbel)
    def evaluateRec(self, u_ids, all_i_ids=None):
        batch_size = len(u_ids)
        i_ids = range(len(self.item_embeddings.weight))
        e_ids = self.paddingItems(i_ids, self.ent_total - 1)
        e_var = to_gpu(V(torch.LongTensor(e_ids)))
        e_e = self.ent_embeddings(e_var)

        all_ie_e = self.item_embeddings.weight + e_e

        u_e = self.user_embeddings(u_ids)

        return torch.matmul(u_e, all_ie_e.t())
    def forward(self, ratings, triples, is_rec=True):

        if is_rec and ratings is not None:
            u_ids, i_ids = ratings

            e_ids = self.paddingItems(i_ids.data, self.ent_total - 1)
            e_var = to_gpu(V(torch.LongTensor(e_ids)))

            u_e = self.user_embeddings(u_ids)
            i_e = self.item_embeddings(i_ids)
            e_e = self.ent_embeddings(e_var)
            ie_e = i_e + e_e

            _, r_e, norm = self.getPreferences(
                u_e, ie_e, use_st_gumbel=self.use_st_gumbel)

            proj_u_e = projection_transH_pytorch(u_e, norm)
            proj_i_e = projection_transH_pytorch(ie_e, norm)

            if self.L1_flag:
                score = torch.sum(torch.abs(proj_u_e + r_e - proj_i_e), 1)
            else:
                score = torch.sum((proj_u_e + r_e - proj_i_e)**2, 1)
        elif not is_rec and triples is not None:
            h, t, r = triples
            h_e = self.ent_embeddings(h)
            t_e = self.ent_embeddings(t)
            r_e = self.rel_embeddings(r)
            norm_e = self.norm_embeddings(r)

            proj_h_e = projection_transH_pytorch(h_e, norm_e)
            proj_t_e = projection_transH_pytorch(t_e, norm_e)

            if self.L1_flag:
                score = torch.sum(torch.abs(proj_h_e + r_e - proj_t_e), 1)
            else:
                score = torch.sum((proj_h_e + r_e - proj_t_e)**2, 1)
        else:
            raise NotImplementedError

        return score
def train_loop(FLAGS,
               model,
               trainer,
               rating_train_dataset,
               triple_train_dataset,
               rating_eval_datasets,
               triple_eval_datasets,
               e_map,
               i_map,
               ikg_map,
               logger,
               vis=None,
               is_report=False):
    rating_train_iter, rating_train_total, rating_train_list, rating_train_dict = rating_train_dataset

    triple_train_iter, triple_train_total, triple_train_list, head_train_dict, tail_train_dict = triple_train_dataset

    all_rating_dicts = None
    if FLAGS.filter_wrong_corrupted:
        all_rating_dicts = [rating_train_dict] + [
            tmp_data[3] for tmp_data in rating_eval_datasets
        ]

    all_head_dicts = None
    all_tail_dicts = None
    if FLAGS.filter_wrong_corrupted:
        all_head_dicts = [head_train_dict] + [
            tmp_data[4] for tmp_data in triple_eval_datasets
        ]
        all_tail_dicts = [tail_train_dict] + [
            tmp_data[5] for tmp_data in triple_eval_datasets
        ]

    item_total = len(i_map)
    entity_total = len(e_map)
    step_to_switch = 10 * FLAGS.joint_ratio

    # Train.
    logger.info("Training.")

    # New Training Loop
    pbar = None
    rec_total_loss = 0.0
    kg_total_loss = 0.0
    model.train()
    model.enable_grad()
    for _ in range(trainer.step, FLAGS.training_steps):

        if FLAGS.early_stopping_steps_to_wait > 0 and (
                trainer.step -
                trainer.best_step) > FLAGS.early_stopping_steps_to_wait:
            logger.info('No improvement after ' +
                        str(FLAGS.early_stopping_steps_to_wait) +
                        ' steps. Stopping training.')
            if pbar is not None: pbar.close()
            break
        if trainer.step % FLAGS.eval_interval_steps == 0:
            if pbar is not None:
                pbar.close()
            rec_total_loss /= (FLAGS.eval_interval_steps * FLAGS.joint_ratio)
            kg_total_loss /= (FLAGS.eval_interval_steps *
                              (1 - FLAGS.joint_ratio))
            logger.info("rec train loss:{:.4f}, kg train loss:{:.4f}!".format(
                rec_total_loss, kg_total_loss))

            rec_performances = []
            for i, eval_data in enumerate(rating_eval_datasets):
                all_eval_dicts = None
                if FLAGS.filter_wrong_corrupted:
                    all_eval_dicts = [rating_train_dict] + [
                        tmp_data[3]
                        for j, tmp_data in enumerate(rating_eval_datasets)
                        if j != i
                    ]

                rec_performances.append(
                    evaluateRec(FLAGS,
                                model,
                                eval_data[0],
                                eval_data[3],
                                all_eval_dicts,
                                i_map,
                                logger,
                                eval_descending=True
                                if trainer.model_target == 1 else False,
                                is_report=is_report))

            kg_performances = []
            for i, eval_data in enumerate(triple_eval_datasets):
                eval_head_dicts = None
                eval_tail_dicts = None
                if FLAGS.filter_wrong_corrupted:
                    eval_head_dicts = [head_train_dict] + [
                        tmp_data[4]
                        for j, tmp_data in enumerate(triple_eval_datasets)
                        if j != i
                    ]
                    eval_tail_dicts = [tail_train_dict] + [
                        tmp_data[5]
                        for j, tmp_data in enumerate(triple_eval_datasets)
                        if j != i
                    ]

                kg_performances.append(
                    evaluateKG(FLAGS,
                               model,
                               eval_data[0],
                               eval_data[1],
                               eval_data[4],
                               eval_data[5],
                               eval_head_dicts,
                               eval_tail_dicts,
                               e_map,
                               logger,
                               eval_descending=False,
                               is_report=is_report))

            if trainer.step > 0:
                is_best = trainer.new_performance(kg_performances[0],
                                                  kg_performances)
                # visuliazation
                if vis is not None:
                    vis.plot_many_stack(
                        {
                            'Rec Train Loss': rec_total_loss,
                            'KG Train Loss': kg_total_loss
                        },
                        win_name="Loss Curve")

                    f1_dict = {}
                    p_dict = {}
                    r_dict = {}
                    rec_hit_dict = {}
                    ndcg_dict = {}
                    for i, performance in enumerate(rec_performances):
                        f1_dict['Rec Eval {} F1'.format(i)] = performance[0]
                        p_dict['Rec Eval {} Precision'.format(
                            i)] = performance[1]
                        r_dict['Rec Eval {} Recall'.format(i)] = performance[2]
                        rec_hit_dict['Rec Eval {} Hit'.format(
                            i)] = performance[3]
                        ndcg_dict['Rec Eval {} NDCG'.format(
                            i)] = performance[4]

                    kg_hit_dict = {}
                    meanrank_dict = {}
                    for i, performance in enumerate(kg_performances):
                        kg_hit_dict['KG Eval {} Hit'.format(
                            i)] = performance[0]
                        meanrank_dict['KG Eval {} MeanRank'.format(
                            i)] = performance[1]

                    if is_best:
                        log_str = [
                            "Best performances in {} step!".format(
                                trainer.best_step)
                        ]
                        log_str += [
                            "{} : {}.".format(s, "%.5f" % f1_dict[s])
                            for s in f1_dict
                        ]
                        log_str += [
                            "{} : {}.".format(s, "%.5f" % p_dict[s])
                            for s in p_dict
                        ]
                        log_str += [
                            "{} : {}.".format(s, "%.5f" % r_dict[s])
                            for s in r_dict
                        ]
                        log_str += [
                            "{} : {}.".format(s, "%.5f" % rec_hit_dict[s])
                            for s in rec_hit_dict
                        ]
                        log_str += [
                            "{} : {}.".format(s, "%.5f" % ndcg_dict[s])
                            for s in ndcg_dict
                        ]
                        log_str += [
                            "{} : {}.".format(s, "%.5f" % kg_hit_dict[s])
                            for s in kg_hit_dict
                        ]
                        log_str += [
                            "{} : {}.".format(s, "%.5f" % meanrank_dict[s])
                            for s in meanrank_dict
                        ]

                        vis.log("\n".join(log_str),
                                win_name="Best Performances")

                    vis.plot_many_stack(f1_dict,
                                        win_name="Rec F1 Score@{}".format(
                                            FLAGS.topn))

                    vis.plot_many_stack(p_dict,
                                        win_name="Rec Precision@{}".format(
                                            FLAGS.topn))

                    vis.plot_many_stack(r_dict,
                                        win_name="Rec Recall@{}".format(
                                            FLAGS.topn))

                    vis.plot_many_stack(rec_hit_dict,
                                        win_name="Rec Hit Ratio@{}".format(
                                            FLAGS.topn))

                    vis.plot_many_stack(ndcg_dict,
                                        win_name="Rec NDCG@{}".format(
                                            FLAGS.topn))

                    vis.plot_many_stack(kg_hit_dict,
                                        win_name="KG Hit Ratio@{}".format(
                                            FLAGS.topn))

                    vis.plot_many_stack(meanrank_dict, win_name="KG MeanRank")

            # set model in training mode
            pbar = tqdm(total=FLAGS.eval_interval_steps)
            pbar.set_description("Training")
            rec_total_loss = 0.0
            kg_total_loss = 0.0

            model.train()
            model.enable_grad()

        # recommendation train
        if trainer.step % 10 < step_to_switch:
            rating_batch = next(rating_train_iter)
            u, pi, ni = getNegRatings(rating_batch,
                                      item_total,
                                      all_dicts=all_rating_dicts)

            e_ids, i_ids = getMappedEntities(pi + ni, i_map, ikg_map)

            if FLAGS.share_embeddings:
                ni = [i_map[i] for i in ni]
                pi = [i_map[i] for i in pi]

            u_var = to_gpu(V(torch.LongTensor(u)))
            pi_var = to_gpu(V(torch.LongTensor(pi)))
            ni_var = to_gpu(V(torch.LongTensor(ni)))

            trainer.optimizer_zero_grad()

            # Run model. output: batch_size * cand_num, input: ratings, triples, is_rec=True
            pos_score = model((u_var, pi_var), None, is_rec=True)
            neg_score = model((u_var, ni_var), None, is_rec=True)

            # Calculate loss.
            losses = bprLoss(pos_score, neg_score, target=trainer.model_target)

            if FLAGS.model_type in ["transup", "jtransup"]:
                losses += orthogonalLoss(model.pref_embeddings.weight,
                                         model.pref_norm_embeddings.weight)
        # kg train
        else:
            triple_batch = next(triple_train_iter)
            ph, pt, pr, nh, nt, nr = getTrainTripleBatch(
                triple_batch,
                entity_total,
                all_head_dicts=all_head_dicts,
                all_tail_dicts=all_tail_dicts)

            e_ids, i_ids = getMappedItems(ph + pt + nh + nt, e_map, ikg_map)

            if FLAGS.share_embeddings:
                ph = [e_map[e] for e in ph]
                pt = [e_map[e] for e in pt]
                nh = [e_map[e] for e in nh]
                nt = [e_map[e] for e in nt]

            ph_var = to_gpu(V(torch.LongTensor(ph)))
            pt_var = to_gpu(V(torch.LongTensor(pt)))
            pr_var = to_gpu(V(torch.LongTensor(pr)))
            nh_var = to_gpu(V(torch.LongTensor(nh)))
            nt_var = to_gpu(V(torch.LongTensor(nt)))
            nr_var = to_gpu(V(torch.LongTensor(nr)))

            trainer.optimizer_zero_grad()

            # Run model. output: batch_size * cand_nu, input: ratings, triples, is_rec=True
            pos_score = model(None, (ph_var, pt_var, pr_var), is_rec=False)
            neg_score = model(None, (nh_var, nt_var, nr_var), is_rec=False)

            # Calculate loss.
            # losses = nn.MarginRankingLoss(margin=FLAGS.margin).forward(pos_score, neg_score, to_gpu(torch.autograd.Variable(torch.FloatTensor([trainer.model_target]*len(ph)))))

            losses = loss.marginLoss()(pos_score, neg_score, FLAGS.margin)

            ent_embeddings = model.ent_embeddings(
                torch.cat([ph_var, pt_var, nh_var, nt_var]))
            rel_embeddings = model.rel_embeddings(torch.cat([pr_var, nr_var]))
            if FLAGS.model_type in ["jtransup"]:
                norm_embeddings = model.norm_embeddings(
                    torch.cat([pr_var, nr_var]))
                losses += loss.orthogonalLoss(rel_embeddings, norm_embeddings)

            losses = losses + loss.normLoss(ent_embeddings) + loss.normLoss(
                rel_embeddings)
            losses = FLAGS.kg_lambda * losses
        # align loss if not share embeddings
        if not FLAGS.share_embeddings and FLAGS.model_type not in [
                'cke', 'jtransup'
        ]:
            e_var = to_gpu(V(torch.LongTensor(e_ids)))
            i_var = to_gpu(V(torch.LongTensor(i_ids)))
            ent_embeddings = model.ent_embeddings(e_var)
            item_embeddings = model.item_embeddings(i_var)
            losses += FLAGS.norm_lambda * loss.pNormLoss(
                ent_embeddings, item_embeddings, L1_flag=FLAGS.L1_flag)

        # Backward pass.
        losses.backward()

        # for param in model.parameters():
        #     print(param.grad.data.sum())

        # Hard Gradient Clipping
        nn.utils.clip_grad_norm(
            [param for name, param in model.named_parameters()],
            FLAGS.clipping_max_value)

        # Gradient descent step.
        trainer.optimizer_step()
        if trainer.step % 10 < step_to_switch:
            rec_total_loss += losses.data[0]
        else:
            kg_total_loss += losses.data[0]
        pbar.update(1)
def evaluateKG(FLAGS,
               model,
               eval_head_iter,
               eval_tail_iter,
               eval_head_dict,
               eval_tail_dict,
               all_head_dicts,
               all_tail_dicts,
               e_map,
               logger,
               eval_descending=True,
               is_report=False):
    # Evaluate
    total_batches = len(eval_head_iter) + len(eval_tail_iter)
    # processing bar
    pbar = tqdm(total=total_batches)
    pbar.set_description("Run Eval")

    model.eval()
    model.disable_grad()

    all_e_var = None
    if FLAGS.share_embeddings:
        all_e_ids = [e_map[e] for e in range(len(e_map))]
        all_e_var = to_gpu(V(torch.LongTensor(all_e_ids)))

    # head prediction evaluation
    head_results = []

    for batch_trs in eval_head_iter:
        t = [tr[0] for tr in batch_trs] if FLAGS.share_embeddings else [
            e_map[tr[0]] for tr in batch_trs
        ]
        r = [tr[1] for tr in batch_trs]
        t_var = to_gpu(V(torch.LongTensor(t)))
        r_var = to_gpu(V(torch.LongTensor(r)))
        # batch * item
        scores = model.evaluateHead(t_var, r_var, all_e_ids=all_e_var)
        preds = zip(batch_trs, scores.data.cpu().numpy())

        head_results.extend(
            evalKGProcess(list(preds),
                          eval_head_dict,
                          all_dicts=all_head_dicts,
                          descending=eval_descending,
                          num_processes=FLAGS.num_processes,
                          topn=FLAGS.topn,
                          queue_limit=FLAGS.max_queue))

        pbar.update(1)

    # tail prediction evaluation
    tail_results = []
    for batch_hrs in eval_tail_iter:
        h = [hr[0] for hr in batch_hrs] if FLAGS.share_embeddings else [
            e_map[hr[0]] for hr in batch_hrs
        ]
        r = [hr[1] for hr in batch_hrs]
        h_var = to_gpu(V(torch.LongTensor(h)))
        r_var = to_gpu(V(torch.LongTensor(r)))
        # batch * item
        scores = model.evaluateTail(h_var, r_var, all_e_ids=all_e_var)
        preds = zip(batch_hrs, scores.data.cpu().numpy())

        tail_results.extend(
            evalKGProcess(list(preds),
                          eval_tail_dict,
                          all_dicts=all_tail_dicts,
                          descending=eval_descending,
                          num_processes=FLAGS.num_processes,
                          topn=FLAGS.topn,
                          queue_limit=FLAGS.max_queue))

        pbar.update(1)

    pbar.close()

    # hit, rank
    head_performances = [result[:2] for result in head_results]
    tail_performances = [result[:2] for result in tail_results]

    head_hit, head_mean_rank = np.array(head_performances).mean(axis=0)

    tail_hit, tail_mean_rank = np.array(tail_performances).mean(axis=0)

    logger.info("head hit:{:.4f}, head mean rank:{:.4f}, topn:{}.".format(
        head_hit, head_mean_rank, FLAGS.topn))

    logger.info("tail hit:{:.4f}, tail mean rank:{:.4f}, topn:{}.".format(
        tail_hit, tail_mean_rank, FLAGS.topn))

    head_num = len(head_results)
    tail_num = len(tail_results)

    avg_hit = float(head_hit * head_num + tail_hit * tail_num) / (head_num +
                                                                  tail_num)
    avg_mean_rank = float(head_mean_rank * head_num +
                          tail_mean_rank * tail_num) / (head_num + tail_num)

    logger.info("avg hit:{:.4f}, avg mean rank:{:.4f}, topn:{}.".format(
        avg_hit, avg_mean_rank, FLAGS.topn))

    if is_report:
        for result in head_results:
            hit = result[0]
            rank = result[1]
            t = result[2][0]
            r = result[2][1]
            gold_h = result[3]
            logger.info("H\t{}\t{}\t{}\t{}".format(gold_h, t, r, hit))
        for result in tail_results:
            hit = result[0]
            rank = result[1]
            h = result[2][0]
            r = result[2][1]
            gold_t = result[3]
            logger.info("T\t{}\t{}\t{}\t{}".format(h, gold_t, r, hit))
    model.enable_grad()
    return avg_hit, avg_mean_rank
Exemple #16
0
    def __init__(self, L1_flag, embedding_size, user_total, item_total,
                 entity_total, relation_total, isShare):
        super(coFM, self).__init__()
        self.L1_flag = L1_flag
        self.is_share = isShare
        self.embedding_size = embedding_size
        self.user_total = user_total
        self.item_total = item_total
        self.ent_total = entity_total
        self.rel_total = relation_total
        self.is_pretrained = False
        # fm
        user_weight = torch.FloatTensor(self.user_total, self.embedding_size)
        nn.init.xavier_uniform(user_weight)
        self.user_embeddings = nn.Embedding(self.user_total,
                                            self.embedding_size)
        self.user_embeddings.weight = nn.Parameter(user_weight)
        normalize_user_emb = F.normalize(self.user_embeddings.weight.data,
                                         p=2,
                                         dim=1)
        self.user_embeddings.weight.data = normalize_user_emb
        self.user_embeddings = to_gpu(self.user_embeddings)

        user_bias = torch.FloatTensor(self.user_total)
        item_bias = torch.FloatTensor(self.item_total)
        nn.init.constant(user_bias, 0)
        nn.init.constant(item_bias, 0)
        self.user_bias = nn.Embedding(self.user_total, 1)
        self.item_bias = nn.Embedding(self.item_total, 1)
        self.user_bias.weight = nn.Parameter(user_bias, 1)
        self.item_bias.weight = nn.Parameter(item_bias, 1)

        self.user_bias = to_gpu(self.user_bias)
        self.item_bias = to_gpu(self.item_bias)

        self.bias = nn.Parameter(to_gpu(torch.FloatTensor([0.0])))

        # trane

        rel_weight = torch.FloatTensor(self.rel_total, self.embedding_size)
        nn.init.xavier_uniform(rel_weight)
        self.rel_embeddings = nn.Embedding(self.rel_total, self.embedding_size)
        self.rel_embeddings.weight = nn.Parameter(rel_weight)
        normalize_rel_emb = F.normalize(self.rel_embeddings.weight.data,
                                        p=2,
                                        dim=1)
        self.rel_embeddings.weight.data = normalize_rel_emb
        self.rel_embeddings = to_gpu(self.rel_embeddings)

        # shared embedding
        ent_weight = torch.FloatTensor(self.ent_total, self.embedding_size)
        nn.init.xavier_uniform(ent_weight)
        self.ent_embeddings = nn.Embedding(self.ent_total, self.embedding_size)
        self.ent_embeddings.weight = nn.Parameter(ent_weight)
        normalize_ent_emb = F.normalize(self.ent_embeddings.weight.data,
                                        p=2,
                                        dim=1)
        self.ent_embeddings.weight.data = normalize_ent_emb
        self.ent_embeddings = to_gpu(self.ent_embeddings)

        if self.is_share:
            assert self.item_total == self.ent_total, "item numbers didn't match entities!"
            self.item_embeddings = self.ent_embeddings
        else:
            item_weight = torch.FloatTensor(self.item_total,
                                            self.embedding_size)
            nn.init.xavier_uniform(item_weight)
            self.item_embeddings = nn.Embedding(self.item_total,
                                                self.embedding_size)
            self.item_embeddings.weight = nn.Parameter(item_weight)
            normalize_item_emb = F.normalize(self.item_embeddings.weight.data,
                                             p=2,
                                             dim=1)
            self.item_embeddings.weight.data = normalize_item_emb
            self.item_embeddings = to_gpu(self.item_embeddings)
def case_rec_evaluateRec(FLAGS,
                         model,
                         eval_iter,
                         eval_dict,
                         all_dicts,
                         i_map,
                         logger,
                         i,
                         eval_descending=True,
                         is_report=False):
    # Evaluate
    total_batches = len(eval_iter)
    # processing bar
    pbar = tqdm(total=total_batches)
    pbar.set_description("Run Eval")

    all_i_var = None
    if FLAGS.share_embeddings:
        all_i_ids = [i_map[i] for i in range(len(i_map))]
        all_i_var = to_gpu(V(torch.LongTensor(all_i_ids)))

    model.eval()
    model.disable_grad()

    results = []
    for u_ids in eval_iter:
        u_var = to_gpu(V(torch.LongTensor(u_ids)))
        # batch * item
        scores = model.evaluateRec(u_var, all_i_ids=all_i_var)
        preds = zip(u_ids, scores.data.cpu().numpy())

        results.extend(
            evalRecProcess(list(preds),
                           eval_dict,
                           all_dicts=all_dicts,
                           descending=eval_descending,
                           num_processes=FLAGS.num_processes,
                           topn=FLAGS.topn,
                           queue_limit=FLAGS.max_queue))

        pbar.update(1)
    pbar.close()

    predictions = [result[5] for result in results
                   ]  # [(pred[0], top_ids, gold), ...], gold is test
    print("Saving predictions. Size: {}.".format(str(len(predictions))))

    predictions_output_filepath = os.path.join(
        FLAGS.log_path, FLAGS.experiment_name + '_pred.dat')
    print_list = []
    for triple in predictions:
        u_id = triple[0]
        top_ids = triple[1]
        #gold = triple[2]
        for i_id in top_ids:
            score = 1.0 / (top_ids.index(i_id) + 1)
            print_list.append((u_id, i_id, score))
    WriteFile(predictions_output_filepath, data=print_list, sep='\t').write()

    # Using CaseRecommender ReadFile class to read test_set from file
    dataset_path = os.path.join(FLAGS.data_path, FLAGS.dataset)
    eval_files = FLAGS.rec_test_files.split(':')
    test_path = os.path.join(dataset_path, eval_files[i])
    eval_data = ReadFile(input_file=test_path).read()
    predictions_data = ReadFile(input_file=predictions_output_filepath).read()
    print("Reading predictions. Size: {}.".format(
        str(len(predictions_data['feedback']))))

    # Creating CaseRecommender evaluator with item-recommendation parameters
    evaluator = ItemRecommendationEvaluation(n_ranks=[10])
    item_rec_metrics = evaluator.evaluate(predictions_data['feedback'],
                                          eval_data)
    print("From CaseRecommender evaluator: {}.".format(str(item_rec_metrics)))
    logger.info("From CaseRecommender evaluator: {}.".format(
        str(item_rec_metrics)))

    # Creating kg-summ-rec evaluator with diversity parameters
    dataset_name = os.path.basename(
        os.path.dirname(os.path.dirname(FLAGS.log_path)))
    tags = dataset_name.split('_')
    if tags[0] == 'ml-sun':
        evaluator2 = DiversityEvaluation(n_ranks=[10])
        dataset_path = os.path.normpath(FLAGS.data_path + os.sep + os.pardir)
        #tags = dataset_name.split('-')
        #if len(tags) > 2:
        #    mode = dataset_name.split('-')[2]
        #    ratio = dataset_name.split('-')[4]
        #else:
        #    mode = 'sv'
        #    ratio = '100'
        dataset_path = os.path.normpath(FLAGS.data_path + os.sep + os.pardir +
                                        os.sep + os.pardir + os.sep + tags[0] +
                                        '_' + tags[1] + '_' + 'oKG')
        mode = 'sv'
        ratio = '100'
        i2genre_map = read_i2genre_map(dataset_path, mode, ratio)
        diversity_metrics = evaluator2.evaluate(predictions_data['feedback'],
                                                eval_data, i2genre_map)
        print("From kg-summ-rec diversity evaluator: {}.".format(
            str(diversity_metrics)))
        logger.info("From kg-summ-rec diversity evaluator: {}.".format(
            str(diversity_metrics)))

    model.enable_grad()
    return item_rec_metrics
def train_loop(FLAGS,
               model,
               trainer,
               train_dataset,
               eval_datasets,
               entity_total,
               relation_total,
               logger,
               vis=None,
               is_report=False):
    train_iter, train_total, train_list, train_head_dict, train_tail_dict = train_dataset

    all_head_dicts = None
    all_tail_dicts = None
    if FLAGS.filter_wrong_corrupted:
        all_head_dicts = [train_head_dict
                          ] + [tmp_data[4] for tmp_data in eval_datasets]
        all_tail_dicts = [train_tail_dict
                          ] + [tmp_data[5] for tmp_data in eval_datasets]

    # Train.
    logger.info("Training.")

    # New Training Loop
    pbar = None
    total_loss = 0.0
    model.enable_grad()
    for _ in range(trainer.step, FLAGS.training_steps):

        if FLAGS.early_stopping_steps_to_wait > 0 and (
                trainer.step -
                trainer.best_step) > FLAGS.early_stopping_steps_to_wait:
            logger.info('No improvement after ' +
                        str(FLAGS.early_stopping_steps_to_wait) +
                        ' steps. Stopping training.')
            if pbar is not None: pbar.close()
            break
        if trainer.step % FLAGS.eval_interval_steps == 0:
            if pbar is not None:
                pbar.close()
            total_loss /= FLAGS.eval_interval_steps
            logger.info("train loss:{:.4f}!".format(total_loss))

            performances = []
            for i, eval_data in enumerate(eval_datasets):
                eval_head_dicts = None
                eval_tail_dicts = None
                if FLAGS.filter_wrong_corrupted:
                    eval_head_dicts = [train_head_dict] + [
                        tmp_data[4]
                        for j, tmp_data in enumerate(eval_datasets) if j != i
                    ]
                    eval_tail_dicts = [train_tail_dict] + [
                        tmp_data[5]
                        for j, tmp_data in enumerate(eval_datasets) if j != i
                    ]

                performances.append(
                    evaluate(FLAGS,
                             model,
                             entity_total,
                             relation_total,
                             eval_data[0],
                             eval_data[1],
                             eval_data[4],
                             eval_data[5],
                             eval_head_dicts,
                             eval_tail_dicts,
                             logger,
                             eval_descending=False,
                             is_report=is_report))

            if trainer.step > 0:
                is_best = trainer.new_performance(performances[0],
                                                  performances)
                # visuliazation
                if vis is not None:
                    vis.plot_many_stack({'KG Train Loss': total_loss},
                                        win_name="Loss Curve")
                    hit_vis_dict = {}
                    meanrank_vis_dict = {}
                    for i, performance in enumerate(performances):
                        hit_vis_dict['KG Eval {} Hit'.format(
                            i)] = performance[0]
                        meanrank_vis_dict['KG Eval {} MeanRank'.format(
                            i)] = performance[1]

                    if is_best:
                        log_str = [
                            "Best performances in {} step!".format(
                                trainer.best_step)
                        ]
                        log_str += [
                            "{} : {}.".format(s, "%.5f" % hit_vis_dict[s])
                            for s in hit_vis_dict
                        ]
                        log_str += [
                            "{} : {}.".format(s, "%.5f" % meanrank_vis_dict[s])
                            for s in meanrank_vis_dict
                        ]
                        vis.log("\n".join(log_str),
                                win_name="Best Performances")

                    vis.plot_many_stack(hit_vis_dict,
                                        win_name="KG Hit Ratio@{}".format(
                                            FLAGS.topn))

                    vis.plot_many_stack(meanrank_vis_dict,
                                        win_name="KG MeanRank")
            # set model in training mode
            pbar = tqdm(total=FLAGS.eval_interval_steps)
            pbar.set_description("Training")
            total_loss = 0.0
            model.train()
            model.enable_grad()

        triple_batch = next(train_iter)
        ph, pt, pr, nh, nt, nr = getTrainTripleBatch(
            triple_batch,
            entity_total,
            all_head_dicts=all_head_dicts,
            all_tail_dicts=all_tail_dicts)

        ph_var = to_gpu(V(torch.LongTensor(ph)))
        pt_var = to_gpu(V(torch.LongTensor(pt)))
        pr_var = to_gpu(V(torch.LongTensor(pr)))
        nh_var = to_gpu(V(torch.LongTensor(nh)))
        nt_var = to_gpu(V(torch.LongTensor(nt)))
        nr_var = to_gpu(V(torch.LongTensor(nr)))

        trainer.optimizer_zero_grad()

        # Run model. output: batch_size * 1
        pos_score = model(ph_var, pt_var, pr_var)
        neg_score = model(nh_var, nt_var, nr_var)

        # Calculate loss.
        # losses = nn.MarginRankingLoss(margin=FLAGS.margin).forward(pos_score, neg_score, to_gpu(torch.autograd.Variable(torch.FloatTensor([trainer.model_target]*len(ph)))))

        losses = loss.marginLoss()(pos_score, neg_score, FLAGS.margin)

        ent_embeddings = model.ent_embeddings(
            torch.cat([ph_var, pt_var, nh_var, nt_var]))
        rel_embeddings = model.rel_embeddings(torch.cat([pr_var, nr_var]))

        if FLAGS.model_type == "transh":
            norm_embeddings = model.norm_embeddings(torch.cat([pr_var,
                                                               nr_var]))
            losses += loss.orthogonalLoss(rel_embeddings, norm_embeddings)

        losses = losses + loss.normLoss(ent_embeddings) + loss.normLoss(
            rel_embeddings)

        # Backward pass.
        losses.backward()

        # for param in model.parameters():
        #     print(param.grad.data.sum())

        # Hard Gradient Clipping
        nn.utils.clip_grad_norm(
            [param for name, param in model.named_parameters()],
            FLAGS.clipping_max_value)

        # Gradient descent step.
        trainer.optimizer_step()
        total_loss += losses.data[0]
        pbar.update(1)
def normLoss(embeddings, dim=1):
    norm = torch.sum(embeddings ** 2, dim=dim, keepdim=True)
    return torch.sum(torch.max(norm - to_gpu(autograd.Variable(torch.FloatTensor([1.0]))), to_gpu(autograd.Variable(torch.FloatTensor([0.0])))))
 def forward(self, pos, neg, margin):
     zero_tensor = to_gpu(torch.FloatTensor(pos.size()))
     zero_tensor.zero_()
     zero_tensor = autograd.Variable(zero_tensor)
     return torch.sum(torch.max(pos - neg + margin, zero_tensor))
Exemple #21
0
def train_loop(FLAGS,
               model,
               trainer,
               train_dataset,
               eval_datasets,
               user_total,
               item_total,
               logger,
               vis=None,
               is_report=False):
    train_iter, train_total, train_list, train_dict = train_dataset

    all_dicts = None
    if FLAGS.filter_wrong_corrupted:
        all_dicts = [train_dict] + [tmp_data[3] for tmp_data in eval_datasets]

    # Train.
    logger.info("Training.")

    # New Training Loop
    pbar = None
    total_loss = 0.0
    model.train()
    model.enable_grad()
    for _ in range(trainer.step, FLAGS.training_steps):

        # if FLAGS.early_stopping_steps_to_wait > 0 and (trainer.step - trainer.best_step) > FLAGS.early_stopping_steps_to_wait:
        #     logger.info('No improvement after ' +
        #                str(FLAGS.early_stopping_steps_to_wait) +
        #                ' steps. Stopping training.')
        #     if pbar is not None: pbar.close()
        #     break
        if trainer.step % FLAGS.eval_interval_steps == 0:
            if pbar is not None:
                pbar.close()
            total_loss /= FLAGS.eval_interval_steps
            logger.info("train loss:{:.4f}!".format(total_loss))

            # performances = []
            # for i, eval_data in enumerate(eval_datasets):
            #     all_eval_dicts = None
            #     if FLAGS.filter_wrong_corrupted:
            #         all_eval_dicts = [train_dict] + [tmp_data[3] for j, tmp_data in enumerate(eval_datasets) if j!=i]

            #     performances.append( evaluate(FLAGS, model, eval_data[0], eval_data[3], all_eval_dicts, logger, eval_descending=True if trainer.model_target == 1 else False, is_report=is_report))

            # if trainer.step > 0 and len(performances) > 0:
            #     is_best = trainer.new_performance(performances[0], performances)

            # # visuliazation
            # if vis is not None:
            #     vis.plot_many_stack({'Rec Train Loss': total_loss},
            #     win_name="Loss Curve")
            #     f1_vis_dict = {}
            #     p_vis_dict = {}
            #     r_vis_dict = {}
            #     hit_vis_dict = {}
            #     ndcg_vis_dict = {}
            #     for i, performance in enumerate(performances):
            #         f1_vis_dict['Rec Eval {} F1'.format(i)] = performance[0]
            #         p_vis_dict['Rec Eval {} Precision'.format(i)] = performance[1]
            #         r_vis_dict['Rec Eval {} Recall'.format(i)] = performance[2]
            #         hit_vis_dict['Rec Eval {} Hit'.format(i)] = performance[3]
            #         ndcg_vis_dict['Rec Eval {} NDCG'.format(i)] = performance[4]

            #     if is_best:
            #         log_str = ["Best performances in {} step!".format(trainer.best_step)]
            #         log_str += ["{} : {}.".format(s, "%.5f" % f1_vis_dict[s]) for s in f1_vis_dict]
            #         log_str += ["{} : {}.".format(s, "%.5f" % p_vis_dict[s]) for s in p_vis_dict]
            #         log_str += ["{} : {}.".format(s, "%.5f" % r_vis_dict[s]) for s in r_vis_dict]
            #         log_str += ["{} : {}.".format(s, "%.5f" % hit_vis_dict[s]) for s in hit_vis_dict]
            #         log_str += ["{} : {}.".format(s, "%.5f" % ndcg_vis_dict[s]) for s in ndcg_vis_dict]

            #         vis.log("\n".join(log_str), win_name="Best Performances")

            #     vis.plot_many_stack(f1_vis_dict, win_name="Rec F1 Score@{}".format(FLAGS.topn))

            #     vis.plot_many_stack(p_vis_dict, win_name="Rec Precision@{}".format(FLAGS.topn))

            #     vis.plot_many_stack(r_vis_dict, win_name="Rec Recall@{}".format(FLAGS.topn))

            #     vis.plot_many_stack(hit_vis_dict, win_name="Rec Hit Ratio@{}".format(FLAGS.topn))

            #     vis.plot_many_stack(ndcg_vis_dict, win_name="Rec NDCG@{}".format(FLAGS.topn))

            # set model in training mode
            pbar = tqdm(total=FLAGS.eval_interval_steps)
            pbar.set_description("Training")
            total_loss = 0.0
            model.train()
            model.enable_grad()

        rating_batch = next(train_iter)
        u, pi, ni = getNegRatings(rating_batch,
                                  item_total,
                                  all_dicts=all_dicts)

        u_var = to_gpu(V(torch.LongTensor(u)))
        pi_var = to_gpu(V(torch.LongTensor(pi)))
        ni_var = to_gpu(V(torch.LongTensor(ni)))

        trainer.optimizer_zero_grad()

        # Run model. output: batch_size * cand_num
        pos_score = model(u_var, pi_var)
        neg_score = model(u_var, ni_var)

        # Calculate loss.
        losses = bprLoss(pos_score, neg_score, target=trainer.model_target)

        if FLAGS.model_type in ["transup", "transupb"]:
            user_embeddings = model.user_embeddings(u_var)
            item_embeddings = model.item_embeddings(torch.cat([pi_var,
                                                               ni_var]))
            losses += orthogonalLoss(
                model.pref_embeddings.weight,
                model.pref_norm_embeddings.weight) + normLoss(
                    user_embeddings) + normLoss(item_embeddings) + normLoss(
                        model.pref_embeddings.weight)

        # Backward pass.
        losses.backward()

        # for param in model.parameters():
        #     print(param.grad.data.sum())

        # Hard Gradient Clipping
        nn.utils.clip_grad_norm(
            [param for name, param in model.named_parameters()],
            FLAGS.clipping_max_value)

        # Gradient descent step.
        trainer.optimizer_step()
        total_loss += losses.item()
        pbar.update(1)
    def __init__(self, L1_flag, embedding_size, user_total, item_total,
                 entity_total, relation_total, i_map, new_map, isShare,
                 use_st_gumbel):
        super(jTransUPModel, self).__init__()
        self.L1_flag = L1_flag
        self.is_share = isShare
        self.use_st_gumbel = use_st_gumbel
        self.embedding_size = embedding_size
        self.user_total = user_total
        self.item_total = item_total
        # padding when item are not aligned with any entity
        self.ent_total = entity_total + 1
        self.rel_total = relation_total
        self.is_pretrained = False
        # store item to item-entity dic
        self.i_map = i_map
        # store item-entity to (entity, item)
        self.new_map = new_map
        # todo: simiplifying the init
        # transup
        user_weight = torch.FloatTensor(self.user_total, self.embedding_size)
        item_weight = torch.FloatTensor(self.item_total, self.embedding_size)
        pref_weight = torch.FloatTensor(self.rel_total, self.embedding_size)
        pref_norm_weight = torch.FloatTensor(self.rel_total,
                                             self.embedding_size)
        nn.init.xavier_uniform(user_weight)
        nn.init.xavier_uniform(item_weight)
        nn.init.xavier_uniform(pref_weight)
        nn.init.xavier_uniform(pref_norm_weight)
        # init user and item embeddings
        self.user_embeddings = nn.Embedding(self.user_total,
                                            self.embedding_size)
        self.item_embeddings = nn.Embedding(self.item_total,
                                            self.embedding_size)
        self.user_embeddings.weight = nn.Parameter(user_weight)
        self.item_embeddings.weight = nn.Parameter(item_weight)
        normalize_user_emb = F.normalize(self.user_embeddings.weight.data,
                                         p=2,
                                         dim=1)
        normalize_item_emb = F.normalize(self.item_embeddings.weight.data,
                                         p=2,
                                         dim=1)
        self.user_embeddings.weight.data = normalize_user_emb
        self.item_embeddings.weight.data = normalize_item_emb
        # init preference parameters
        self.pref_embeddings = nn.Embedding(self.rel_total,
                                            self.embedding_size)
        self.pref_norm_embeddings = nn.Embedding(self.rel_total,
                                                 self.embedding_size)
        self.pref_embeddings.weight = nn.Parameter(pref_weight)
        self.pref_norm_embeddings.weight = nn.Parameter(pref_norm_weight)
        normalize_pref_emb = F.normalize(self.pref_embeddings.weight.data,
                                         p=2,
                                         dim=1)
        normalize_pref_norm_emb = F.normalize(
            self.pref_norm_embeddings.weight.data, p=2, dim=1)
        self.pref_embeddings.weight.data = normalize_pref_emb
        self.pref_norm_embeddings.weight.data = normalize_pref_norm_emb

        self.user_embeddings = to_gpu(self.user_embeddings)
        self.item_embeddings = to_gpu(self.item_embeddings)
        self.pref_embeddings = to_gpu(self.pref_embeddings)
        self.pref_norm_embeddings = to_gpu(self.pref_norm_embeddings)

        # transh
        ent_weight = torch.FloatTensor(self.ent_total - 1, self.embedding_size)
        rel_weight = torch.FloatTensor(self.rel_total, self.embedding_size)
        norm_weight = torch.FloatTensor(self.rel_total, self.embedding_size)
        nn.init.xavier_uniform(ent_weight)
        nn.init.xavier_uniform(rel_weight)
        nn.init.xavier_uniform(norm_weight)
        norm_ent_weight = F.normalize(ent_weight, p=2, dim=1)
        # init user and item embeddings
        self.ent_embeddings = nn.Embedding(self.ent_total,
                                           self.embedding_size,
                                           padding_idx=self.ent_total - 1)
        self.rel_embeddings = nn.Embedding(self.rel_total, self.embedding_size)
        self.norm_embeddings = nn.Embedding(self.rel_total,
                                            self.embedding_size)

        self.ent_embeddings.weight = nn.Parameter(
            torch.cat([norm_ent_weight,
                       torch.zeros(1, self.embedding_size)],
                      dim=0))
        self.rel_embeddings.weight = nn.Parameter(rel_weight)
        self.norm_embeddings.weight = nn.Parameter(norm_weight)

        normalize_rel_emb = F.normalize(self.rel_embeddings.weight.data,
                                        p=2,
                                        dim=1)
        normalize_norm_emb = F.normalize(self.norm_embeddings.weight.data,
                                         p=2,
                                         dim=1)

        self.rel_embeddings.weight.data = normalize_rel_emb
        self.norm_embeddings.weight.data = normalize_norm_emb

        self.ent_embeddings = to_gpu(self.ent_embeddings)
        self.rel_embeddings = to_gpu(self.rel_embeddings)
        self.norm_embeddings = to_gpu(self.norm_embeddings)
    def __init__(self, L1_flag, embedding_size, user_total, item_total,
                 entity_total, relation_total, i_map, new_map):
        super(CKE, self).__init__()
        self.L1_flag = L1_flag
        self.embedding_size = embedding_size
        self.user_total = user_total
        self.item_total = item_total
        # padding when item are not aligned with any entity
        self.ent_total = entity_total + 1
        self.rel_total = relation_total
        self.is_pretrained = False
        # store item to item-entity dic
        self.i_map = i_map
        # store item-entity to (entity, item)
        self.new_map = new_map

        # bprmf
        # init user and item embeddings
        user_weight = torch.FloatTensor(self.user_total, self.embedding_size)
        item_weight = torch.FloatTensor(self.item_total, self.embedding_size)
        nn.init.xavier_uniform(user_weight)
        nn.init.xavier_uniform(item_weight)
        self.user_embeddings = nn.Embedding(self.user_total,
                                            self.embedding_size)
        self.item_embeddings = nn.Embedding(self.item_total,
                                            self.embedding_size)
        self.user_embeddings.weight = nn.Parameter(user_weight)
        self.item_embeddings.weight = nn.Parameter(item_weight)
        normalize_user_emb = F.normalize(self.user_embeddings.weight.data,
                                         p=2,
                                         dim=1)
        normalize_item_emb = F.normalize(self.item_embeddings.weight.data,
                                         p=2,
                                         dim=1)
        self.user_embeddings.weight.data = normalize_user_emb
        self.item_embeddings.weight.data = normalize_item_emb

        self.user_embeddings = to_gpu(self.user_embeddings)
        self.item_embeddings = to_gpu(self.item_embeddings)

        # transR

        ent_weight = torch.FloatTensor(self.ent_total - 1, self.embedding_size)
        rel_weight = torch.FloatTensor(self.rel_total, self.embedding_size)
        proj_weight = torch.FloatTensor(
            self.rel_total, self.embedding_size * self.embedding_size)
        nn.init.xavier_uniform(ent_weight)
        nn.init.xavier_uniform(rel_weight)

        norm_ent_weight = F.normalize(ent_weight, p=2, dim=1)

        if self.is_pretrained:
            nn.init.eye(proj_weight)
            proj_weight = proj_weight.view(-1).expand(self.relation_total, -1)
        else:
            nn.init.xavier_uniform(proj_weight)

        # init user and item embeddings
        self.ent_embeddings = nn.Embedding(self.ent_total,
                                           self.embedding_size,
                                           padding_idx=self.ent_total - 1)

        self.rel_embeddings = nn.Embedding(self.rel_total, self.embedding_size)
        self.proj_embeddings = nn.Embedding(
            self.rel_total, self.embedding_size * self.embedding_size)

        self.ent_embeddings.weight = nn.Parameter(
            torch.cat([norm_ent_weight,
                       torch.zeros(1, self.embedding_size)],
                      dim=0))
        self.rel_embeddings.weight = nn.Parameter(rel_weight)
        self.proj_embeddings.weight = nn.Parameter(proj_weight)

        # normalize_ent_emb = F.normalize(self.ent_embeddings.weight.data, p=2, dim=1)
        normalize_rel_emb = F.normalize(self.rel_embeddings.weight.data,
                                        p=2,
                                        dim=1)
        # normalize_proj_emb = F.normalize(self.proj_embeddings.weight.data, p=2, dim=1)

        # self.ent_embeddings.weight.data = normalize_ent_emb
        self.rel_embeddings.weight.data = normalize_rel_emb
        # self.proj_embeddings.weight.data = normalize_proj_emb

        self.ent_embeddings = to_gpu(self.ent_embeddings)
        self.rel_embeddings = to_gpu(self.rel_embeddings)
        self.proj_embeddings = to_gpu(self.proj_embeddings)