class_docstr: Graph neural networks are well-suited for session-based recommendation,
  because it can automatically extract features of session graphs with considerations of rich node connections.
class_docstr_tok: ["Graph","neural","networks","are","well-suited","for","session-based","recommendation",",","because","it","can","automatically","extract","features","of","session","graphs","with","considerations","of","rich","node","connections","."]
docstr: Obtain latent vectors of nodes via gated graph neural network.
  
  Args:
      A (torch.FloatTensor): The connection matrix,shape of [batch_size, max_session_len, 2 * max_session_len]
  
      hidden (torch.FloatTensor): The item node embedding matrix, shape of
          [batch_size, max_session_len, embedding_size]
  
  Returns:
      torch.FloatTensor: Latent vectors of nodes,shape of [batch_size, max_session_len, embedding_size]
docstr_tok: ["Obtain","latent","vectors","of","nodes","via","gated","graph","neural","network",".","Args",":","A","(","torch.FloatTensor",")",":","The","connection","matrix",",","shape","of","[","batch_size",",","max_session_len",",","2","*","max_session_len","]","hidden","(","torch.FloatTensor",")",":","The","item","node","embedding","matrix",",","shape","of","[","batch_size",",","max_session_len",",","embedding_size","]","Returns",":","torch.FloatTensor",":","Latent","vectors","of","nodes",",","shape","of","[","batch_size",",","max_session_len",",","embedding_size","]"]
code: def GNNCell(self, A, hidden):
      r"""Obtain latent vectors of nodes via gated graph neural network.
  
      Args:
          A (torch.FloatTensor): The connection matrix,shape of [batch_size, max_session_len, 2 * max_session_len]
  
          hidden (torch.FloatTensor): The item node embedding matrix, shape of
              [batch_size, max_session_len, embedding_size]
  
      Returns:
          torch.FloatTensor: Latent vectors of nodes,shape of [batch_size, max_session_len, embedding_size]
  
      """
  
      input_in = torch.matmul(
          A[:, :, : A.size(1)], self.linear_edge_in(hidden)
      )
      input_out = torch.matmul(
          A[:, :, A.size(1) : 2 * A.size(1)],
          self.linear_edge_out(hidden),
      )
      # [batch_size, max_session_len, embedding_size * 2]
      inputs = torch.cat([input_in, input_out], 2)
  
      # gi.size equals to gh.size, shape of [batch_size, max_session_len, embedding_size * 3]
      gi = F.linear(inputs, self.w_ih, self.b_ih)
      gh = F.linear(hidden, self.w_hh, self.b_hh)
      # (batch_size, max_session_len, embedding_size)
      i_r, i_i, i_n = gi.chunk(3, 2)
      h_r, h_i, h_n = gh.chunk(3, 2)
      reset_gate = torch.sigmoid(i_r + h_r)
      input_gate = torch.sigmoid(i_i + h_i)
      new_gate = torch.tanh(i_n + reset_gate * h_n)
      hy = (1 - input_gate) * hidden + input_gate * new_gate
      return hy
  
imports: import math
  import numpy
  import torch
  from torch import nn
  from torch.nn import Parameter
  from torch.nn import functional
  from recbole.model.abstract_recommender import SequentialRecommender
  from recbole.model.layers import TransformerEncoder
  from recbole.model.loss import EmbLoss, BPRLoss
label_desc: Use image node_id 3 for calling the GNN obj's underlying member method code with example usage: obj.GNNCell(A, hidden) and returns: hy