class_docstr: A graph total variation convolutional layer (GTVConv) from the paper
  
  > [Total Variation Graph Neural Networks](https://arxiv.org/abs/2211.06218)<br>
  > Jonas Berg Hansen and Filippo Maria Bianchi
  
  **Mode**: single, disjoint, batch.
  
  This layer computes
  $$
      \X' = \sigma\left[\left(\I - \delta\L_\hat{\mathbf{\Gamma}}\right) \tilde{\X} \right]
  $$
  where
  $$
      \begin{align}
          \tilde{\X} &= \X \W\\[5pt]
          \L_\hat{\mathbf{\Gamma}} &= \D_\mathbf{\hat{\Gamma}} - \hat{\mathbf{\Gamma}}\\[5pt]
          [\hat{\mathbf{\Gamma}}]_{ij} &= \frac{[\mathbf{A}]_{ij}}{\max\{||\tilde{\x}_i-\tilde{\x}_j||_1, \epsilon\}}\\
      \end{align}
  $$
  
  **Input**
  
  - Node features of shape `(batch, n_nodes, n_node_features)`;
  - Adjacency matrix of shape `(batch, n_nodes, n_nodes)`;
  
  **Output**
  
  - Node features with the same shape as the input, but with the last
  dimension changed to `channels`.
  
  **Arguments**
  
  - `channels`: number of output channels;
  - `delta_coeff`: step size for gradient descent of GTV
  - `epsilon`: small number used to numerically stabilize the computation of new adjacency weights
  - `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 __init__(
      self,
      channels,
      delta_coeff=1.0,
      epsilon=0.001,
      activation=None,
      use_bias=True,
      kernel_initializer="glorot_uniform",
      bias_initializer="zeros",
      kernel_regularizer=None,
      bias_regularizer=None,
      activity_regularizer=None,
      kernel_constraint=None,
      bias_constraint=None,
      **kwargs,
  ):
      super().__init__(
          activation=activation,
          use_bias=use_bias,
          kernel_initializer=kernel_initializer,
          bias_initializer=bias_initializer,
          kernel_regularizer=kernel_regularizer,
          bias_regularizer=bias_regularizer,
          activity_regularizer=activity_regularizer,
          kernel_constraint=kernel_constraint,
          bias_constraint=bias_constraint,
          **kwargs,
      )
  
      self.channels = channels
      self.delta_coeff = delta_coeff
      self.epsilon = epsilon
  
file_path: spektral/spektral/layers/convolutional/gtv_conv.py
imports: import tensorflow
  from tensorflow.keras import backend
  from spektral.layers import ops
  from spektral.layers.convolutional.conv import Conv
label_desc: Use image node_id 1 to create a new GTVConv object from inherited base classes: Conv with example: obj = GTVConv(channels, delta_coeff, epsilon, activation, use_bias, kernel_initializer, bias_initializer, kernel_regularizer, bias_regularizer, activity_regularizer, kernel_constraint, bias_constraint)