class_docstr: Attentional Aggregator for GraphSAGE implemented with Keras base layer
  
  Implements the aggregator of Veličković et al. "Graph Attention Networks" ICLR 2018
  
  Args:
      output_dim (int): Output dimension
      bias (bool): Optional bias
      act (Callable or str): name of the activation function to use (must be a
          Keras activation function), or alternatively, a TensorFlow operation.
class_docstr_tok: ["Attentional","Aggregator","for","GraphSAGE","implemented","with","Keras","base","layer","Implements","the","aggregator","of","Veli\u010dkovi\u0107","et","al",".","``","Graph","Attention","Networks","''","ICLR","2018","Args",":","output_dim","(","int",")",":","Output","dimension","bias","(","bool",")",":","Optional","bias","act","(","Callable","or","str",")",":","name","of","the","activation","function","to","use","(","must","be","a","Keras","activation","function",")",",","or","alternatively",",","a","TensorFlow","operation","."]
docstr: Apply aggregator on the input tensors, `inputs`
  
  Args:
    inputs (List[Tensor]): Tensors giving self and neighbour features
          x[0]: self Tensor (batch_size, head size, feature_size)
          x[k>0]: group Tensors for neighbourhood (batch_size, head size, neighbours, feature_size)
  
  Returns:
      Keras Tensor representing the aggregated embeddings in the input.
docstr_tok: ["Apply","aggregator","on","the","input","tensors",",","`","inputs","`","Args",":","inputs","(","List","[","Tensor","]",")",":","Tensors","giving","self","and","neighbour","features","x","[","0","]",":","self","Tensor","(","batch_size",",","head","size",",","feature_size",")","x","[","k",">","0","]",":","group","Tensors","for","neighbourhood","(","batch_size",",","head","size",",","neighbours",",","feature_size",")","Returns",":","Keras","Tensor","representing","the","aggregated","embeddings","in","the","input","."]
code: def call(self, inputs, **kwargs):
      """
      Apply aggregator on the input tensors, `inputs`
  
      Args:
        inputs (List[Tensor]): Tensors giving self and neighbour features
              x[0]: self Tensor (batch_size, head size, feature_size)
              x[k>0]: group Tensors for neighbourhood (batch_size, head size, neighbours, feature_size)
  
      Returns:
          Keras Tensor representing the aggregated embeddings in the input.
  
      """
      # We require the self group to be included to calculate attention
      if not self.included_weight_groups[0]:
          raise ValueError(
              "The head node group must have non-zero dimension"
          )
  
      # If a neighbourhood dimension exists for the group, aggregate over the neighbours
      # otherwise create a simple layer.
      x_self = inputs[0]
      group_sources = []
      for ii, x_g in enumerate(inputs[1:]):
          group_idx = ii + 1
          if not self.included_weight_groups[group_idx]:
              continue
  
          # Get the weights for this group
          w_g, w_attn_s, w_attn_g = self.w_group[group_idx]
  
          # Group transform for self & neighbours
          xw_self = K.expand_dims(K.dot(x_self, w_g), axis=2)
          xw_neigh = K.dot(x_g, w_g)
  
          # Concatenate self vector to neighbour vectors
          # Shape is (n_b, n_h, n_neigh+1, n_out[ii])
          xw_all = K.concatenate([xw_self, xw_neigh], axis=2)
  
          # Calculate group attention
          attn_self = K.dot(xw_self, w_attn_s)  # (n_b, n_h, 1)
          attn_neigh = K.dot(
              xw_all, w_attn_g
          )  # (n_b, n_h, n_neigh+1, 1)
  
          # Add self and neighbour attn and apply activation
          # Note: This broadcasts to (n_b, n_h, n_neigh + 1, 1)
          attn_u = self.attn_act(attn_self + attn_neigh)
  
          # Attn coefficients, softmax over the neighbours
          attn = K.softmax(attn_u, axis=2)
  
          # Multiply attn coefficients by neighbours (and self) and aggregate
          h_out = K.sum(attn * xw_all, axis=2)
          group_sources.append(h_out)
  
      # If there are no groups with features built, fallback to a MLP on the head node features
      if not group_sources:
          group_sources = [K.dot(x_self, self.w_group[0])]
  
      # Concatenate or sum the outputs from all groups
      h_out = K.concatenate(group_sources, axis=2)
  
      if self.has_bias:
          h_out = h_out + self.bias
  
      return self.act(h_out)
  
imports: import warnings
  import numpy
  from tensorflow.keras.layers import Layer
  from tensorflow.keras import Input
  from tensorflow.keras import backend
  from tensorflow.keras.layers import Lambda, Dropout, Reshape, LeakyReLU
  from tensorflow.keras.utils import Sequence
  from tensorflow.keras import activations, initializers, constraints, regularizers
  from typing import List, Tuple, Callable, AnyStr, Union
  from ..mapper import GraphSAGENodeGenerator, GraphSAGELinkGenerator, DirectedGraphSAGENodeGenerator, DirectedGraphSAGELinkGenerator, NodeSequence, LinkSequence
  from .misc import deprecated_model_function
  from ..connector.neo4j.mapper import Neo4jGraphSAGENodeGenerator, Neo4jDirectedGraphSAGENodeGenerator
label_desc: Use image node_id 4 for calling the AttentionalAggregator obj's underlying member method code with example usage: obj.call(inputs) and returns: self