class_docstr: Neural Graph Collaborative Filtering
  
  Parameters
  ----------
  name: string, default: 'NGCF'
      The name of the recommender model.
  
  emb_size: int, default: 64
      Size of the node embeddings.
  
  layer_sizes: list, default: [64, 64, 64]
      Size of the output of convolution layers.
  
  dropout_rates: list, default: [0.1, 0.1, 0.1]
      Dropout rate for each of the convolution layers.
      - Number of values should be the same as 'layer_sizes'
  
  num_epochs: int, default: 1000
      Maximum number of iterations or the number of epochs.
  
  learning_rate: float, default: 0.001
      The learning rate that determines the step size at each iteration.
  
  batch_size: int, default: 1024
      Mini-batch size used for training.
  
  early_stopping: {min_delta: float, patience: int}, optional, default: None
      If `None`, no early stopping. Meaning of the arguments:
  
      - `min_delta`:  the minimum increase in monitored value on validation
                      set to be considered as improvement,
                      i.e. an increment of less than min_delta will count as
                      no improvement.
  
      - `patience`:   number of epochs with no improvement after which
                      training should be stopped.
  
  lambda_reg: float, default: 1e-4
      Weight decay for the L2 normalization.
  
  trainable: boolean, optional, default: True
      When False, the model is not trained and Cornac assumes that the model
      is already pre-trained.
  
  verbose: boolean, optional, default: False
      When True, some running logs are displayed.
  
  seed: int, optional, default: 2020
      Random seed for parameters initialization.
  
  References
  ----------
  *   Wang, Xiang, et al. "Neural graph collaborative filtering." Proceedings of the 42nd international ACM SIGIR conference on Research and development in Information Retrieval. 2019.
docstr: Fit the model to observations.
  
  Parameters
  ----------
  train_set: :obj:`cornac.data.Dataset`, required
      User-Item preference data as well as additional modalities.
  
  val_set: :obj:`cornac.data.Dataset`, optional, default: None
      User-Item preference data for model selection purposes (e.g., early stopping).
  
  Returns
  -------
  self : object
docstr_tok: ["Fit","the","model","to","observations",".","Parameters","--","--","--","--","--","train_set",":",":","obj",":","`","cornac.data.Dataset","`",",","required","User-Item","preference","data","as","well","as","additional","modalities",".","val_set",":",":","obj",":","`","cornac.data.Dataset","`",",","optional",",","default",":","None","User-Item","preference","data","for","model","selection","purposes","(","e.g.",",","early","stopping",")",".","Returns","--","--","--","-","self",":","object"]
code: def fit(self, train_set, val_set=None):
      """Fit the model to observations.
  
      Parameters
      ----------
      train_set: :obj:`cornac.data.Dataset`, required
          User-Item preference data as well as additional modalities.
  
      val_set: :obj:`cornac.data.Dataset`, optional, default: None
          User-Item preference data for model selection purposes (e.g., early stopping).
  
      Returns
      -------
      self : object
      """
      Recommender.fit(self, train_set, val_set)
  
      if not self.trainable:
          return self
  
      # model setup
      import torch
      from .ngcf import Model
      from .ngcf import construct_graph
  
      self.device = torch.device(
          "cuda" if torch.cuda.is_available() else "cpu"
      )
      if self.seed is not None:
          torch.manual_seed(self.seed)
          if torch.cuda.is_available():
              torch.cuda.manual_seed_all(self.seed)
  
      graph = construct_graph(
          train_set, self.total_users, self.total_items
      ).to(self.device)
      model = Model(
          graph,
          self.emb_size,
          self.layer_sizes,
          self.dropout_rates,
          self.lambda_reg,
      ).to(self.device)
  
      optimizer = torch.optim.Adam(
          model.parameters(), lr=self.learning_rate
      )
  
      # model training
      pbar = trange(
          self.num_epochs,
          desc="Training",
          unit="iter",
          position=0,
          leave=False,
          disable=not self.verbose,
      )
      for _ in pbar:
          model.train()
          accum_loss = 0.0
          for batch_u, batch_i, batch_j in tqdm(
              train_set.uij_iter(
                  batch_size=self.batch_size,
                  shuffle=True,
              ),
              desc="Epoch",
              total=train_set.num_batches(self.batch_size),
              leave=False,
              position=1,
              disable=not self.verbose,
          ):
              (
                  u_g_embeddings,
                  pos_i_g_embeddings,
                  neg_i_g_embeddings,
              ) = model(graph, batch_u, batch_i, batch_j)
  
              (
                  batch_loss,
                  batch_bpr_loss,
                  batch_reg_loss,
              ) = model.loss_fn(
                  u_g_embeddings, pos_i_g_embeddings, neg_i_g_embeddings
              )
              accum_loss += batch_loss.cpu().item() * len(batch_u)
  
              optimizer.zero_grad()
              batch_loss.backward()
              optimizer.step()
  
          accum_loss /= len(
              train_set.uir_tuple[0]
          )  # normalize over all observations
          pbar.set_postfix(loss=accum_loss)
  
          # store user and item embedding matrices for prediction
          model.eval()
          u_embs, i_embs, _ = model(graph)
          # we will use numpy for faster prediction in the score function, no need torch
          self.U = u_embs.cpu().detach().numpy()
          self.V = i_embs.cpu().detach().numpy()
  
          if self.early_stopping is not None and self.early_stop(
              train_set, val_set, **self.early_stopping
          ):
              break
  
file_path: cornac/cornac/models/ngcf/recom_ngcf.py
imports: from ..recommender import Recommender
  from ..recommender import ANNMixin, MEASURE_DOT
  from ...exception import ScoreException
  from tqdm.auto import tqdm, trange
label_desc: Use image node_id 2 for calling the NGCF obj's underlying member method code with example usage: obj.fit(train_set, val_set) and returns: self