class_docstr: A Topology Adaptive Graph Convolutional layer (TAG) from the paper
  
  > [Topology Adaptive Graph Convolutional Networks](https://arxiv.org/abs/1710.10370)<br>
  > Jian Du et al.
  
  **Mode**: single, disjoint, mixed.
  
  **This layer expects a sparse adjacency matrix.**
  
  This layer computes:
  $$
      \Z = \sum\limits_{k=0}^{K} \D^{-1/2}\A^k\D^{-1/2}\X\W^{(k)}
  $$
  
  **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, but the last dimension
  changed to `channels`.
  
  **Arguments**
  
  - `channels`: integer, number of output channels;
  - `K`: the order of the layer (i.e., the layer will consider a K-hop
  neighbourhood for each node);
  - `activation`: activation function;
  - `use_bias`: bool, add a bias vector to the output;
  - `kernel_initializer`: initializer for the weights;
  - `bias_initializer`: initializer for the bias vector;
  - `kernel_regularizer`: regularization applied to the weights;
  - `bias_regularizer`: regularization applied to the bias vector;
  - `activity_regularizer`: regularization applied to the output;
  - `kernel_constraint`: constraint applied to the weights;
  - `bias_constraint`: constraint applied to the bias vector.
code: def build(self, input_shape):
      assert len(input_shape) >= 2
      self.built = True
  
file_path: spektral/spektral/layers/convolutional/tag_conv.py
imports: from tensorflow.keras import backend
  from tensorflow.keras.layers import Dense
  from spektral.layers.convolutional.message_passing import MessagePassing
  from spektral.utils import normalized_adjacency
label_desc: Use image node_id 2 for calling the TAGConv obj's underlying member method code with example usage: obj.build(input_shape) without return types