class_docstr: A GraphSAGE layer from the paper
  
  > [Inductive Representation Learning on Large Graphs](https://arxiv.org/abs/1706.02216)<br>
  > William L. Hamilton et al.
  
  **Mode**: single, disjoint, mixed.
  
  **This layer expects a sparse adjacency matrix.**
  
  This layer computes:
  $$
      \X' = \big[ \textrm{AGGREGATE}(\X) \| \X \big] \W + \b; \\
      \X' = \frac{\X'}{\|\X'\|}
  $$
  where \( \textrm{AGGREGATE} \) is a function to aggregate a node's
  neighbourhood. The supported aggregation methods are: sum, mean,
  max, min, and product.
  
  **Input**
  
  - Node features of shape `(n_nodes, n_node_features)`;
  - Binary adjacency matrix of shape `(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;
  - `aggregate_op`: str, aggregation method to use (`'sum'`, `'mean'`,
  `'max'`, `'min'`, `'prod'`);
  - `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 build(self, input_shape):
      assert len(input_shape) >= 2
      input_dim = input_shape[0][-1]
      self.kernel = self.add_weight(
          shape=(2 * input_dim, self.channels),
          initializer=self.kernel_initializer,
          name="kernel",
          regularizer=self.kernel_regularizer,
          constraint=self.kernel_constraint,
      )
      if self.use_bias:
          self.bias = self.add_weight(
              shape=(self.channels,),
              initializer=self.bias_initializer,
              name="bias",
              regularizer=self.bias_regularizer,
              constraint=self.bias_constraint,
          )
      self.built = True
  
file_path: spektral/spektral/layers/convolutional/graphsage_conv.py
imports: from tensorflow.keras import backend
  from spektral.layers import ops
  from spektral.layers.convolutional.message_passing import MessagePassing
label_desc: Use image node_id 2 for calling the GraphSageConv obj's underlying member method code with example usage: obj.build(input_shape) without return types