class_docstr: Utility layer calculating a single channel of the diffusional convolution.
  
  The procedure is based on [https://arxiv.org/abs/1707.01926](https://arxiv.org/abs/1707.01926)
  
  **Input**
  
  - Node features of shape `([batch], n_nodes, n_node_features)`;
  - Normalized adjacency or attention coef. matrix \(\hat \A \) of shape
  `([batch], n_nodes, n_nodes)`; Use DiffusionConvolution.preprocess to normalize.
  
  **Output**
  
  - Node features with the same shape as the input, but with the last
  dimension changed to \(1\).
  
  **Arguments**
  
  - `num_diffusion_steps`: How many diffusion steps to consider. \(K\) in paper.
  - `kernel_initializer`: initializer for the weights;
  - `kernel_regularizer`: regularization applied to the kernel vectors;
  - `kernel_constraint`: constraint applied to the kernel vectors;
class_docstr_tok: ["Utility","layer","calculating","a","single","channel","of","the","diffusional","convolution",".","The","procedure","is","based","on","[","https",":","\/\/arxiv.org\/abs\/1707.01926","]","(","https",":","\/\/arxiv.org\/abs\/1707.01926",")","*","*","Input","*","*","-","Node","features","of","shape","`","(","[","batch","]",",","n_nodes",",","n_node_features",")","`",";","-","Normalized","adjacency","or","attention","coef",".","matrix","\\","(","\\hat","\\A","\\",")","of","shape","`","(","[","batch","]",",","n_nodes",",","n_nodes",")","`",";","Use","DiffusionConvolution.preprocess","to","normalize",".","*","*","Output","*","*","-","Node","features","with","the","same","shape","as","the","input",",","but","with","the","last","dimension","changed","to","\\","(","1\\",")",".","*","*","Arguments","*","*","-","`","num_diffusion_steps","`",":","How","many","diffusion","steps","to","consider",".","\\","(","K\\",")","in","paper",".","-","`","kernel_initializer","`",":","initializer","for","the","weights",";","-","`","kernel_regularizer","`",":","regularization","applied","to","the","kernel","vectors",";","-","`","kernel_constraint","`",":","constraint","applied","to","the","kernel","vectors",";"]
code: def call(self, inputs):
      x, a = inputs
  
      # Calculate diffusion matrix: sum kernel_k * Attention_t^k
      # tf.polyval needs a list of tensors as the coeff. thus we
      # unstack kernel
      diffusion_matrix = tf.math.polyval(tf.unstack(self.kernel), a)
  
      # Apply it to X to get a matrix C = [C_1, ..., C_F] (n_nodes x n_node_features)
      # of diffused features
      diffused_features = tf.matmul(diffusion_matrix, x)
  
      # Now we add all diffused features (columns of the above matrix)
      # and apply a non linearity to obtain H:,q (eq. 3 in paper)
      H = tf.math.reduce_sum(diffused_features, axis=-1)
  
      # H has shape ([batch], n_nodes) but as it is the sum of columns
      # we reshape it to ([batch], n_nodes, 1)
      return tf.expand_dims(H, -1)
  
file_path: spektral/spektral/layers/convolutional/diffusion_conv.py
imports: import tensorflow
  import tensorflow.keras.layers
  from spektral.layers.convolutional.conv import Conv
  from spektral.utils import normalized_adjacency
label_desc: Use image node_id 3 for calling the DiffuseFeatures obj's underlying member method code with example usage: obj.call(inputs) and returns: tf