class_docstr: Graph Attention (GAT) layer. The base implementation is taken from
  https://github.com/danielegrattarola/keras-gat,
  with some modifications added for ease of use.
  
  Based on the original paper: Graph Attention Networks. P. Veličković et al. ICLR 2018 https://arxiv.org/abs/1710.10903
  
  Notes:
    - The inputs are tensors with a batch dimension of 1:
      Keras requires this batch dimension, and for full-batch methods
      we only have a single "batch".
  
    - There are two inputs required, the node features,
      and the graph adjacency matrix
  
    - This does not add self loops to the adjacency matrix, you should preprocess
      the adjacency matrix to add self-loops
  
  .. seealso:: :class:`.GAT` combines several of these layers, and :class:`.GraphAttentionSparse` supports a sparse adjacency matrix.
  
  Args:
      F_out (int): dimensionality of output feature vectors
      attn_heads (int or list of int): number of attention heads
      attn_heads_reduction (str): reduction applied to output features of each attention head, ``concat`` or ``average``.
          ``average`` should be applied in the final prediction layer of the model (Eq. 6 of the paper).
      in_dropout_rate (float): dropout rate applied to features
      attn_dropout_rate (float): dropout rate applied to attention coefficients
      activation (str): nonlinear activation applied to layer's output to obtain output features (eq. 4 of the GAT paper)
      final_layer (bool): Deprecated, use ``tf.gather`` or :class:`.GatherIndices`
      use_bias (bool): toggles an optional bias
      saliency_map_support (bool): If calculating saliency maps using the tools in
          stellargraph.interpretability.saliency_maps this should be True. Otherwise this should be False (default).
      kernel_initializer (str or func, optional): The initialiser to use for the head weights.
      kernel_regularizer (str or func, optional): The regulariser to use for the head weights.
      kernel_constraint (str or func, optional): The constraint to use for the head weights.
      bias_initializer (str or func, optional): The initialiser to use for the head bias.
      bias_regularizer (str or func, optional): The regulariser to use for the head bias.
      bias_constraint (str or func, optional): The constraint to use for the head bias.
      attn_kernel_initializer (str or func, optional): The initialiser to use for the attention weights.
      attn_kernel_regularizer (str or func, optional): The regulariser to use for the attention weights.
      attn_kernel_constraint (str or func, optional): The constraint to use for the attention weights.
