class_docstr: SimpleX is a simple, unified collaborative filtering model.
  
  SimpleX presents a simple and easy-to-understand model. Its advantage lies
  in its loss function, which uses a larger number of negative samples and
  sets a threshold to filter out less informative samples, it also uses
  relative weights to control the balance of positive-sample loss
  and negative-sample loss.
  
  We implement the model following the original author with a pairwise training mode.
docstr: Get the loss
  
  Args:
      user (torch.Tensor): User's id, shape: [user_num]
      pos_item (torch.Tensor): Positive item's id, shape: [user_num]
      history_item (torch.Tensor): Id of historty item, shape: [user_num, max_history_len]
      history_len (torch.Tensor): History item's length, shape: [user_num]
      neg_item_seq (torch.Tensor): Negative item seq's id, shape: [user_num, neg_seq_len]
  
  Returns:
      torch.Tensor: Loss, shape: []
docstr_tok: ["Get","the","loss","Args",":","user","(","torch.Tensor",")",":","User","'s","id",",","shape",":","[","user_num","]","pos_item","(","torch.Tensor",")",":","Positive","item","'s","id",",","shape",":","[","user_num","]","history_item","(","torch.Tensor",")",":","Id","of","historty","item",",","shape",":","[","user_num",",","max_history_len","]","history_len","(","torch.Tensor",")",":","History","item","'s","length",",","shape",":","[","user_num","]","neg_item_seq","(","torch.Tensor",")",":","Negative","item","seq","'s","id",",","shape",":","[","user_num",",","neg_seq_len","]","Returns",":","torch.Tensor",":","Loss",",","shape",":","[","]"]
code: def forward(
      self, user, pos_item, history_item, history_len, neg_item_seq
  ):
      r"""Get the loss
  
      Args:
          user (torch.Tensor): User's id, shape: [user_num]
          pos_item (torch.Tensor): Positive item's id, shape: [user_num]
          history_item (torch.Tensor): Id of historty item, shape: [user_num, max_history_len]
          history_len (torch.Tensor): History item's length, shape: [user_num]
          neg_item_seq (torch.Tensor): Negative item seq's id, shape: [user_num, neg_seq_len]
  
      Returns:
          torch.Tensor: Loss, shape: []
      """
      # [user_num, embedding_size]
      user_e = self.user_emb(user)
      # [user_num, embedding_size]
      pos_item_e = self.item_emb(pos_item)
      # [user_num, max_history_len, embedding_size]
      history_item_e = self.item_emb(history_item)
      # [nuser_num, neg_seq_len, embedding_size]
      neg_item_seq_e = self.item_emb(neg_item_seq)
  
      # [user_num, embedding_size]
      UI_aggregation_e = self.get_UI_aggregation(
          user_e, history_item_e, history_len
      )
      UI_aggregation_e = self.dropout(UI_aggregation_e)
  
      pos_cos = self.get_cos(UI_aggregation_e, pos_item_e.unsqueeze(1))
      neg_cos = self.get_cos(UI_aggregation_e, neg_item_seq_e)
  
      # CCL loss
      pos_loss = torch.relu(1 - pos_cos)
      neg_loss = torch.relu(neg_cos - self.margin)
      neg_loss = neg_loss.mean(1, keepdim=True) * self.negative_weight
      CCL_loss = (pos_loss + neg_loss).mean()
  
      # l2 regularization loss
      reg_loss = self.reg_loss(
          user_e,
          pos_item_e,
          history_item_e,
          neg_item_seq_e,
          require_pow=self.require_pow,
      )
  
      loss = CCL_loss + self.reg_weight * reg_loss.sum()
      return loss
  
file_path: RecBole/recbole/model/general_recommender/simplex.py
imports: import torch
  from torch import nn
  import torch.nn.functional
  from recbole.model.init import xavier_normal_initialization
  from recbole.model.abstract_recommender import GeneralRecommender
  from recbole.model.loss import EmbLoss
  from recbole.utils import InputType
label_desc: Use image node_id 4 for calling the SimpleX obj's underlying member method code with example usage: obj.forward(user, pos_item, history_item, history_len, neg_item_seq) and returns: loss