class_docstr: SAS Rec model
  Self-Attentive Sequential Recommendation Using Transformer
  
  :Citation:
  
      Wang-Cheng Kang, Julian McAuley (2018), Self-Attentive Sequential
      Recommendation. Proceedings of IEEE International Conference on
      Data Mining (ICDM'18)
  
      Original source code from nnkkmto/SASRec-tf2,
      https://github.com/nnkkmto/SASRec-tf2
docstr: Model forward pass.
  
  Args:
      x (tf.Tensor): Input tensor.
      training (tf.Tensor): Training tensor.
  
  Returns:
      tf.Tensor, tf.Tensor, tf.Tensor:
      - Logits of the positive examples.
      - Logits of the negative examples.
      - Mask for nonzero targets
docstr_tok: ["Model","forward","pass",".","Args",":","x","(","tf.Tensor",")",":","Input","tensor",".","training","(","tf.Tensor",")",":","Training","tensor",".","Returns",":","tf.Tensor",",","tf.Tensor",",","tf.Tensor",":","-","Logits","of","the","positive","examples",".","-","Logits","of","the","negative","examples",".","-","Mask","for","nonzero","targets"]
code: def call(self, x, training):
      """Model forward pass.
  
      Args:
          x (tf.Tensor): Input tensor.
          training (tf.Tensor): Training tensor.
  
      Returns:
          tf.Tensor, tf.Tensor, tf.Tensor:
          - Logits of the positive examples.
          - Logits of the negative examples.
          - Mask for nonzero targets
      """
  
      input_seq = x["input_seq"]
      pos = x["positive"]
      neg = x["negative"]
  
      mask = tf.expand_dims(
          tf.cast(tf.not_equal(input_seq, 0), tf.float32), -1
      )
      seq_embeddings, positional_embeddings = self.embedding(input_seq)
  
      # add positional embeddings
      seq_embeddings += positional_embeddings
  
      # dropout
      seq_embeddings = self.dropout_layer(seq_embeddings)
  
      # masking
      seq_embeddings *= mask
  
      # --- ATTENTION BLOCKS ---
      seq_attention = seq_embeddings
      seq_attention = self.encoder(seq_attention, training, mask)
      seq_attention = self.layer_normalization(
          seq_attention
      )  # (b, s, d)
  
      # --- PREDICTION LAYER ---
      # user's sequence embedding
      pos = self.mask_layer(pos)
      neg = self.mask_layer(neg)
  
      pos = tf.reshape(pos, [tf.shape(input_seq)[0] * self.seq_max_len])
      neg = tf.reshape(neg, [tf.shape(input_seq)[0] * self.seq_max_len])
      pos_emb = self.item_embedding_layer(pos)
      neg_emb = self.item_embedding_layer(neg)
      seq_emb = tf.reshape(
          seq_attention,
          [
              tf.shape(input_seq)[0] * self.seq_max_len,
              self.embedding_dim,
          ],
      )  # (b*s, d)
  
      pos_logits = tf.reduce_sum(pos_emb * seq_emb, -1)
      neg_logits = tf.reduce_sum(neg_emb * seq_emb, -1)
  
      pos_logits = tf.expand_dims(pos_logits, axis=-1)  # (bs, 1)
      # pos_prob = tf.keras.layers.Dense(1, activation='sigmoid')(pos_logits)  # (bs, 1)
  
      neg_logits = tf.expand_dims(neg_logits, axis=-1)  # (bs, 1)
      # neg_prob = tf.keras.layers.Dense(1, activation='sigmoid')(neg_logits)  # (bs, 1)
  
      # output = tf.concat([pos_logits, neg_logits], axis=0)
  
      # masking for loss calculation
      istarget = tf.reshape(
          tf.cast(tf.not_equal(pos, 0), dtype=tf.float32),
          [tf.shape(input_seq)[0] * self.seq_max_len],
      )
  
      return pos_logits, neg_logits, istarget
  
imports: import random
  import numpy
  from tqdm import tqdm
  import tensorflow
  from recommenders.utils.timer import Timer
label_desc: Use image node_id 3 for calling the SASREC obj's underlying member method code with example usage: obj.call(x, training) and returns: pos_logits,  neg_logits,  istarget