class_docstr: A DiffPool layer from the paper
  
  > [Hierarchical Graph Representation Learning with Differentiable Pooling](https://arxiv.org/abs/1806.08804)<br>
  > Rex Ying et al.
  
  **Mode**: single, batch.
  
  This layer learns a soft clustering of the input graph as follows:
  $$
      \begin{align}
          \Z &= \textrm{GNN}_{embed}(\A, \X); \\
          \S &= \textrm{GNN}_{pool}(\A, \X); \\
          \X' &= \S^\top \Z; \\
          \A' &= \S^\top \A \S; \\
      \end{align}
  $$
  where:
  $$
      \textrm{GNN}_{\square}(\A, \X) = \D^{-1/2} \A \D^{-1/2} \X \W_{\square}.
  $$
  The number of output channels of \(\textrm{GNN}_{embed}\) is controlled by the
  `channels` parameter.
  
  Two auxiliary loss terms are also added to the model: the link prediction loss
  $$
      L_{LP} = \big\| \A - \S\S^\top \big\|_F
  $$
  and the entropy loss
  $$
      L_{E} - \frac{1}{N} \sum\limits_{i = 1}^{N} \S \log (\S).
  $$
  
  The layer can be used without a supervised loss to compute node clustering by
  minimizing the two auxiliary losses.
  
  **Input**
  
  - Node features of shape `(batch, n_nodes_in, n_node_features)`;
  - Adjacency matrix of shape `(batch, n_nodes_in, n_nodes_in)`;
  
  **Output**
  
  - Reduced node features of shape `(batch, n_nodes_out, channels)`;
  - Reduced adjacency matrix of shape `(batch, n_nodes_out, n_nodes_out)`;
  - If `return_selection=True`, the selection matrix of shape
  `(batch, n_nodes_in, n_nodes_out)`.
  
  **Arguments**
  
  - `k`: number of output nodes;
  - `channels`: number of output channels (if `None`, the number of output channels is
  the same as the input);
  - `return_selection`: boolean, whether to return the selection matrix;
  - `activation`: activation to apply after reduction;
  - `kernel_initializer`: initializer for the weights;
  - `kernel_regularizer`: regularization applied to the weights;
  - `kernel_constraint`: constraint applied to the weights;
class_docstr_tok: ["A","DiffPool","layer","from","the","paper",">","[","Hierarchical","Graph","Representation","Learning","with","Differentiable","Pooling","]","(","https",":","\/\/arxiv.org\/abs\/1806.08804",")","<","br",">",">","Rex","Ying","et","al",".","*","*","Mode","*","*",":","single",",","batch",".","This","layer","learns","a","soft","clustering","of","the","input","graph","as","follows",":","$","$","\\begin","{","align","}","\\Z","&","=","\\textrm","{","GNN","}","_","{","embed","}","(","\\A",",","\\X",")",";","\\\\","\\S","&","=","\\textrm","{","GNN","}","_","{","pool","}","(","\\A",",","\\X",")",";","\\\\","\\X","'","&","=","\\S^\\top","\\Z",";","\\\\","\\A","'","&","=","\\S^\\top","\\A","\\S",";","\\\\","\\end","{","align","}","$","$","where",":","$","$","\\textrm","{","GNN","}","_","{","\\square","}","(","\\A",",","\\X",")","=","\\D^","{","-1\/2","}","\\A","\\D^","{","-1\/2","}","\\X","\\W_","{","\\square","}",".","$","$","The","number","of","output","channels","of","\\","(","\\textrm","{","GNN","}","_","{","embed","}","\\",")","is","controlled","by","the","`","channels","`","parameter",".","Two","auxiliary","loss","terms","are","also","added","to","the","model",":","the","link","prediction","loss","$","$","L_","{","LP","}","=","\\big\\|","\\A","-","\\S\\S^\\top","\\big\\|_F","$","$","and","the","entropy","loss","$","$","L_","{","E","}","-","\\frac","{","1","}","{","N","}","\\sum\\limits_","{","i","=","1","}","^","{","N","}","\\S","\\log","(","\\S",")",".","$","$","The","layer","can","be","used","without","a","supervised","loss","to","compute","node","clustering","by","minimizing","the","two","auxiliary","losses",".","*","*","Input","*","*","-","Node","features","of","shape","`","(","batch",",","n_nodes_in",",","n_node_features",")","`",";","-","Adjacency","matrix","of","shape","`","(","batch",",","n_nodes_in",",","n_nodes_in",")","`",";","*","*","Output","*","*","-","Reduced","node","features","of","shape","`","(","batch",",","n_nodes_out",",","channels",")","`",";","-","Reduced","adjacency","matrix","of","shape","`","(","batch",",","n_nodes_out",",","n_nodes_out",")","`",";","-","If","`","return_selection=True","`",",","the","selection","matrix","of","shape","`","(","batch",",","n_nodes_in",",","n_nodes_out",")","`",".","*","*","Arguments","*","*","-","`","k","`",":","number","of","output","nodes",";","-","`","channels","`",":","number","of","output","channels","(","if","`","None","`",",","the","number","of","output","channels","is","the","same","as","the","input",")",";","-","`","return_selection","`",":","boolean",",","whether","to","return","the","selection","matrix",";","-","`","activation","`",":","activation","to","apply","after","reduction",";","-","`","kernel_initializer","`",":","initializer","for","the","weights",";","-","`","kernel_regularizer","`",":","regularization","applied","to","the","weights",";","-","`","kernel_constraint","`",":","constraint","applied","to","the","weights",";"]
code: def build(self, input_shape):
      in_channels = input_shape[0][-1]
      if self.channels is None:
          self.channels = in_channels
      self.kernel_emb = self.add_weight(
          shape=(in_channels, self.channels),
          name="kernel_emb",
          initializer=self.kernel_initializer,
          regularizer=self.kernel_regularizer,
          constraint=self.kernel_constraint,
      )
  
      self.kernel_pool = self.add_weight(
          shape=(in_channels, self.k),
          name="kernel_pool",
          initializer=self.kernel_initializer,
          regularizer=self.kernel_regularizer,
          constraint=self.kernel_constraint,
      )
      super().build(input_shape)
  
file_path: spektral/spektral/layers/pooling/diff_pool.py
imports: import tensorflow
  from tensorflow.keras import activations
  from tensorflow.keras import backend
  from spektral.layers import ops
  from spektral.layers.pooling.src import SRCPool
label_desc: Use image node_id 2 for calling the DiffPool obj's underlying member method code with example usage: obj.build(input_shape) without return types