class_docstr: A block containing multiple subsequent graph (multi-head) attention stacks.
  
  One convolution stack consists of one graph multi-head attention in addition to an activation layer.
  The block expects the input tensors to have the form:
  
  - Feature matrix: first in_key: (batch-dim, num-of-nodes, feature-dim)
  - Adjacency matrix: second in_key: (batch-dim, num-of-nodes, num-of-nodes) (also symmetric)
  
  And returns a tensor of the form (batch-dim, num-of-nodes, feature-out-dim).
  
  :param in_keys: Two keys identifying the feature matrix and adjacency matrix respectively.
  :param out_keys: One key identifying the output tensors.
  :param in_shapes: List of input shapes.
  :param hidden_features: List containing the number of hidden features for hidden layers.
  :param non_lins: The non-linearity/ies to apply after each layer (the same in all layers, or a list corresponding
      to each layer).
  :param n_heads: The number of heads each stack should have. (default suggestion 8)
  :param attention_alpha: Specify the negative slope of the leakyReLU in each of the attention layers.
      parameter with init value :param node_self_importance. (default suggestion 0.2)
  :param avg_last_head_attentions: Specify whether to average the outputs from the attention head in the last layer
      of the attention stack. (default suggestion True or n_heads=0 in the last layer)
  :param attention_dropout: Specify the dropout to be within the layers applied on the computed attention.
class_docstr_tok: ["A","block","containing","multiple","subsequent","graph","(","multi-head",")","attention","stacks",".","One","convolution","stack","consists","of","one","graph","multi-head","attention","in","addition","to","an","activation","layer",".","The","block","expects","the","input","tensors","to","have","the","form",":","-","Feature","matrix",":","first","in_key",":","(","batch-dim",",","num-of-nodes",",","feature-dim",")","-","Adjacency","matrix",":","second","in_key",":","(","batch-dim",",","num-of-nodes",",","num-of-nodes",")","(","also","symmetric",")","And","returns","a","tensor","of","the","form","(","batch-dim",",","num-of-nodes",",","feature-out-dim",")",".",":","param","in_keys",":","Two","keys","identifying","the","feature","matrix","and","adjacency","matrix","respectively",".",":","param","out_keys",":","One","key","identifying","the","output","tensors",".",":","param","in_shapes",":","List","of","input","shapes",".",":","param","hidden_features",":","List","containing","the","number","of","hidden","features","for","hidden","layers",".",":","param","non_lins",":","The","non-linearity\/ies","to","apply","after","each","layer","(","the","same","in","all","layers",",","or","a","list","corresponding","to","each","layer",")",".",":","param","n_heads",":","The","number","of","heads","each","stack","should","have",".","(","default","suggestion","8",")",":","param","attention_alpha",":","Specify","the","negative","slope","of","the","leakyReLU","in","each","of","the","attention","layers",".","parameter","with","init","value",":","param","node_self_importance",".","(","default","suggestion","0.2",")",":","param","avg_last_head_attentions",":","Specify","whether","to","average","the","outputs","from","the","attention","head","in","the","last","layer","of","the","attention","stack",".","(","default","suggestion","True","or","n_heads=0","in","the","last","layer",")",":","param","attention_dropout",":","Specify","the","dropout","to","be","within","the","layers","applied","on","the","computed","attention","."]
docstr: Compiles a block-specific dictionary of network layers.
  
  This could be overwritten by derived layers (e.g. to get a 'BatchNormalizedConvolutionBlock').
  
  :return: Ordered dictionary of torch modules [str, nn.Module].
docstr_tok: ["Compiles","a","block-specific","dictionary","of","network","layers",".","This","could","be","overwritten","by","derived","layers","(","e.g",".","to","get","a","'BatchNormalizedConvolutionBlock","'",")",".",":","return",":","Ordered","dictionary","of","torch","modules","[","str",",","nn.Module","]","."]
code: def build_layer_dict(self) -> OrderedDict:
      """Compiles a block-specific dictionary of network layers.
  
      This could be overwritten by derived layers (e.g. to get a 'BatchNormalizedConvolutionBlock').
  
      :return: Ordered dictionary of torch modules [str, nn.Module].
      """
      layer_dict = OrderedDict()
      # treat first layer
      layer_dict[f"gat_00"] = GraphMultiHeadAttentionLayer(
          in_features=self.input_features,
          out_features=self.hidden_features[0],
          alpha=self.attention_alpha[0],
          n_heads=self.n_heads[0],
          dropout=self.attention_dropout[0],
          avg_out=self.avg_last_head_attentions
          and len(self.hidden_features) == 1,
      )
      layer_dict[f"{self.non_lins[0].__name__}_00"] = self.non_lins[0]()
  
      # treat remaining layers
      for i, h in enumerate(self.hidden_features[1:], start=1):
          # Mulit-head attention
          layer_dict[f"gat_{i}0"] = GraphMultiHeadAttentionLayer(
              in_features=self.hidden_features[i - 1]
              * self.n_heads[i - 1],
              out_features=self.hidden_features[i],
              alpha=self.attention_alpha[i],
              n_heads=self.n_heads[i],
              dropout=self.attention_dropout[i],
              avg_out=self.avg_last_head_attentions
              and i == len(self.hidden_features) - 1,
          )
          # Non-lin
          layer_dict[
              f"{self.non_lins[i].__name__}_{i}0"
          ] = self.non_lins[i]()
  
      return layer_dict
  
imports: from collections import OrderedDict
  from typing import Union, List, Sequence, Dict
  import numpy
  import torch
  import torch.nn.functional
  from torch import nn
  from maze.core.annotations import override
  from maze.core.utils.factory import Factory
  from maze.perception.blocks.feed_forward.graph_conv import GraphAdjacencyMethods
  from maze.perception.blocks.shape_normalization import ShapeNormalizationBlock
label_desc: Use image node_id 3 for calling the GraphAttentionBlock obj's underlying member method code with example usage: obj.build_layer_dict() and returns: layer_dict