class_docstr_tok: ["Graph","Attention","(","GAT",")","layer",".","The","base","implementation","is","taken","from","https",":","\/\/github.com\/danielegrattarola\/keras-gat",",","with","some","modifications","added","for","ease","of","use",".","Based","on","the","original","paper",":","Graph","Attention","Networks",".","P.","Veli\u010dkovi\u0107","et","al",".","ICLR","2018","https",":","\/\/arxiv.org\/abs\/1710.10903","Notes",":","-","The","inputs","are","tensors","with","a","batch","dimension","of","1",":","Keras","requires","this","batch","dimension",",","and","for","full-batch","methods","we","only","have","a","single","``","batch","''",".","-","There","are","two","inputs","required",",","the","node","features",",","and","the","graph","adjacency","matrix","-","This","does","not","add","self","loops","to","the","adjacency","matrix",",","you","should","preprocess","the","adjacency","matrix","to","add","self-loops","..","seealso",":",":",":","class",":","`",".GAT","`","combines","several","of","these","layers",",","and",":","class",":","`",".GraphAttentionSparse","`","supports","a","sparse","adjacency","matrix",".","Args",":","F_out","(","int",")",":","dimensionality","of","output","feature","vectors","attn_heads","(","int","or","list","of","int",")",":","number","of","attention","heads","attn_heads_reduction","(","str",")",":","reduction","applied","to","output","features","of","each","attention","head",",","``","concat","``","or","``","average","``",".","``","average","``","should","be","applied","in","the","final","prediction","layer","of","the","model","(","Eq",".","6","of","the","paper",")",".","in_dropout_rate","(","float",")",":","dropout","rate","applied","to","features","attn_dropout_rate","(","float",")",":","dropout","rate","applied","to","attention","coefficients","activation","(","str",")",":","nonlinear","activation","applied","to","layer","'s","output","to","obtain","output","features","(","eq",".","4","of","the","GAT","paper",")","final_layer","(","bool",")",":","Deprecated",",","use","``","tf.gather","``","or",":","class",":","`",".GatherIndices","`","use_bias","(","bool",")",":","toggles","an","optional","bias","saliency_map_support","(","bool",")",":","If","calculating","saliency","maps","using","the","tools","in","stellargraph.interpretability.saliency_maps","this","should","be","True",".","Otherwise","this","should","be","False","(","default",")",".","kernel_initializer","(","str","or","func",",","optional",")",":","The","initialiser","to","use","for","the","head","weights",".","kernel_regularizer","(","str","or","func",",","optional",")",":","The","regulariser","to","use","for","the","head","weights",".","kernel_constraint","(","str","or","func",",","optional",")",":","The","constraint","to","use","for","the","head","weights",".","bias_initializer","(","str","or","func",",","optional",")",":","The","initialiser","to","use","for","the","head","bias",".","bias_regularizer","(","str","or","func",",","optional",")",":","The","regulariser","to","use","for","the","head","bias",".","bias_constraint","(","str","or","func",",","optional",")",":","The","constraint","to","use","for","the","head","bias",".","attn_kernel_initializer","(","str","or","func",",","optional",")",":","The","initialiser","to","use","for","the","attention","weights",".","attn_kernel_regularizer","(","str","or","func",",","optional",")",":","The","regulariser","to","use","for","the","attention","weights",".","attn_kernel_constraint","(","str","or","func",",","optional",")",":","The","constraint","to","use","for","the","attention","weights","."]
docstr: Creates the layer as a Keras graph.
  
  Note that the inputs are tensors with a batch dimension of 1:
  Keras requires this batch dimension, and for full-batch methods
  we only have a single "batch".
  
  There are two inputs required, the node features,
  and the graph adjacency matrix
  
  Notes:
      This does not add self loops to the adjacency matrix.
  
  Args:
      inputs (list): list of inputs with 3 items:
      node features (size 1 x N x F),
      graph adjacency matrix (size N x N),
      where N is the number of nodes in the graph,
            F is the dimensionality of node features
            M is the number of output nodes
