class_docstr: An Attention-based Graph Neural Network (AGNN) from the paper
  
  > [Attention-based Graph Neural Network for Semi-supervised Learning](https://arxiv.org/abs/1803.03735)<br>
  > Kiran K. Thekumparampil et al.
  
  **Mode**: single, disjoint, mixed.
  
  **This layer expects a sparse adjacency matrix.**
  
  This layer computes:
  $$
      \X' = \P\X
  $$
  where
  $$
      \P_{ij} = \frac{
          \exp \left( \beta \cos \left( \x_i, \x_j \right) \right)
      }{
          \sum\limits_{k \in \mathcal{N}(i) \cup \{ i \}}
          \exp \left( \beta \cos \left( \x_i, \x_k \right) \right)
      }
  $$
  and \(\beta\) is a trainable parameter.
  
  **Input**
  
  - Node features of shape `(n_nodes, n_node_features)`;
  - Binary adjacency matrix of shape `(n_nodes, n_nodes)`.
  
  **Output**
  
  - Node features with the same shape of the input.
  
  **Arguments**
  
  - `trainable`: boolean, if True, then beta is a trainable parameter.
  Otherwise, beta is fixed to 1;
  - `activation`: activation function;
class_docstr_tok: ["An","Attention-based","Graph","Neural","Network","(","AGNN",")","from","the","paper",">","[","Attention-based","Graph","Neural","Network","for","Semi-supervised","Learning","]","(","https",":","\/\/arxiv.org\/abs\/1803.03735",")","<","br",">",">","Kiran","K.","Thekumparampil","et","al",".","*","*","Mode","*","*",":","single",",","disjoint",",","mixed",".","*","*","This","layer","expects","a","sparse","adjacency","matrix",".","*","*","This","layer","computes",":","$","$","\\X","'","=","\\P\\X","$","$","where","$","$","\\P_","{","ij","}","=","\\frac","{","\\exp","\\left","(","\\beta","\\cos","\\left","(","\\x_i",",","\\x_j","\\right",")","\\right",")","}","{","\\sum\\limits_","{","k","\\in","\\mathcal","{","N","}","(","i",")","\\cup","\\","{","i","\\","}","}","\\exp","\\left","(","\\beta","\\cos","\\left","(","\\x_i",",","\\x_k","\\right",")","\\right",")","}","$","$","and","\\","(","\\beta\\",")","is","a","trainable","parameter",".","*","*","Input","*","*","-","Node","features","of","shape","`","(","n_nodes",",","n_node_features",")","`",";","-","Binary","adjacency","matrix","of","shape","`","(","n_nodes",",","n_nodes",")","`",".","*","*","Output","*","*","-","Node","features","with","the","same","shape","of","the","input",".","*","*","Arguments","*","*","-","`","trainable","`",":","boolean",",","if","True",",","then","beta","is","a","trainable","parameter",".","Otherwise",",","beta","is","fixed","to","1",";","-","`","activation","`",":","activation","function",";"]
code: def message(self, x, x_norm=None):
      x_j = self.get_sources(x)
      x_norm_i = self.get_targets(x_norm)
      x_norm_j = self.get_sources(x_norm)
      alpha = self.beta * tf.reduce_sum(x_norm_i * x_norm_j, axis=-1)
  
      if len(alpha.shape) == 2:
          alpha = tf.transpose(alpha)  # For mixed mode
      alpha = ops.unsorted_segment_softmax(
          alpha, self.index_targets, self.n_nodes
      )
      if len(alpha.shape) == 2:
          alpha = tf.transpose(alpha)  # For mixed mode
      alpha = alpha[..., None]
  
      return alpha * x_j
  
file_path: spektral/spektral/layers/convolutional/agnn_conv.py
imports: import tensorflow
  from tensorflow.keras import backend
  from spektral.layers import ops
  from spektral.layers.convolutional.message_passing import MessagePassing
label_desc: Use image node_id 4 for calling the AGNNConv obj's underlying member method code with example usage: obj.message(x, x_norm) and returns: unknown