class_docstr: A stack of Graph Convolutional layers that implement a graph convolution network model
  as in https://arxiv.org/abs/1609.02907
  
  The model minimally requires specification of the layer sizes as a list of int
  corresponding to the feature dimensions for each hidden layer,
  activation functions for each hidden layers, and a generator object.
  
  To use this class as a Keras model, the features and preprocessed adjacency matrix
  should be supplied using:
  
  - the :class:`.FullBatchNodeGenerator` class for node inference
  - the :class:`.ClusterNodeGenerator` class for scalable/inductive node inference using the Cluster-GCN training procedure (https://arxiv.org/abs/1905.07953)
  - the :class:`.FullBatchLinkGenerator` class for link inference
  
  To have the appropriate preprocessing the generator object should be instantiated
  with the ``method='gcn'`` argument.
  
  Note that currently the GCN class is compatible with both sparse and dense adjacency
  matrices and the :class:`.FullBatchNodeGenerator` will default to sparse.
  
  Example:
      Creating a GCN node classification model from an existing :class:`.StellarGraph`
      object ``G``::
  
          generator = FullBatchNodeGenerator(G, method="gcn")
          gcn = GCN(
                  layer_sizes=[32, 4],
                  activations=["elu","softmax"],
                  generator=generator,
                  dropout=0.5
              )
          x_inp, predictions = gcn.in_out_tensors()
  
  Notes:
    - The inputs are tensors with a batch dimension of 1. These are provided by the         :class:`.FullBatchNodeGenerator` object.
  
    - This assumes that the normalized Laplacian matrix is provided as input to
      Keras methods. When using the :class:`.FullBatchNodeGenerator` specify the
      ``method='gcn'`` argument to do this preprocessing.
  
    - The nodes provided to the :meth:`.FullBatchNodeGenerator.flow` method are
      used by the final layer to select the predictions for those nodes in order.
      However, the intermediate layers before the final layer order the nodes
      in the same way as the adjacency matrix.
  
  .. seealso::
  
     Examples using GCN:
  
     - `node classification <https://stellargraph.readthedocs.io/en/stable/demos/node-classification/gcn-node-classification.html>`__
     - `node classification trained with Cluster-GCN <https://stellargraph.readthedocs.io/en/stable/demos/node-classification/cluster-gcn-node-classification.html>`__
     - `node classification with Neo4j and Cluster-GCN <https://stellargraph.readthedocs.io/en/stable/demos/connector/neo4j/cluster-gcn-on-cora-neo4j-example.html>`__
     - `semi-supervised node classification <https://stellargraph.readthedocs.io/en/stable/demos/node-classification/gcn-deep-graph-infomax-fine-tuning-node-classification.html>`__
     - `link prediction <https://stellargraph.readthedocs.io/en/stable/demos/link-prediction/gcn-link-prediction.html>`__
     - `unsupervised representation learning with Deep Graph Infomax <https://stellargraph.readthedocs.io/en/stable/demos/embeddings/deep-graph-infomax-embeddings.html>`__
     - interpreting GCN predictions: `dense <https://stellargraph.readthedocs.io/en/stable/demos/interpretability/gcn-node-link-importance.html>`__, `sparse <https://stellargraph.readthedocs.io/en/stable/demos/interpretability/gcn-sparse-node-link-importance.html>`__
     - `ensemble model for node classification <https://stellargraph.readthedocs.io/en/stable/demos/ensembles/ensemble-node-classification-example.html>`__
     - `comparison of link prediction algorithms <https://stellargraph.readthedocs.io/en/stable/demos/link-prediction/homogeneous-comparison-link-prediction.html>`__
  
     Appropriate data generators: :class:`.FullBatchNodeGenerator`, :class:`.FullBatchLinkGenerator`, :class:`.ClusterNodeGenerator`.
  
     Related models:
  
     - Other full-batch models: see the documentation of :class:`.FullBatchNodeGenerator` for a full list
     - :class:`.RGCN` for a generalisation to multiple edge types
     - :class:`.GCNSupervisedGraphClassification` for graph classification by pooling the output of GCN
     - :class:`.GCN_LSTM` for time-series and sequence prediction, incorporating the graph structure via GCN
     - :class:`.DeepGraphInfomax` for unsupervised training
  
     :class:`.GraphConvolution` is the base layer out of which a GCN model is built.
  
  Args:
      layer_sizes (list of int): Output sizes of GCN layers in the stack.
      generator (FullBatchNodeGenerator): The generator instance.
      bias (bool): If True, a bias vector is learnt for each layer in the GCN model.
      dropout (float): Dropout rate applied to input features of each GCN layer.
      activations (list of str or func): Activations applied to each layer's output;
          defaults to ``['relu', ..., 'relu']``.
      kernel_initializer (str or func, optional): The initialiser to use for the weights of each layer.
      kernel_regularizer (str or func, optional): The regulariser to use for the weights of each layer.
      kernel_constraint (str or func, optional): The constraint to use for the weights of each layer.
      bias_initializer (str or func, optional): The initialiser to use for the bias of each layer.
      bias_regularizer (str or func, optional): The regulariser to use for the bias of each layer.
      bias_constraint (str or func, optional): The constraint to use for the bias of each layer.
      squeeze_output_batch (bool, optional): if True, remove the batch dimension when the batch size is 1. If False, leave the batch dimension.
class_docstr_tok: ["A","stack","of","Graph","Convolutional","layers","that","implement","a","graph","convolution","network","model","as","in","https",":","\/\/arxiv.org\/abs\/1609.02907","The","model","minimally","requires","specification","of","the","layer","sizes","as","a","list","of","int","corresponding","to","the","feature","dimensions","for","each","hidden","layer",",","activation","functions","for","each","hidden","layers",",","and","a","generator","object",".","To","use","this","class","as","a","Keras","model",",","the","features","and","preprocessed","adjacency","matrix","should","be","supplied","using",":","-","the",":","class",":","`",".FullBatchNodeGenerator","`","class","for","node","inference","-","the",":","class",":","`",".ClusterNodeGenerator","`","class","for","scalable\/inductive","node","inference","using","the","Cluster-GCN","training","procedure","(","https",":","\/\/arxiv.org\/abs\/1905.07953",")","-","the",":","class",":","`",".FullBatchLinkGenerator","`","class","for","link","inference","To","have","the","appropriate","preprocessing","the","generator","object","should","be","instantiated","with","the","``","method='gcn","'","``","argument",".","Note","that","currently","the","GCN","class","is","compatible","with","both","sparse","and","dense","adjacency","matrices","and","the",":","class",":","`",".FullBatchNodeGenerator","`","will","default","to","sparse",".","Example",":","Creating","a","GCN","node","classification","model","from","an","existing",":","class",":","`",".StellarGraph","`","object","``","G","``",":",":","generator","=","FullBatchNodeGenerator","(","G",",","method=","''","gcn","''",")","gcn","=","GCN","(","layer_sizes=","[","32",",","4","]",",","activations=","[","``","elu","''",",","''","softmax","''","]",",","generator=generator",",","dropout=0.5",")","x_inp",",","predictions","=","gcn.in_out_tensors","(",")","Notes",":","-","The","inputs","are","tensors","with","a","batch","dimension","of","1",".","These","are","provided","by","the",":","class",":","`",".FullBatchNodeGenerator","`","object",".","-","This","assumes","that","the","normalized","Laplacian","matrix","is","provided","as","input","to","Keras","methods",".","When","using","the",":","class",":","`",".FullBatchNodeGenerator","`","specify","the","``","method='gcn","'","``","argument","to","do","this","preprocessing",".","-","The","nodes","provided","to","the",":","meth",":","`",".FullBatchNodeGenerator.flow","`","method","are","used","by","the","final","layer","to","select","the","predictions","for","those","nodes","in","order",".","However",",","the","intermediate","layers","before","the","final","layer","order","the","nodes","in","the","same","way","as","the","adjacency","matrix",".","..","seealso",":",":","Examples","using","GCN",":","-","`","node","classification","<","https",":","\/\/stellargraph.readthedocs.io\/en\/stable\/demos\/node-classification\/gcn-node-classification.html",">","`","__","-","`","node","classification","trained","with","Cluster-GCN","<","https",":","\/\/stellargraph.readthedocs.io\/en\/stable\/demos\/node-classification\/cluster-gcn-node-classification.html",">","`","__","-","`","node","classification","with","Neo4j","and","Cluster-GCN","<","https",":","\/\/stellargraph.readthedocs.io\/en\/stable\/demos\/connector\/neo4j\/cluster-gcn-on-cora-neo4j-example.html",">","`","__","-","`","semi-supervised","node","classification","<","https",":","\/\/stellargraph.readthedocs.io\/en\/stable\/demos\/node-classification\/gcn-deep-graph-infomax-fine-tuning-node-classification.html",">","`","__","-","`","link","prediction","<","https",":","\/\/stellargraph.readthedocs.io\/en\/stable\/demos\/link-prediction\/gcn-link-prediction.html",">","`","__","-","`","unsupervised","representation","learning","with","Deep","Graph","Infomax","<","https",":","\/\/stellargraph.readthedocs.io\/en\/stable\/demos\/embeddings\/deep-graph-infomax-embeddings.html",">","`","__","-","interpreting","GCN","predictions",":","`","dense","<","https",":","\/\/stellargraph.readthedocs.io\/en\/stable\/demos\/interpretability\/gcn-node-link-importance.html",">","`","__",",","`","sparse","<","https",":","\/\/stellargraph.readthedocs.io\/en\/stable\/demos\/interpretability\/gcn-sparse-node-link-importance.html",">","`","__","-","`","ensemble","model","for","node","classification","<","https",":","\/\/stellargraph.readthedocs.io\/en\/stable\/demos\/ensembles\/ensemble-node-classification-example.html",">","`","__","-","`","comparison","of","link","prediction","algorithms","<","https",":","\/\/stellargraph.readthedocs.io\/en\/stable\/demos\/link-prediction\/homogeneous-comparison-link-prediction.html",">","`","__","Appropriate","data","generators",":",":","class",":","`",".FullBatchNodeGenerator","`",",",":","class",":","`",".FullBatchLinkGenerator","`",",",":","class",":","`",".ClusterNodeGenerator","`",".","Related","models",":","-","Other","full-batch","models",":","see","the","documentation","of",":","class",":","`",".FullBatchNodeGenerator","`","for","a","full","list","-",":","class",":","`",".RGCN","`","for","a","generalisation","to","multiple","edge","types","-",":","class",":","`",".GCNSupervisedGraphClassification","`","for","graph","classification","by","pooling","the","output","of","GCN","-",":","class",":","`",".GCN_LSTM","`","for","time-series","and","sequence","prediction",",","incorporating","the","graph","structure","via","GCN","-",":","class",":","`",".DeepGraphInfomax","`","for","unsupervised","training",":","class",":","`",".GraphConvolution","`","is","the","base","layer","out","of","which","a","GCN","model","is","built",".","Args",":","layer_sizes","(","list","of","int",")",":","Output","sizes","of","GCN","layers","in","the","stack",".","generator","(","FullBatchNodeGenerator",")",":","The","generator","instance",".","bias","(","bool",")",":","If","True",",","a","bias","vector","is","learnt","for","each","layer","in","the","GCN","model",".","dropout","(","float",")",":","Dropout","rate","applied","to","input","features","of","each","GCN","layer",".","activations","(","list","of","str","or","func",")",":","Activations","applied","to","each","layer","'s","output",";","defaults","to","``","[","'relu","'",",","...",",","'relu","'","]","``",".","kernel_initializer","(","str","or","func",",","optional",")",":","The","initialiser","to","use","for","the","weights","of","each","layer",".","kernel_regularizer","(","str","or","func",",","optional",")",":","The","regulariser","to","use","for","the","weights","of","each","layer",".","kernel_constraint","(","str","or","func",",","optional",")",":","The","constraint","to","use","for","the","weights","of","each","layer",".","bias_initializer","(","str","or","func",",","optional",")",":","The","initialiser","to","use","for","the","bias","of","each","layer",".","bias_regularizer","(","str","or","func",",","optional",")",":","The","regulariser","to","use","for","the","bias","of","each","layer",".","bias_constraint","(","str","or","func",",","optional",")",":","The","constraint","to","use","for","the","bias","of","each","layer",".","squeeze_output_batch","(","bool",",","optional",")",":","if","True",",","remove","the","batch","dimension","when","the","batch","size","is","1",".","If","False",",","leave","the","batch","dimension","."]
code: def __init__(
      self,
      layer_sizes,
      generator,
      bias=True,
      dropout=0.0,
      activations=None,
      kernel_initializer="glorot_uniform",
      kernel_regularizer=None,
      kernel_constraint=None,
      bias_initializer="zeros",
      bias_regularizer=None,
      bias_constraint=None,
      squeeze_output_batch=True,
  ):
      if not isinstance(
          generator, (FullBatchGenerator, ClusterNodeGenerator)
      ):
          raise TypeError(
              f"Generator should be a instance of FullBatchNodeGenerator, "
              f"FullBatchLinkGenerator or ClusterNodeGenerator"
          )
  
      n_layers = len(layer_sizes)
      self.layer_sizes = layer_sizes
      self.activations = activations
      self.bias = bias
      self.dropout = dropout
      self.squeeze_output_batch = squeeze_output_batch
  
      # Copy required information from generator
      self.method = generator.method
      self.multiplicity = generator.multiplicity
      self.n_features = generator.features.shape[1]
      self.use_sparse = generator.use_sparse
      if isinstance(generator, FullBatchGenerator):
          self.n_nodes = generator.features.shape[0]
      else:
          self.n_nodes = None
  
      if self.method == "none":
          self.graph_norm_layer = GraphPreProcessingLayer(
              num_of_nodes=self.n_nodes
          )
  
      # Activation function for each layer
      if activations is None:
          activations = ["relu"] * n_layers
      elif len(activations) != n_layers:
          raise ValueError(
              "Invalid number of activations; require one function per layer"
          )
      self.activations = activations
  
      # Initialize a stack of GCN layers
      self._layers = []
      for ii in range(n_layers):
          self._layers.append(Dropout(self.dropout))
          self._layers.append(
              GraphConvolution(
                  self.layer_sizes[ii],
                  activation=self.activations[ii],
                  use_bias=self.bias,
                  kernel_initializer=kernel_initializer,
                  kernel_regularizer=kernel_regularizer,
                  kernel_constraint=kernel_constraint,
                  bias_initializer=bias_initializer,
                  bias_regularizer=bias_regularizer,
                  bias_constraint=bias_constraint,
              )
          )
  
imports: import warnings
  import tensorflow
  from tensorflow.keras import backend
  from tensorflow.keras import activations, initializers, constraints, regularizers
  from tensorflow.keras.layers import Input, Layer, Lambda, Dropout, Reshape
  from ..mapper import FullBatchGenerator, ClusterNodeGenerator
  from .misc import SqueezedSparseConversion, deprecated_model_function, GatherIndices
  from .preprocessing_layer import GraphPreProcessingLayer
label_desc: Use image node_id 1 to create a new GCN object  with example: obj = GCN(layer_sizes, generator, bias, dropout, activations, kernel_initializer, kernel_regularizer, kernel_constraint, bias_initializer, bias_regularizer, bias_constraint, squeeze_output_batch)