def forward(self, word_pos, context_positions, negative_sample=False): embed_word = self.word_embedding(word_pos) # 1 * emb_size embed_context = self.context_embedding(context_positions) # n * emb_size score = torch.matmul(embed_context, embed_word.transpose(dim0=1, dim1=0)) #score = n * 1 # following is an example of something you can only do in a framework that allows # dynamic graph creation if negative_sample: score = -1*score obj = -1 * torch.sum(F.logsigmoid(score)) return obj
def pairwise_loss(u_batch, i_batch_p, i_batch_n, hid_d): u_batch = u_batch.view(len(u_batch), 1, hid_d) i_batch_p = i_batch_p.view(len(i_batch_p), hid_d, 1) i_batch_n = i_batch_n.view(len(i_batch_n), hid_d, 1) out_p = torch.bmm(u_batch, i_batch_p) out_n = -torch.bmm(u_batch, i_batch_n) # sum_p = F.logsigmoid(out_p) # sum_n = F.logsigmoid(out_n) # loss_sum = - (sum_p + sum_n) loss_sum = -F.logsigmoid(out_p + out_n) loss_sum = loss_sum.sum() / len(loss_sum) return loss_sum
def step(self, x, n, cumul=None, total_computes=None): """ n is the index of the upcoming block, Given the current activation decide whether to go in or skip/exit. returns the binary decision and the log-(p, 1-p) """ T, B, C = x.size() if self.detach_before_classifier: x = x.detach() x = self.halting_predictors[n if self. separate_halting_predictors else 0](x) halt_logits = F.logsigmoid(x) # the log-p of halting # Apply the gumbel trick halt = halt_logits.view(-1, 2) halt = F.gumbel_softmax(halt, tau=self.gumbel_tau).view(T, B, 2) return halt
def forward(self, input, target): p = torch.sigmoid(input) loss = - (target * ((1 - p) ** self.gamma) * F.logsigmoid(input)) - ((1 - target) * (p ** self.gamma) * F.logsigmoid(-input)) if self.weight is not None: loss = torch.mul(loss, self.weight) loss = torch.mean(loss, dim=-1) if self.reduction == "mean": loss = loss.mean(dim=0) elif self.reduction == "sum": loss = loss.sum(dim=0) return loss
def forward(self, input, target): # Inspired by the implementation of binary_cross_entropy_with_logits if not (target.size() == input.size()): raise ValueError( "Target size ({}) must be the same as input size ({})".format( target.size(), input.size())) max_val = (-input).clamp(min=0) loss = input - input * target + max_val + ( (-max_val).exp() + (-input - max_val).exp()).log() # This formula gives us the log sigmoid of 1-p if y is 0 and of p if y is 1 invprobs = F.logsigmoid(-input * (target * 2 - 1)) loss = (invprobs * self.gamma).exp() * loss return loss.mean()
def _inputs_as_onehot( y_pred: Tensor, y_true: Tensor, mode: str = "auto", from_logits: bool = False, discretize: bool = False, ) -> Tuple[Tensor, Tensor]: assert mode in MODES batch_size, num_classes = y_pred.shape[:2] if mode == AUTO_MODE: if y_pred.shape == y_true.shape: mode = BINARY_MODE if num_classes == 1 else ONEHOT_MODE else: mode = MULTI_MODE if from_logits: # Apply activations to get [0..1] class probabilities # Using Log-Exp as this gives more numerically stable result and does not cause vanishing gradient on # extreme values 0 and 1 if mode == BINARY_MODE: y_pred = F.logsigmoid(y_pred.float()).exp() elif mode in (MULTI_MODE, ONEHOT_MODE): y_pred = F.log_softmax(y_pred.float(), dim=1).exp() if discretize: if mode == BINARY_MODE: y_pred = torch.round(y_pred).clamp_min(0.0).clamp_max(1.0) else: y_pred = hard_max(y_pred) if mode == BINARY_MODE: y_true = y_true.view(batch_size, 1, -1) y_pred = y_pred.view(batch_size, 1, -1) elif mode == ONEHOT_MODE: y_true = y_true.view(batch_size, num_classes, -1) y_pred = y_pred.view(batch_size, num_classes, -1) elif mode == MULTI_MODE: y_pred = y_pred.view(batch_size, num_classes, -1) y_true = y_true.view(batch_size, -1) y_true = F.one_hot(y_true, num_classes).permute(0, 2, 1) assert y_pred.shape == y_true.shape return y_pred.float(), y_true.float()
def forward(self, x, log_s_k): x = torch.cat([x, log_s_k], dim=1) x = self.conv1(x) x = self.bn1(x) x = self.relu(x) x = self.maxpool(x) x = self.res1(x) x = self.res2(x) x = self.res3(x) x = self.res1_upsample(x) x = self.res2_upsample(x) x = self.res3_upsample(x) x = self.res4_upsample(x) x = self.res5_upsample(x) x = self.output(x) x = F.logsigmoid(x) # Old code # Downsampling blocks # x, skip1 = self.downblock1(torch.cat((x, log_s_k), dim=1)) # x, skip2 = self.downblock2(x) # x, skip3 = self.downblock3(x) # x, skip4 = self.downblock4(x) # x, skip5 = self.downblock5(x) # x, skip6 = self.downblock6(x) # x, skip7 = self.downblock7(x) # # The input to the MLP is the last skip tensor collected from the downsampling path (after flattening) # # _, skip6 = self.downblock6(x) # # Flatten # x = skip7.flatten(start_dim=1) # x = self.mlp(x) # # Reshape to match shape of last skip tensor # x = x.view(skip7.shape) # # Upsampling blocks # # x = self.upblock1(x, skip6) # x = self.upblock2(x, skip7) # x = self.upblock3(x, skip6) # x = self.upblock4(x, skip5) # x = self.upblock5(x, skip4) # x = self.upblock6(x, skip3) # x = self.upblock7(x, skip2) # x = self.upblock8(x, skip1) # Output layer # x = self.output(x) # x = F.logsigmoid(x) return x
def cbow(self, center, contexts, negatives): # center_emb: (batchsize, dim) # context_emb: (batchsize, context_len, dim) # negative_emb: (batchsize, negative, dim) center_emb = self.center_embed(center) context_emb = self.context_embed(contexts) negative_emb = self.center_embed(negatives) # context_vec: (batchsize, dim) context_vec = torch.sum(context_emb, dim=1) print('*******************') print('cbow') print('*******************') print('center_emb') # print(center_emb) print(center_emb.shape) print('context_emb') # print(context_emb) print(context_emb.shape) print('negative_emb') # print(negative_emb) print(negative_emb.shape) # emb: (batchsize, negative + 1, dim) emb = torch.cat((center_emb.unsqueeze(1), -negative_emb), dim=1) print('emb') # print(context_emb) print(emb.shape) # score: (batchsize, negative + 1) score = torch.bmm(emb, context_vec.unsqueeze(2)).squeeze(2) print('score') print(score) print(score.shape) # score: (batchsize, negative + 1) loss = -torch.mean(F.logsigmoid(score)) print('loss') print(loss) print(loss.shape) return loss
def forward(self, inputs: torch.Tensor) -> torch.Tensor: ''' `model_output` (tensor) - column 0 must be the scores of positive pois, others must be the negative. ''' if inputs.shape[1] > 2: wstr = f'In BPRLoss, model_output/pred shape is {inputs.shape}, the second dim > 2' warnings.warn(wstr, RuntimeWarning) loss: torch.Tensor = -F.logsigmoid(inputs[:, 0:1] - inputs[:, 1:]) if self.reduction == 'mean': loss = torch.mean(loss) elif self.reduction == 'sum': loss = torch.sum(loss) elif self.reduction == 'none': pass else: raise ValueError("reduction must be 'none' | 'mean' | 'sum'") return loss
def forward(self, input, target): if not (target.size() == input.size()): raise ValueError( "Target size ({}) must be the same as input size ({})".format( target.size(), input.size())) max_val = (-input).clamp(min=0) loss = input - input * target + max_val + \ ((-max_val).exp() + (-input - max_val).exp()).log() invprobs = F.logsigmoid(-input * (target * 2.0 - 1.0)) loss = (invprobs * self.gamma).exp() * loss if self.average: return loss.mean() else: return loss.sum()
def asymmetric_focal_loss(self, output, target): # output = torch.sigmoid(output).clip(self.eps, 1. - self.eps) # calculate losses separately for each class, only suppressing background class back_ce = -(1 - target) * torch.pow( 1 - torch.sigmoid(output).clip(self.eps, 1. - self.eps), self.gamma ) * torch.log(1 - torch.sigmoid(output).clip(self.eps, 1. - self.eps)) fore_ce = -target * F.logsigmoid(output) # focal_factor = (1 - target).mul_(torch.pow(1 - torch.sigmoid(output).clip(self.eps, 1. - self.eps), self.gamma)) # loss = (output * focal_factor).add_((-output).exp() + 1).mul_() # loss = (-output).exp_().add_(1).log_().mul_(focal_factor + target).add_(x * focal_factor) # loss = (1 - target).mul_((1 - output).pow_(self.gamma)).mul_(torch.log(torch.sigmoid(output).mul_(-1).add_(1))).add_(target.mul_(F.logsigmoid(output))) return (1 - self.delta) * back_ce + self.delta * fore_ce
def forward(self, inputs, targets): inputs = inputs.contiguous().view(-1) targets = targets.contiguous().view(-1) max_val = (-inputs).clamp(min=0) loss = inputs * (1 - targets) + max_val + ( (-max_val).exp() + (-inputs - max_val).exp()).log() # This formula gives us the log sigmoid of 1-p if y is 0 and of p if y is 1 invprobs = F.logsigmoid(-inputs * (targets * 2 - 1)) focal_loss = self.alpha * (invprobs * self.gamma).exp() * loss # Online Hard Example Mining: top x% losses (pixel-wise). Refer to http://www.robots.ox.ac.uk/~tvg/publications/2017/0026.pdf OHEM, _ = focal_loss.topk(k=int(self.OHEM_percent * [*focal_loss.shape][0])) return OHEM.mean()
def bpr_loss(y_input, y_target, n_samp=4): # getting tensors, batch size from packed sequences score, batch_sizes = y_input target, _ = y_target batch_size = batch_sizes[0] loss_batch = torch.zeros((batch_size, 1), dtype=torch.float32) for i in range(batch_size): pos_score = torch.masked_select(score, target.byte()) for j in range(n_samp): samples = neg_sample(y_target) neg_score = torch.masked_select(score, samples[0]) loss_sample = - torch.sum(F.logsigmoid(pos_score - neg_score)) / n_samp loss_batch[i] += loss_sample return torch.sum(loss_batch) / batch_size.float()
def eval_cross_entropy_loss(model, loader, sigma=1.0): """ formula in https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/MSR-TR-2010-82.pdf C = 0.5 * (1 - S_ij) * sigma * (si - sj) + log(1 + exp(-sigma * (si - sj))) when S_ij = 1: C = log(1 + exp(-sigma(si - sj))) when S_ij = -1: C = log(1 + exp(-sigma(sj - si))) sigma can change the shape of the curve """ model.eval() with torch.no_grad(): total_cost = 0 # total_pairs = len(loader) pairs_in_compute = 0 for X, Y in loader: Y = Y.reshape(-1, 1) rel_diff = Y - Y.T pos_pairs = (rel_diff > 0).numpy().astype(np.float32) num_pos_pairs = np.sum(pos_pairs, (0, 1)) # skip negative sessions, no relevant info: if num_pos_pairs == 0: continue neg_pairs = (rel_diff < 0).numpy().astype(np.float32) num_pairs = ( 2 * num_pos_pairs ) # num pos pairs and neg pairs are always the same pos_pairs = torch.tensor(pos_pairs).cuda() neg_pairs = torch.tensor(neg_pairs).cuda() Sij = pos_pairs - neg_pairs # only calculate the different pairs diff_pairs = pos_pairs + neg_pairs pairs_in_compute += num_pairs X_tensor = X.squeeze().cuda() y_pred = model(X_tensor) y_pred_diff = y_pred - y_pred.t() # logsigmoid(x) = log(1 / (1 + exp(-x))) equivalent to log(1 + exp(-x)) C = 0.5 * (1 - Sij) * sigma * y_pred_diff - F.logsigmoid( -sigma * y_pred_diff ) C = C * diff_pairs cost = torch.sum(C, (0, 1)) total_cost += cost avg_cost = total_cost / pairs_in_compute return avg_cost
def forward(self, x): x = F.relu(self.conv1(x)) x = F.max_pool2d(x, 2) x = F.relu(self.conv2(x)) x = F.max_pool2d(x, 2) x = F.relu(self.conv3(x)) x = F.max_pool2d(x, 2) x = x.view(1, 28 * 28 * 64) x = F.relu(self.fc1(x)) #x = F.relu(self.fc2(x)) x = self.fc2(x) x = F.logsigmoid(x) return x
def weighted_focal_loss_with_logits(logits, labels, weights, gamma=2.): """ weighted binary focal loss with raw score (before sigmoid) logits: raw score, vector labels: corresponding labels, vector weights: corresponding weights, vector gamma: hyper parameters for focal loss, by default 2 """ log_probs = F.logsigmoid(logits) probs = F.sigmoid(logits) pos_logprobs = log_probs[labels == 1] neg_logprobs = torch.log(torch.clamp(1 - probs[labels == 0], 1e-6, 1)) pos_probs = probs[labels == 1] neg_probs = 1 - probs[labels == 0] pos_weights = weights[labels == 1] neg_weights = weights[labels == 0] pos_probs = pos_probs.detach() neg_probs = neg_probs.detach() pos_loss = - pos_logprobs * (1 - pos_probs) ** gamma neg_loss = - neg_logprobs * (1 - neg_probs) ** gamma loss = ((pos_loss * pos_weights).sum() + (neg_loss * neg_weights).sum()) / (weights.sum() + 1e-12) pos_correct = (probs[labels != 0] > 0.5).sum() pos_total = (labels != 0).sum() neg_correct = (probs[labels == 0] < 0.5).sum() neg_total = (labels == 0).sum() return loss, pos_correct, pos_total, neg_correct, neg_total log_probs[labels == 0] = torch.log(1 - probs[labels == 0]) probs[labels == 0] = 1 - probs[labels == 0] loss = - log_probs * (1 - probs) ** gamma loss = (weights * loss).sum()/(weights.sum()+1e-12) pos_correct = (probs[labels != 0] > 0.5).sum() pos_total = (labels != 0).sum() neg_correct = (probs[labels == 0] > 0.5).sum() neg_total = (labels == 0).sum() return loss, pos_correct, pos_total, neg_correct, neg_total
def _train(self, model, train_loader, val_loader=None): criterions = { 'autoencoder': nn.CrossEntropyLoss(), 'generator': lambda t: -torch.mean(F.logsigmoid(t)), 'discriminator': nn.BCEWithLogitsLoss() } optimizers = { 'autoencoder': torch.optim.Adam(list(model.encoder.parameters()) + list(model.decoder.parameters()), lr=self.config.lr), 'generator': torch.optim.Adam(model.encoder.parameters(), lr=self.config.lr), 'discriminator': torch.optim.Adam(model.discriminator.parameters(), lr=self.config.lr) } schedulers = { k: torch.optim.lr_scheduler.StepLR(v, self.config.step_size, self.config.gamma) for k, v in optimizers.items() } device = torch.device(self.config.device) log = Logger() for epoch in range(self.config.train_epochs): tqdm_data = tqdm(train_loader, desc='Training (epoch #{})'.format(epoch)) for scheduler in schedulers.values(): scheduler.step() log.append( self._train_epoch(model, tqdm_data, criterions, optimizers)) log.write(self.config.log_file) if val_loader is not None: tqdm_data = tqdm(val_loader, desc='Validation (epoch #{})'.format(epoch)) self._train_epoch(model, tqdm_data, criterions) if epoch % self.config.save_frequency == 0: model.to('cpu') torch.save( model.state_dict(), self.config.model_save[:-3] + '_{0:03d}.pt'.format(epoch)) model.to(device)
def binary_focal_loss_with_logits(x, y, alpha=0.25, gamma=2): '''Focal loss for binary case. Args: x: (tensor) predictions, sized [N,D]. y: (tensor) targets, sized [N,]. Return: (tensor) focal loss. ''' # return binary_focal_loss(x.sigmoid(), y, alpha, gamma) y = y.view(x.size()).float() # This formula gives us the log sigmoid of 1-p if y is 0 and of p if y is 1 pt = F.logsigmoid(-x * (y * 2 - 1)).exp() w = pt.pow(gamma) w = torch.where(y < 0, w * alpha, w * (1 - alpha)) loss = F.binary_cross_entropy_with_logits(x, y, w, reduction='none') return loss
def forward(self, x): x = F.relu( self.conv1(x)) # computes the activation of first convolution x = self.pool(x) # Maxpooling layer x = F.relu( self.conv2(x)) # computes the activation of second convolution x = self.pool(x) # Maxpooling layer x = F.relu( self.conv3(x)) # computes the activation of second convolution x = x.view( -1, 32 * 5 * 5) # reshape data to input to the input layer of the neural net x = F.relu(self.fc1( x)) # computes the activation of the first fully connected layer x = F.logsigmoid(self.fc2( x)) # computes the activation of the second fully connected layer x = self.fc3(x) # computes the third fully connected layer return x
def forward(self, input, target): if not (target.size() == input.size()): raise ValueError( "Target size ({}) must be the same as input size ({})".format( target.size(), input.size())) max_val = (-input).clamp(min=0) loss = input - input * target + max_val + ( (-max_val).exp() + (-input - max_val).exp()).log() invprobs = F.logsigmoid(-input * ((target > 0.5).float() * 2.0 - 1.0)) loss = (invprobs * self.gamma).exp() * loss if self.weight is None: loss = 1.0 / loss.shape[1] * loss else: loss = loss * self.normalized_weight.view(1, -1) return loss.sum(dim=1).mean()
def loss(self, prediction, target): if self.is_regression: y = target p = prediction eps = 1e-7 mask = (y != 0.).float().detach() mse = (y - p)**2 mse[mask == 0] = 0 loss = mse.sum() / (mask.sum() + eps) return loss else: labels = target / 2 + 0.5 mask = (labels != 0.5).float().detach() ce = -( labels * F.logsigmoid(prediction) + (1 - labels) * torch.log(1 - torch.sigmoid(prediction) + 1e-7)) loss = (ce * mask).sum() / (mask.sum() + 1e-7) return loss
def negative_sampling_line(z, edge_index, num_negative_samples = 5): ''' Parameters: z: the sampled community using gumbel softmax reparametrization trick edge_index: edges in the graph num_negative_samples: number of negative samples to be used for the optimization The function has been partially inspired from this file: https://github.com/DMPierre/LINE/blob/master/utils/line.py ''' ## Basically this will output a tuple of length 3 and the third index will contain the nodes from negative edges negsamples = structured_negative_sampling(edge_index) negsamples = negsamples[2] negativenodes = -self.nodes_embeddings(negsamples) mulpositivebatch = torch.mul(v_i, v_j) positivebatch = F.logsigmoid(torch.sum(mulpositivebatch, dim=1))
def negative_criterion_for_triplet_loss( anchor: torch.Tensor, positive: torch.Tensor) -> torch.Tensor: r""" .. math:: negative\ loss = - \log\Bigl(\sigma(-f(x^{ref}) ^\mathrm{T}f(x_k^{neg}))\Bigl) Args: anchor: :math:`f(x^{ref})` ... anchor representation positive: :math:`f(x^{neg})` ... negative representation Returns: negative loss (torch.Tensor) """ negative_loss = -torch.mean(F.logsigmoid(-torch.bmm(anchor, positive))) return negative_loss
def forward(self, focus, context): ''' focus : 중심단어의 아이디 context : 주변 단어의 아이디 (네거티브 샘플일수도 있음) ''' # 중심단어 임베딩하기 embed_focus = self.embeddings(focus).view((1, -1)) # 주변단어 임베딩하기 embed_ctx = self.embeddings(context).view((1, -1)) # 두 단어간의 내적값이 score # 같을수록 1에 가까워지고 # 다를수록 0에 가까워짐 # 결과적으로 두 단어 임베딩간의 유사도를 예측함 score = torch.mm(embed_focus, torch.t(embed_ctx)) log_probs = F.logsigmoid(score) return log_probs
def loss_per_level(self, estConf, gtDisp): N, C, H, W = estConf.shape scaled_gtDisp = gtDisp scale = 1.0 if gtDisp.shape[-2] != H or gtDisp.shape[-1] != W: # compute scale per level and scale gtDisp scale = gtDisp.shape[-1] / (W * 1.0) scaled_gtDisp = gtDisp / scale scaled_gtDisp = self.scale_func(scaled_gtDisp, (H, W)) # mask for valid disparity # gt zero and lt max disparity mask = (scaled_gtDisp > 0) & (scaled_gtDisp < (self.max_disp / scale)) mask = mask.detach_().type_as(gtDisp) # NLL loss loss = (-1.0 * F.logsigmoid(estConf) * mask).mean() return loss
def bpr_loss(users, pos_items, neg_items, decay=1): pos_scores = torch.mul(users, pos_items).sum(1) neg_scores = torch.mul(users, neg_items).sum(1) regularizer = torch.sum(users**2) / 2 + torch.sum( pos_items**2) / 2 + torch.sum(neg_items**2) / 2 regularizer = regularizer / 1e6 # In the first version, we implement the bpr loss via the following codes: # We report the performance in our paper using this implementation. maxi = F.logsigmoid(pos_scores - neg_scores) mf_loss = -torch.mean(maxi) ## In the second version, we implement the bpr loss via the following codes to avoid 'NAN' loss during training: ## However, it will change the training performance and training performance. ## Please retrain the model and do a grid search for the best experimental setting. # mf_loss = tf.reduce_sum(tf.nn.softplus(-(pos_scores - neg_scores))) decay = 0.1 emb_loss = decay * regularizer return mf_loss, emb_loss
def forward(self, y_pred, y_true): # Inspired by the implementation of binary_cross_entropy_with_logits y_pred = y_pred[:, 1].contiguous().view(-1) y_true = y_true.contiguous().view(-1) if not (y_true.size() == y_pred.size()): raise ValueError( "Target size ({}) must be the same as y_pred size ({})".format( y_true.size(), y_pred.size())) max_val = (-y_pred).clamp(min=0) loss = y_pred - y_pred * y_true + max_val + ( (-max_val).exp() + (-y_pred - max_val).exp()).log() # This formula gives us the log sigmoid of 1-p if y is 0 and of p if y is 1 invprobs = F.logsigmoid(-y_pred * (y_true * 2 - 1)) loss = (invprobs * self.gamma).exp() * loss return loss.mean()
def focal_loss(pred: np.ndarray, target: np.ndarray) -> float: gamma = 2 # Inspired by the implementation of binary_cross_entropy_with_logits if target.size() != pred.size(): raise ValueError( f'target size {target.size} must be the as input size {pred.size()}' ) max_val = (-pred).clamp(min=0) loss = pred - pred * target + max_val + ((-max_val).exp() + (-pred - max_val).exp()).log() # This formula gives us the log sigmoid of 1-p if y is 0 and of p if y is 1 invprobs = F.logsigmoid(-pred * (target * 2 - 1)) loss = (invprobs * gamma).exp() * loss return loss.mean()
def forward(self, x): x_u = torch.index_select(self.user_embeddings, 0, x[0]) x_i = torch.index_select(self.item_embeddings, 0, x[1]) x_j = torch.index_select(self.item_embeddings, 0, x[2]) #x_ui = torch.einsum("nf,nf->n", x_u, x_i) #x_uj = torch.einsum("nf,nf->n", x_u, x_j) #x_uij = x_ui - x_uj #loss = -F.logsigmoid(x_uij).sum() pos_scores = torch.sum(torch.mul(x_u, x_i), dim=1) neg_scores = torch.sum(torch.mul(x_u, x_j), dim=1) xuij = F.logsigmoid(pos_scores - neg_scores) loss = -(torch.sum(xuij)) return loss
def sg(self, center, contexts, negatives): # center_emb: (batchsize, dim) # context_emb: (batchsize, context_len, dim) # negative_emb: (batchsize, negative, dim) center_emb = self.center_embed(center) context_emb = self.context_embed(contexts) negative_emb = self.center_embed(negatives) # emb: (batchsize, negative + 1, dim) emb = torch.cat((center_emb.unsqueeze(1), -negative_emb), dim=1) # score: (batchsize, negatives + 1, context_len) score = torch.bmm(emb, context_emb.transpose(1, 2)) # score: (batchsize, negative + 1) loss = -torch.mean(F.logsigmoid(score)) return loss
def bpr_loss(self, users, pos_items, neg_items): # Calculate BPR loss pos_scores = torch.sum(torch.mul(users, pos_items), dim=1) neg_scores = torch.sum(torch.mul(users, neg_items), dim=1) regularizer = ( 1.0 / 2 * (users ** 2).sum() + 1.0 / 2 * (pos_items ** 2).sum() + 1.0 / 2 * (neg_items ** 2).sum() ) regularizer = regularizer / self.batch_size maxi = F.logsigmoid(pos_scores - neg_scores) mf_loss = -torch.mean(maxi) emb_loss = self.decay * regularizer reg_loss = 0.0 return mf_loss, emb_loss, reg_loss
def generator_loss(fake_logit): return -F.logsigmoid(fake_logit).mean()
def discriminator_loss(real_logit, fake_logit): return -F.logsigmoid(real_logit).mean() - F.logsigmoid(-fake_logit).mean()