class_docstr: Computes the inner product between elements of a 2d Tensor:
  $$
      \langle \x, \x \rangle = \x\x^\top.
  $$
  
  **Mode**: single.
  
  **Input**
  
  - Tensor of shape `(n_nodes, n_features)`;
  
  **Output**
  
  - Tensor of shape `(n_nodes, n_nodes)`.
  
  :param trainable_kernel: add a trainable square matrix between the inner
  product (e.g., `X @ W @ X.T`);
  :param activation: activation function;
  :param kernel_initializer: initializer for the weights;
  :param kernel_regularizer: regularization applied to the kernel;
  :param kernel_constraint: constraint applied to the kernel;
code: def __init__(
      self,
      trainable_kernel=False,
      activation=None,
      kernel_initializer="glorot_uniform",
      kernel_regularizer=None,
      kernel_constraint=None,
      **kwargs,
  ):
      super().__init__(**kwargs)
      self.trainable_kernel = trainable_kernel
      self.activation = activations.get(activation)
      self.kernel_initializer = initializers.get(kernel_initializer)
      self.kernel_regularizer = regularizers.get(kernel_regularizer)
      self.kernel_constraint = constraints.get(kernel_constraint)
  
imports: import numpy
  import tensorflow
  from tensorflow.keras import activations
  from tensorflow.keras import backend
  from tensorflow.keras import constraints, initializers, regularizers
  from tensorflow.keras.layers import Layer
  from tensorflow.python.framework import smart_cond
  from spektral.layers import ops
label_desc: Use image node_id 1 to create a new InnerProduct object from inherited base classes: Layer with example: obj = InnerProduct(trainable_kernel, activation, kernel_initializer, kernel_regularizer, kernel_constraint)