docstr_tok: ["Creates","the","layer","as","a","Keras","graph",".","Note","that","the","inputs","are","tensors","with","a","batch","dimension","of","1",":","Keras","requires","this","batch","dimension",",","and","for","full-batch","methods","we","only","have","a","single","``","batch","''",".","There","are","two","inputs","required",",","the","node","features",",","and","the","graph","adjacency","matrix","Notes",":","This","does","not","add","self","loops","to","the","adjacency","matrix",".","Args",":","inputs","(","list",")",":","list","of","inputs","with","3","items",":","node","features","(","size","1","x","N","x","F",")",",","graph","adjacency","matrix","(","size","N","x","N",")",",","where","N","is","the","number","of","nodes","in","the","graph",",","F","is","the","dimensionality","of","node","features","M","is","the","number","of","output","nodes"]
code: def call(self, inputs):
      """
      Creates the layer as a Keras graph.
  
      Note that the inputs are tensors with a batch dimension of 1:
      Keras requires this batch dimension, and for full-batch methods
      we only have a single "batch".
  
      There are two inputs required, the node features,
      and the graph adjacency matrix
  
      Notes:
          This does not add self loops to the adjacency matrix.
  
      Args:
          inputs (list): list of inputs with 3 items:
          node features (size 1 x N x F),
          graph adjacency matrix (size N x N),
          where N is the number of nodes in the graph,
                F is the dimensionality of node features
                M is the number of output nodes
      """
      X = inputs[0]  # Node features (1 x N x F)
      A = inputs[1]  # Adjacency matrix (1 X N x N)
      N = K.int_shape(A)[-1]
  
      batch_dim, n_nodes, _ = K.int_shape(X)
      if batch_dim != 1:
          raise ValueError(
              "Currently full-batch methods only support a batch dimension of one"
          )
  
      else:
          # Remove singleton batch dimension
          X = K.squeeze(X, 0)
          A = K.squeeze(A, 0)
  
      outputs = []
      for head in range(self.attn_heads):
          kernel = self.kernels[head]  # W in the paper (F x F')
          attention_kernel = self.attn_kernels[
              head
          ]  # Attention kernel a in the paper (2F' x 1)
  
          # Compute inputs to attention network
          features = K.dot(X, kernel)  # (N x F')
  
          # Compute feature combinations
          # Note: [[a_1], [a_2]]^T [[Wh_i], [Wh_2]] = [a_1]^T [Wh_i] + [a_2]^T [Wh_j]
          attn_for_self = K.dot(
              features, attention_kernel[0]
          )  # (N x 1), [a_1]^T [Wh_i]
          attn_for_neighs = K.dot(
              features, attention_kernel[1]
          )  # (N x 1), [a_2]^T [Wh_j]
  
          # Attention head a(Wh_i, Wh_j) = a^T [[Wh_i], [Wh_j]]
          dense = attn_for_self + K.transpose(
              attn_for_neighs
          )  # (N x N) via broadcasting
  
          # Add nonlinearity
          dense = LeakyReLU(alpha=0.2)(dense)
  
          # Mask values before activation (Vaswani et al., 2017)
          # YT: this only works for 'binary' A, not for 'weighted' A!
          # YT: if A does not have self-loops, the node itself will be masked, so A should have self-loops
          # YT: this is ensured by setting the diagonal elements of A tensor to 1 above
          if not self.saliency_map_support:
              mask = -10e9 * (1.0 - A)
              dense += mask
              dense = K.softmax(dense)  # (N x N), Eq. 3 of the paper
  
          else:
              # dense = dense - tf.reduce_max(dense)
              # GAT with support for saliency calculations
              W = (self.delta * A) * K.exp(
                  dense - K.max(dense, axis=1, keepdims=True)
              ) * (1 - self.non_exist_edge) + self.non_exist_edge * (
                  A + self.delta * (tf.ones((N, N)) - A) + tf.eye(N)
              ) * K.exp(
                  dense - K.max(dense, axis=1, keepdims=True)
              )
              dense = W / K.sum(W, axis=1, keepdims=True)
  
          # Apply dropout to features and attention coefficients
          dropout_feat = Dropout(self.in_dropout_rate)(
              features
          )  # (N x F')
          dropout_attn = Dropout(self.attn_dropout_rate)(
              dense
          )  # (N x N)
  
          # Linear combination with neighbors' features [YT: see Eq. 4]
          node_features = K.dot(dropout_attn, dropout_feat)  # (N x F')
  
          if self.use_bias:
              node_features = K.bias_add(
                  node_features, self.biases[head]
              )
  
          # Add output of attention head to final output
          outputs.append(node_features)
  
      # Aggregate the heads' output according to the reduction method
      if self.attn_heads_reduction == "concat":
          output = K.concatenate(outputs)  # (N x KF')
      else:
          output = K.mean(K.stack(outputs), axis=0)  # N x F')
  
      # Nonlinear activation function
      output = self.activation(output)
  
      # Add batch dimension back if we removed it
      if batch_dim == 1:
          output = K.expand_dims(output, 0)
  
      return output
  
imports: import warnings
  import tensorflow
  from tensorflow.keras import backend
  from tensorflow.keras import activations, constraints, initializers, regularizers
  from tensorflow.keras.layers import Input, Layer, Dropout, LeakyReLU, Lambda, Reshape
  from ..mapper import FullBatchNodeGenerator, FullBatchGenerator, ClusterNodeGenerator
  from .misc import SqueezedSparseConversion, deprecated_model_function, GatherIndices
label_desc: Use image node_id 5 for calling the GraphAttention obj's underlying member method code with example usage: obj.call(inputs) and returns: output