class_docstr: NCL is a neighborhood-enriched contrastive learning paradigm for graph collaborative filtering.
  Both structural and semantic neighbors are explicitly captured as contrastive learning objects.
class_docstr_tok: ["NCL","is","a","neighborhood-enriched","contrastive","learning","paradigm","for","graph","collaborative","filtering",".","Both","structural","and","semantic","neighbors","are","explicitly","captured","as","contrastive","learning","objects","."]
code: def calculate_loss(self, interaction):
      # clear the storage variable when training
      if (
          self.restore_user_e is not None
          or self.restore_item_e is not None
      ):
          self.restore_user_e, self.restore_item_e = None, None
  
      user = interaction[self.USER_ID]
      pos_item = interaction[self.ITEM_ID]
      neg_item = interaction[self.NEG_ITEM_ID]
  
      (
          user_all_embeddings,
          item_all_embeddings,
          embeddings_list,
      ) = self.forward()
  
      center_embedding = embeddings_list[0]
      context_embedding = embeddings_list[self.hyper_layers * 2]
  
      ssl_loss = self.ssl_layer_loss(
          context_embedding, center_embedding, user, pos_item
      )
      proto_loss = self.ProtoNCE_loss(center_embedding, user, pos_item)
  
      u_embeddings = user_all_embeddings[user]
      pos_embeddings = item_all_embeddings[pos_item]
      neg_embeddings = item_all_embeddings[neg_item]
  
      # calculate BPR Loss
      pos_scores = torch.mul(u_embeddings, pos_embeddings).sum(dim=1)
      neg_scores = torch.mul(u_embeddings, neg_embeddings).sum(dim=1)
  
      mf_loss = self.mf_loss(pos_scores, neg_scores)
  
      u_ego_embeddings = self.user_embedding(user)
      pos_ego_embeddings = self.item_embedding(pos_item)
      neg_ego_embeddings = self.item_embedding(neg_item)
  
      reg_loss = self.reg_loss(
          u_ego_embeddings, pos_ego_embeddings, neg_ego_embeddings
      )
  
      return mf_loss + self.reg_weight * reg_loss, ssl_loss, proto_loss
  
imports: import numpy
  import scipy.sparse
  import torch
  import torch.nn.functional
  from recbole.model.abstract_recommender import GeneralRecommender
  from recbole.model.init import xavier_uniform_initialization
  from recbole.model.loss import BPRLoss, EmbLoss
  from recbole.utils import InputType
label_desc: Use image node_id 9 for calling the NCL obj's underlying member method code with example usage: obj.calculate_loss(interaction) and returns: unknown,  ssl_loss,  proto_loss