class_docstr: The GraphSAGE operator from the `"Inductive Representation Learning on
  Large Graphs" <https://arxiv.org/abs/1706.02216>`_ paper.
  
  .. math::
      \mathbf{x}^{\prime}_i = \mathbf{W}_1 \mathbf{x}_i + \mathbf{W}_2 \cdot
      \mathrm{mean}_{j \in \mathcal{N(i)}} \mathbf{x}_j
  
  If :obj:`project = True`, then :math:`\mathbf{x}_j` will first get
  projected via
  
  .. math::
      \mathbf{x}_j \leftarrow \sigma ( \mathbf{W}_3 \mathbf{x}_j +
      \mathbf{b})
  
  as described in Eq. (3) of the paper.
  
  Args:
      in_channels (int or tuple): Size of each input sample, or :obj:`-1` to
          derive the size from the first input(s) to the forward method.
          A tuple corresponds to the sizes of source and target
          dimensionalities.
      out_channels (int): Size of each output sample.
      aggr (str or Aggregation, optional): The aggregation scheme to use.
          Any aggregation of :obj:`torch_geometric.nn.aggr` can be used,
          *e.g.*, :obj:`"mean"`, :obj:`"max"`, or :obj:`"lstm"`.
          (default: :obj:`"mean"`)
      normalize (bool, optional): If set to :obj:`True`, output features
          will be :math:`\ell_2`-normalized, *i.e.*,
          :math:`\frac{\mathbf{x}^{\prime}_i}
          {\| \mathbf{x}^{\prime}_i \|_2}`.
          (default: :obj:`False`)
      root_weight (bool, optional): If set to :obj:`False`, the layer will
          not add transformed root node features to the output.
          (default: :obj:`True`)
      project (bool, optional): If set to :obj:`True`, the layer will apply a
          linear transformation followed by an activation function before
          aggregation (as described in Eq. (3) of the paper).
          (default: :obj:`False`)
      bias (bool, optional): If set to :obj:`False`, the layer will not learn
          an additive bias. (default: :obj:`True`)
      **kwargs (optional): Additional arguments of
          :class:`torch_geometric.nn.conv.MessagePassing`.
  
  Shapes:
      - **inputs:**
        node features :math:`(|\mathcal{V}|, F_{in})` or
        :math:`((|\mathcal{V_s}|, F_{s}), (|\mathcal{V_t}|, F_{t}))`
        if bipartite,
        edge indices :math:`(2, |\mathcal{E}|)`
      - **outputs:** node features :math:`(|\mathcal{V}|, F_{out})` or
        :math:`(|\mathcal{V_t}|, F_{out})` if bipartite
code: def message_and_aggregate(
      self, adj_t: Adj, x: OptPairTensor
  ) -> Tensor:
      if isinstance(adj_t, SparseTensor):
          adj_t = adj_t.set_value(None, layout=None)
      return spmm(adj_t, x[0], reduce=self.aggr)
  
file_path: pytorch_geometric/torch_geometric/nn/conv/sage_conv.py
imports: from typing import List, Optional, Tuple, Union
  import torch.nn.functional
  from torch import Tensor
  from torch_geometric.nn.aggr import Aggregation, MultiAggregation
  from torch_geometric.nn.conv import MessagePassing
  from torch_geometric.nn.dense.linear import Linear
  from torch_geometric.typing import Adj, OptPairTensor, Size, SparseTensor
  from torch_geometric.utils import spmm
label_desc: Use image node_id 5 for calling the SAGEConv obj's underlying member method code with example usage: obj.message_and_aggregate(adj_t, x) and returns: spmm