class_docstr: SSE-PT Model
  
  :Citation:
  
  Wu L., Li S., Hsieh C-J., Sharpnack J., SSE-PT: Sequential Recommendation
  Via Personalized Transformer, RecSys, 2020.
  TF 1.x codebase: https://github.com/SSE-PT/SSE-PT
  TF 2.x codebase (SASREc): https://github.com/nnkkmto/SASRec-tf2
docstr: Losses are calculated separately for the positive and negative
  items based on the corresponding logits. A mask is included to
  take care of the zero items (added for padding).
  
  Args:
      pos_logits (tf.Tensor): Logits of the positive examples.
      neg_logits (tf.Tensor): Logits of the negative examples.
      istarget (tf.Tensor): Mask for nonzero targets.
  
  Returns:
      float: Loss.
docstr_tok: ["Losses","are","calculated","separately","for","the","positive","and","negative","items","based","on","the","corresponding","logits",".","A","mask","is","included","to","take","care","of","the","zero","items","(","added","for","padding",")",".","Args",":","pos_logits","(","tf.Tensor",")",":","Logits","of","the","positive","examples",".","neg_logits","(","tf.Tensor",")",":","Logits","of","the","negative","examples",".","istarget","(","tf.Tensor",")",":","Mask","for","nonzero","targets",".","Returns",":","float",":","Loss","."]
code: def loss_function(self, pos_logits, neg_logits, istarget):
      """Losses are calculated separately for the positive and negative
      items based on the corresponding logits. A mask is included to
      take care of the zero items (added for padding).
  
      Args:
          pos_logits (tf.Tensor): Logits of the positive examples.
          neg_logits (tf.Tensor): Logits of the negative examples.
          istarget (tf.Tensor): Mask for nonzero targets.
  
      Returns:
          float: Loss.
      """
  
      pos_logits = pos_logits[:, 0]
      neg_logits = neg_logits[:, 0]
  
      # ignore padding items (0)
      # istarget = tf.reshape(
      #     tf.cast(tf.not_equal(self.pos, 0), dtype=tf.float32),
      #     [tf.shape(self.input_seq)[0] * self.seq_max_len],
      # )
      # for logits
      loss = tf.reduce_sum(
          -tf.math.log(tf.math.sigmoid(pos_logits) + 1e-24) * istarget
          - tf.math.log(1 - tf.math.sigmoid(neg_logits) + 1e-24)
          * istarget
      ) / tf.reduce_sum(istarget)
  
      # for probabilities
      # loss = tf.reduce_sum(
      #         - tf.math.log(pos_logits + 1e-24) * istarget -
      #         tf.math.log(1 - neg_logits + 1e-24) * istarget
      # ) / tf.reduce_sum(istarget)
      reg_loss = tf.compat.v1.losses.get_regularization_loss()
      # reg_losses = tf.compat.v1.get_collection(tf.compat.v1.GraphKeys.REGULARIZATION_LOSSES)
      # loss += sum(reg_losses)
      loss += reg_loss
  
      return loss
  
file_path: recommenders/recommenders/models/sasrec/ssept.py
imports: import tensorflow
  from recommenders.models.sasrec.model import SASREC, Encoder, LayerNormalization
label_desc: Use image node_id 4 for calling the SSEPT obj's underlying member method code with example usage: obj.loss_function(pos_logits, neg_logits, istarget) and returns: loss