class_docstr: RippleNet is an knowledge enhanced matrix factorization model.
  The original interaction matrix of :math:`n_{users} \times n_{items}`
  and related knowledge graph is set as model input,
  we carefully design the data interface and use ripple set to train and test efficiently.
  We just implement the model following the original author with a pointwise training mode.
class_docstr_tok: ["RippleNet","is","an","knowledge","enhanced","matrix","factorization","model",".","The","original","interaction","matrix","of",":","math",":","`","n_","{","users","}","\\times","n_","{","items","}","`","and","related","knowledge","graph","is","set","as","model","input",",","we","carefully","design","the","data","interface","and","use","ripple","set","to","train","and","test","efficiently",".","We","just","implement","the","model","following","the","original","author","with","a","pointwise","training","mode","."]
code: def calculate_loss(self, interaction):
      label = interaction[self.LABEL]
      output = self.forward(interaction)
      rec_loss = self.loss(output, label)
  
      kge_loss = None
      for hop in range(self.n_hop):
          # (batch_size * n_memory, 1, dim)
          h_expanded = self.h_emb_list[hop].unsqueeze(1)
          # (batch_size * n_memory, dim)
          t_expanded = self.t_emb_list[hop]
          # (batch_size * n_memory, dim, dim)
          r_mat = self.r_emb_list[hop].view(
              -1, self.embedding_size, self.embedding_size
          )
          # (N, 1, dim) (N, dim, dim) -> (N, 1, dim)
          hR = torch.bmm(h_expanded, r_mat).squeeze(1)
          # (N, dim) (N, dim)
          hRt = torch.sum(hR * t_expanded, dim=1)
          if kge_loss is None:
              kge_loss = torch.mean(self.sigmoid(hRt))
          else:
              kge_loss = kge_loss + torch.mean(self.sigmoid(hRt))
  
      reg_loss = None
      for hop in range(self.n_hop):
          tp_loss = self.l2_loss(
              self.h_emb_list[hop],
              self.t_emb_list[hop],
              self.r_emb_list[hop],
          )
          if reg_loss is None:
              reg_loss = tp_loss
          else:
              reg_loss = reg_loss + tp_loss
      reg_loss = reg_loss + self.l2_loss(self.transform_matrix.weight)
      loss = (
          rec_loss
          - self.kg_weight * kge_loss
          + self.reg_weight * reg_loss
      )
  
      return loss
  
file_path: RecBole/recbole/model/knowledge_aware_recommender/ripplenet.py
imports: import collections
  import numpy
  import torch
  import torch.nn
  from recbole.model.abstract_recommender import KnowledgeRecommender
  from recbole.model.init import xavier_normal_initialization
  from recbole.model.loss import BPRLoss, EmbLoss
  from recbole.utils import InputType
label_desc: Use image node_id 5 for calling the RippleNet obj's underlying member method code with example usage: obj.calculate_loss(interaction) and returns: loss