@@ -52,6 +52,20 @@ class EmbeddingLearner(nn.Module): | |||
n_score = score[:, pos_num:] | |||
return p_score, n_score | |||
def bpr_loss(p_scores, n_values): | |||
p1 = p_scores[:,0,None] | |||
p2 = p_scores[:,1,None] | |||
num_neg = n_values.shape[1] | |||
half_index = int(num_neg/2) | |||
d1 = torch.sub(p1,n_values[:,0:half_index]) | |||
d2 = torch.sub(p2,n_values[:,half_index:]) | |||
t = F.logsigmoid(torch.add(d1,d2)) | |||
loss = (-1) * t.sum() / n_values.shape[1] | |||
return loss | |||
class MetaTL(nn.Module): | |||
def __init__(self, itemnum, parameter): | |||
@@ -68,6 +82,7 @@ class MetaTL(nn.Module): | |||
self.embedding_learner = EmbeddingLearner() | |||
self.loss_func = nn.MarginRankingLoss(self.margin) | |||
self.rel_q_sharing = dict() | |||
def split_concat(self, positive, negative): | |||
@@ -101,15 +116,15 @@ class MetaTL(nn.Module): | |||
y = torch.Tensor([1]).to(self.device) | |||
self.zero_grad() | |||
sorted,indecies = torch.sort(n_score, descending=True,dim=1) | |||
n_values = sorted[:,0:p_score.shape[1]] | |||
loss = self.loss_func(p_score, n_values, y) | |||
# sorted,indecies = torch.sort(n_score, descending=True,dim=1) | |||
# n_values = sorted[:,0:p_score.shape[1]] | |||
n_values = n_score | |||
loss = bpr_loss(p_score,n_values) | |||
# loss = self.loss_func(p_score, n_values, y) | |||
loss.backward(retain_graph=True) | |||
grad_meta = rel.grad | |||
rel_q = rel - self.beta*grad_meta | |||
self.rel_q_sharing[curr_rel] = rel_q | |||
rel_q = rel_q.expand(-1, num_q + num_n, -1, -1) |
@@ -31,7 +31,7 @@ def sample_function_mixed(user_train, usernum, itemnum, batch_size, maxlen, resu | |||
seq = np.zeros([maxlen], dtype=np.int32) | |||
pos = np.zeros([maxlen], dtype=np.int32) | |||
neg = np.zeros([maxlen*30], dtype=np.int32) | |||
neg = np.zeros([maxlen*5], dtype=np.int32) | |||
if len(user_train[user]) < maxlen: | |||
nxt_idx = len(user_train[user]) - 1 | |||
@@ -62,7 +62,7 @@ def sample_function_mixed(user_train, usernum, itemnum, batch_size, maxlen, resu | |||
# for idx in range(maxlen*30 - 1): | |||
# support_negative_triples.append([seq[-1], curr_rel, neg[idx]]) | |||
for j in range(30): | |||
for j in range(5): | |||
for idx in range(maxlen-1): | |||
support_negative_triples.append([seq[idx], curr_rel, neg[j*maxlen + idx]]) | |||
@@ -119,7 +119,7 @@ class DataLoader(object): | |||
seq = np.zeros([self.maxlen], dtype=np.int32) | |||
pos = np.zeros([self.maxlen - 1], dtype=np.int32) | |||
# neg = np.zeros([self.maxlen*30 - 1], dtype=np.int32) | |||
neg = np.zeros([self.maxlen * 30], dtype=np.int32) | |||
neg = np.zeros([self.maxlen * 5], dtype=np.int32) | |||
idx = self.maxlen - 1 | |||
@@ -144,7 +144,7 @@ class DataLoader(object): | |||
# for idx in range(len(neg)): | |||
# support_negative_triples.append([seq[-1],curr_rel,neg[idx]]) | |||
for j in range(30): | |||
for j in range(5): | |||
for idx in range(self.maxlen-1): | |||
support_negative_triples.append([seq[idx], curr_rel, neg[j * self.maxlen + idx]]) | |||