Ejemplo n.º 1
0
    def forward_deprecated(self, review_word_emb, review_word_mask,
                           prod_rword_idxs_pvc, rand_prod_rword_idxs, n_negs):
        ''' rand_prod_rword_idxs: batch_size, review_count, pv_window_size * pvc_word_count
            prod_rword_idxs_pvc: batch_size, review_count, review_word_limit
            review_word_mask: indicate which target is valid
        '''
        batch_size, pv_window_size, embedding_size = review_word_emb.size()
        _, _, word_count = prod_rword_idxs_pvc.size()
        pvc_word_count = word_count / pv_window_size

        rand_word_emb = self.word_embeddings(
            rand_prod_rword_idxs.view(-1, pvc_word_count))
        corr_review_vector = get_vector_mean(
            rand_word_emb, rand_prod_rword_idxs.ne(self.word_pad_idx))
        corr_review_vector = corr_review_vector.view(-1, embedding_size, 1)

        #for each target word, there is k words negative sampling
        vocab_size = word_embeddings.weight.size() - 1
        #compute the loss of review generating positive and negative words
        neg_sample_idxs = torch.multinomial(self.word_dists,
                                            batch_size * pv_window_size *
                                            n_negs,
                                            replacement=True)
        neg_sample_emb = self.word_embeddings(neg_sample_idxs)
        #cuda.longtensor
        #negative sampling according to x^0.75
        #each word has n_neg corresponding samples
        target_emb = review_word_emb.view(batch_size * pv_window_size,
                                          embedding_size).unsqueeze(1)
        oloss = torch.bmm(target_emb,
                          corr_review_vector).squeeze(-1).squeeze(-1).view(
                              batch_size, -1)
        nloss = torch.bmm(
            neg_sample_emb.unsqueeze(1).neg(),
            corr_review_vector).squeeze(-1).squeeze(-1)
        nloss = nloss.view(batch_size, pv_window_size, -1)
        oloss = oloss.sigmoid().log()  #batch_size, pv_window_size
        nloss = nloss.sigmoid().log().sum(
            2)  # batch_size, pv_window_size#(n_negs->1)
        loss = -(nloss + oloss)  #* review_word_mask.float()
        loss = get_vector_mean(loss.unsqueeze(-1), review_word_mask)
        #(batch_size, )
        #loss = get_vector_mean(loss.unsqueeze(-1), review_ids.ne(self.review_pad_idx))
        #loss = loss.mean()
        _, rcount, review_word_limit = prod_rword_idxs_pvc.size()
        pvc_word_emb = self.word_embeddings(
            prod_rword_idxs_pvc.view(-1, review_word_limit))
        review_emb = get_vector_mean(pvc_word_emb,
                                     prod_rword_idxs_pvc.ne(self.word_pad_idx))

        return review_emb.view(-1, rcount, embedding_size), loss
Ejemplo n.º 2
0
 def get_para_vector(self, prod_rword_idxs_pvc):
     pvc_word_emb = self.context_embeddings(prod_rword_idxs_pvc)
     if self.corrupt_rate > 0.:
         self.apply_token_dropout(pvc_word_emb, self.corrupt_rate)
     review_emb = get_vector_mean(pvc_word_emb,
                                  prod_rword_idxs_pvc.ne(self.word_pad_idx))
     return review_emb
Ejemplo n.º 3
0
    def forward(self, review_word_emb, review_word_mask, prod_rword_idxs_pvc,
                n_negs):
        '''
            prod_rword_idxs_pvc: batch_size (real_batch_size * review_count), review_word_limit
            review_word_emb: batch_size * reivew_count, embedding_size
            review_word_mask: indicate which target is valid
        '''
        batch_size, pv_window_size, embedding_size = review_word_emb.size()
        pvc_word_emb = self.context_embeddings(prod_rword_idxs_pvc)
        review_emb = get_vector_mean(pvc_word_emb,
                                     prod_rword_idxs_pvc.ne(self.word_pad_idx))
        self.apply_token_dropout(pvc_word_emb, self.corrupt_rate)
        corr_review_emb = get_vector_mean(
            pvc_word_emb, prod_rword_idxs_pvc.ne(self.word_pad_idx))

        #for each target word, there is k words negative sampling
        #compute the loss of review generating positive and negative words
        neg_sample_idxs = torch.multinomial(self.word_dists,
                                            batch_size * pv_window_size *
                                            n_negs,
                                            replacement=True)
        neg_sample_emb = self.word_embeddings(
            neg_sample_idxs.view(batch_size, -1))
        output_pos = torch.bmm(
            review_word_emb,
            corr_review_emb.unsqueeze(2))  # batch_size, pv_window_size, 1
        output_neg = torch.bmm(neg_sample_emb,
                               corr_review_emb.unsqueeze(2)).view(
                                   batch_size, pv_window_size, -1)
        scores = torch.cat((output_pos, output_neg),
                           dim=-1)  #batch_size, pv_window_size, 1+n_negs
        target = torch.cat(
            (torch.ones(output_pos.size(), device=scores.device),
             torch.zeros(output_neg.size(), device=scores.device)),
            dim=-1)
        loss = self.bce_logits_loss(scores, target).sum(
            -1)  #batch_size, pv_window_size
        loss = get_vector_mean(loss.unsqueeze(-1), review_word_mask)

        #cuda.longtensor
        #negative sampling according to x^0.75
        return review_emb, loss
