class_docstr: A block containing multiple subsequent graph convolution stacks.
  
  One convolution stack consists of one graph convolution 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 bias: Specify if a bias should be used at each layer (can be list or single).
  :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 node_self_importance: Specify how important a given node is to itself (default should be 1).
  :param trainable_node_self_importance: Specify if the node_self_importance should be a constant or a trainable
      parameter with init value :param node_self_importance.
  :param preprocess_adj: Specify whether to preprocess the adjacency, that is compute:
      adj^ := D^bar^(-1/2) A^bar D^bar^(-1/2) in every forward pass for the whole bach. If this is set to false, the
      already normalized adj^ is expected as an input. Here A^bar := A + I_n * :param self_importance_scalar, and
      D^bar_ii := sum_j A^bar_ij.
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["gcn_00"] = GraphConvLayer(
          in_features=self.input_features,
          out_features=self.hidden_features[0],
          bias=self.bias[0],
      )
      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):
          layer_dict[f"conv_{i}0"] = GraphConvLayer(
              in_features=self.hidden_features[i - 1],
              out_features=self.hidden_features[i],
              bias=self.bias[i],
          )
          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, Optional, Callable
  import numpy
  import torch
  from torch import nn
  from torch.nn.parameter import Parameter
  from maze.core.annotations import override
  from maze.core.utils.factory import Factory
  from maze.perception.blocks.shape_normalization import ShapeNormalizationBlock
label_desc: Use image node_id 3 for calling the GraphConvBlock obj's underlying member method code with example usage: obj.build_layer_dict() and returns: layer_dict