class_docstr: The approximate personalized propagation of neural predictions layer
  from the `"Predict then Propagate: Graph Neural Networks meet Personalized
  PageRank" <https://arxiv.org/abs/1810.05997>`_ paper.
  
  .. math::
      \mathbf{X}^{(0)} &= \mathbf{X}
  
      \mathbf{X}^{(k)} &= (1 - \alpha) \mathbf{\hat{D}}^{-1/2}
      \mathbf{\hat{A}} \mathbf{\hat{D}}^{-1/2} \mathbf{X}^{(k-1)} + \alpha
      \mathbf{X}^{(0)}
  
      \mathbf{X}^{\prime} &= \mathbf{X}^{(K)},
  
  where :math:`\mathbf{\hat{A}} = \mathbf{A} + \mathbf{I}` denotes the
  adjacency matrix with inserted self-loops and
  :math:`\hat{D}_{ii} = \sum_{j=0} \hat{A}_{ij}` its diagonal degree matrix.
  The adjacency matrix can include other values than :obj:`1` representing
  edge weights via the optional :obj:`edge_weight` tensor.
  
  Args:
      K (int): Number of iterations :math:`K`.
      alpha (float): Teleport probability :math:`\alpha`.
      dropout (float, optional): Dropout probability of edges during
          training. (default: :obj:`0`)
      cached (bool, optional): If set to :obj:`True`, the layer will cache
          the computation of :math:`\mathbf{\hat{D}}^{-1/2} \mathbf{\hat{A}}
          \mathbf{\hat{D}}^{-1/2}` on first execution, and will use the
          cached version for further executions.
          This parameter should only be set to :obj:`True` in transductive
          learning scenarios. (default: :obj:`False`)
      add_self_loops (bool, optional): If set to :obj:`False`, will not add
          self-loops to the input graph. (default: :obj:`True`)
      normalize (bool, optional): Whether to add self-loops and apply
          symmetric normalization. (default: :obj:`True`)
      **kwargs (optional): Additional arguments of
          :class:`torch_geometric.nn.conv.MessagePassing`.
  
  Shapes:
      - **input:**
        node features :math:`(|\mathcal{V}|, F)`,
        edge indices :math:`(2, |\mathcal{E}|)`,
        edge weights :math:`(|\mathcal{E}|)` *(optional)*
      - **output:** node features :math:`(|\mathcal{V}|, F)`
code: def __init__(
      self,
      K: int,
      alpha: float,
      dropout: float = 0.0,
      cached: bool = False,
      add_self_loops: bool = True,
      normalize: bool = True,
      **kwargs,
  ):
      kwargs.setdefault("aggr", "add")
      super().__init__(**kwargs)
      self.K = K
      self.alpha = alpha
      self.dropout = dropout
      self.cached = cached
      self.add_self_loops = add_self_loops
      self.normalize = normalize
  
      self._cached_edge_index = None
      self._cached_adj_t = None
  
file_path: pytorch_geometric/torch_geometric/nn/conv/appnp.py
imports: from typing import Optional
  import torch.nn.functional
  from torch import Tensor
  from torch_geometric.nn.conv import MessagePassing
  from torch_geometric.nn.conv.gcn_conv import gcn_norm
  from torch_geometric.typing import Adj, OptPairTensor, OptTensor, SparseTensor
  from torch_geometric.utils import is_torch_sparse_tensor, spmm, to_edge_index
  from torch_geometric.utils.sparse import set_sparse_value
label_desc: Use image node_id 1 to create a new APPNP object from inherited base classes: MessagePassing with example: obj = APPNP(K, alpha, dropout, cached, add__loops, normalize)