class_docstr: S3Rec is the first work to incorporate self-supervised learning in
  sequential recommendation.
  
  NOTE:
      Under this framework, we need reconstruct the pretraining data,
      which would affect the pre-training speed.
code: def __init__(self, config, dataset):
      super(S3Rec, self).__init__(config, dataset)
  
      # load parameters info
      self.n_layers = config["n_layers"]
      self.n_heads = config["n_heads"]
      self.hidden_size = config["hidden_size"]  # same as embedding_size
      self.inner_size = config[
          "inner_size"
      ]  # the dimensionality in feed-forward layer
      self.hidden_dropout_prob = config["hidden_dropout_prob"]
      self.attn_dropout_prob = config["attn_dropout_prob"]
      self.hidden_act = config["hidden_act"]
      self.layer_norm_eps = config["layer_norm_eps"]
  
      self.FEATURE_FIELD = config["item_attribute"]
      self.FEATURE_LIST = self.FEATURE_FIELD + config["LIST_SUFFIX"]
      self.train_stage = config["train_stage"]  # pretrain or finetune
      self.pre_model_path = config[
          "pre_model_path"
      ]  # We need this for finetune
      self.mask_ratio = config["mask_ratio"]
      self.aap_weight = config["aap_weight"]
      self.mip_weight = config["mip_weight"]
      self.map_weight = config["map_weight"]
      self.sp_weight = config["sp_weight"]
  
      self.initializer_range = config["initializer_range"]
      self.loss_type = config["loss_type"]
  
      # load dataset info
      self.n_items = dataset.item_num + 1  # for mask token
      self.mask_token = self.n_items - 1
      self.n_features = (
          dataset.num(self.FEATURE_FIELD) - 1
      )  # we don't need padding
      self.item_feat = dataset.get_item_feature()
  
      # define layers and loss
      # modules shared by pre-training stage and fine-tuning stage
      self.item_embedding = nn.Embedding(
          self.n_items, self.hidden_size, padding_idx=0
      )
      self.position_embedding = nn.Embedding(
          self.max_seq_length, self.hidden_size
      )
      self.feature_embedding = nn.Embedding(
          self.n_features, self.hidden_size, padding_idx=0
      )
  
      self.trm_encoder = TransformerEncoder(
          n_layers=self.n_layers,
          n_heads=self.n_heads,
          hidden_size=self.hidden_size,
          inner_size=self.inner_size,
          hidden_dropout_prob=self.hidden_dropout_prob,
          attn_dropout_prob=self.attn_dropout_prob,
          hidden_act=self.hidden_act,
          layer_norm_eps=self.layer_norm_eps,
      )
  
      self.LayerNorm = nn.LayerNorm(
          self.hidden_size, eps=self.layer_norm_eps
      )
      self.dropout = nn.Dropout(self.hidden_dropout_prob)
  
      # modules for pretrain
      # add unique dense layer for 4 losses respectively
      self.aap_norm = nn.Linear(self.hidden_size, self.hidden_size)
      self.mip_norm = nn.Linear(self.hidden_size, self.hidden_size)
      self.map_norm = nn.Linear(self.hidden_size, self.hidden_size)
      self.sp_norm = nn.Linear(self.hidden_size, self.hidden_size)
      self.loss_fct = nn.BCEWithLogitsLoss(reduction="none")
  
      # modules for finetune
      if self.loss_type == "BPR" and self.train_stage == "finetune":
          self.loss_fct = BPRLoss()
      elif self.loss_type == "CE" and self.train_stage == "finetune":
          self.loss_fct = nn.CrossEntropyLoss()
      elif self.train_stage == "finetune":
          raise NotImplementedError(
              "Make sure 'loss_type' in ['BPR', 'CE']!"
          )
  
      # parameters initialization
      assert self.train_stage in ["pretrain", "finetune"]
      if self.train_stage == "pretrain":
          self.apply(self._init_weights)
      else:
          # load pretrained model for finetune
          pretrained = torch.load(self.pre_model_path)
          self.logger.info(
              f"Load pretrained model from {self.pre_model_path}"
          )
          self.load_state_dict(pretrained["state_dict"])
  
imports: import random
  import torch
  from torch import nn
  from recbole.model.abstract_recommender import SequentialRecommender
  from recbole.model.layers import TransformerEncoder
  from recbole.model.loss import BPRLoss
label_desc: Use image node_id 1 to create a new S3Rec object from inherited base classes: SequentialRecommender with example: obj = S3Rec(config, dataset)