Ejemplo n.º 4
0
 def forward(self, review_ids, review_word_emb, review_word_mask, n_negs):
     batch_size, pv_window_size, embedding_size = review_word_emb.size()
     #for each target word, there is k words negative sampling
     review_emb = self.review_embeddings(review_ids)
     review_emb = self.drop_layer(review_emb)
     #vocab_size = self.word_embeddings.weight.size() - 1
     #compute the loss of review generating positive and negative words
     neg_sample_idxs = torch.multinomial(self.word_dists,
                                         batch_size * pv_window_size *
                                         n_negs,
                                         replacement=True)
     neg_sample_emb = self.word_embeddings(
         neg_sample_idxs.view(batch_size, -1))
     output_pos = torch.bmm(
         review_word_emb,
         review_emb.unsqueeze(2))  # batch_size, pv_window_size, 1
     output_neg = torch.bmm(neg_sample_emb, review_emb.unsqueeze(2)).view(
         batch_size, pv_window_size, -1)
     scores = torch.cat((output_pos, output_neg),
                        dim=-1)  #batch_size, pv_window_size, 1+n_negs
     target = torch.cat(
         (torch.ones(output_pos.size(), device=scores.device),
          torch.zeros(output_neg.size(), device=scores.device)),
         dim=-1)
     loss = self.bce_logits_loss(scores, target).sum(
         -1)  #batch_size, pv_window_size
     loss = get_vector_mean(loss.unsqueeze(-1), review_word_mask)
     #cuda.longtensor
     #negative sampling according to x^0.75
     #each word has n_neg corresponding samples
     '''
     oloss = torch.bmm(review_word_emb, review_emb.unsqueeze(2)).squeeze(-1)
     nloss = torch.bmm(neg_sample_emb.neg(), review_emb.unsqueeze(2)).squeeze(-1)
     nloss = nloss.view(batch_size, pv_window_size, -1)
     oloss = oloss.sigmoid().log() #batch_size, pv_window_size
     nloss = nloss.sigmoid().log().sum(2)# batch_size, pv_window_size#(n_negs->1)
     loss = -(nloss + oloss) # * review_word_mask.float()
     loss = get_vector_mean(loss.unsqueeze(-1), review_word_mask)
     #(batch_size, )
     #loss = loss.sum() / review_ids.ne(self.review_pad_idx).float().sum()
     '''
     return review_emb, loss
Ejemplo n.º 5
0
    def item_to_words(self, target_prod_idxs, target_word_idxs, n_negs):
        batch_size, pv_window_size = target_word_idxs.size()
        prod_emb = self.product_emb(target_prod_idxs)
        target_word_emb = self.word_embeddings(target_word_idxs)

        #for each target word, there is k words negative sampling
        #vocab_size = self.word_embeddings.weight.size() - 1
        #compute the loss of review generating positive and negative words
        neg_sample_idxs = torch.multinomial(self.word_dists,
                                            batch_size * pv_window_size *
                                            n_negs,
                                            replacement=True)
        neg_sample_emb = self.word_embeddings(
            neg_sample_idxs.view(batch_size, -1))
        output_pos = torch.bmm(
            target_word_emb,
            prod_emb.unsqueeze(2))  # batch_size, pv_window_size, 1
        output_neg = torch.bmm(neg_sample_emb, prod_emb.unsqueeze(2)).view(
            batch_size, pv_window_size, -1)
        pos_bias = self.word_bias[target_word_idxs.view(-1)].view(
            batch_size, pv_window_size, 1)
        neg_bias = self.word_bias[neg_sample_idxs].view(
            batch_size, pv_window_size, -1)
        output_pos += pos_bias
        output_neg += neg_bias

        scores = torch.cat((output_pos, output_neg),
                           dim=-1)  #batch_size, pv_window_size, 1+n_negs
        target = torch.cat(
            (torch.ones(output_pos.size(), device=scores.device),
             torch.zeros(output_neg.size(), device=scores.device)),
            dim=-1)
        loss = self.bce_logits_loss(scores, target).sum(
            -1)  #batch_size, pv_window_size
        loss = get_vector_mean(loss.unsqueeze(-1),
                               target_word_idxs.ne(self.word_pad_idx))
        loss = loss.mean()
        return loss