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 get_config(self):
      config = {
          "trainable_kernel": self.trainable_kernel,
          "activation": self.activation,
          "kernel_initializer": self.kernel_initializer,
          "kernel_regularizer": self.kernel_regularizer,
          "kernel_constraint": self.kernel_constraint,
      }
      base_config = super().get_config()
      return dict(list(base_config.items()) + list(config.items()))
  
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 4 for calling the InnerProduct obj's underlying member method code with example usage: obj.get_config() and returns: dict