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 full_sort_predict(self, interaction):
      users = interaction[self.USER_ID].cpu().numpy()
      memories_h, memories_r, memories_t = {}, {}, {}
      for hop in range(self.n_hop):
          memories_h[hop] = []
          memories_r[hop] = []
          memories_t[hop] = []
          for user in users:
              memories_h[hop].append(self.ripple_set[user][hop][0])
              memories_r[hop].append(self.ripple_set[user][hop][1])
              memories_t[hop].append(self.ripple_set[user][hop][2])
      # memories_h, memories_r, memories_t = self.ripple_set[user]
      # item = interaction[self.ITEM_ID]
      self.item_embeddings = self.entity_embedding.weight[
          : self.n_items
      ]
      # self.item_embeddings = self.entity_embedding(item)
  
      self.h_emb_list = []
      self.r_emb_list = []
      self.t_emb_list = []
      for i in range(self.n_hop):
          # [batch size * n_memory]
          head_ent = torch.cat(memories_h[i], dim=0)
          relation = torch.cat(memories_r[i], dim=0)
          tail_ent = torch.cat(memories_t[i], dim=0)
          # self.logger.info("Hop {}, size {}".format(i, head_ent.size(), relation.size(), tail_ent.size()))
  
          # [batch size * n_memory, dim]
          self.h_emb_list.append(self.entity_embedding(head_ent))
  
          # [batch size * n_memory, dim * dim]
          self.r_emb_list.append(self.relation_embedding(relation))
  
          # [batch size * n_memory, dim]
          self.t_emb_list.append(self.entity_embedding(tail_ent))
  
      o_list = self._key_addressing_full()
      y = o_list[-1]
      for i in range(self.n_hop - 1):
          y = y + o_list[i]
      # [batch_size, n_item, dim] [batch_size, n_item, dim]
      scores = torch.sum(self.item_embeddings * y, dim=-1)
      return scores.view(-1)
  
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 8 for calling the RippleNet obj's underlying member method code with example usage: obj.full_sort_predict(interaction) and returns: scores