class_docstr: The powermean aggregation operator based on a power term, as
  described in the `"DeeperGCN: All You Need to Train Deeper GCNs"
  <https://arxiv.org/abs/2006.07739>`_ paper.
  
  .. math::
      \mathrm{powermean}(\mathcal{X}|p) = \left(\frac{1}{|\mathcal{X}|}
      \sum_{\mathbf{x}_i\in\mathcal{X}}\mathbf{x}_i^{p}\right)^{1/p},
  
  where :math:`p` controls the power of the powermean when aggregating over
  a set of features :math:`\mathcal{X}`.
  
  Args:
      p (float, optional): Initial power for powermean aggregation.
          (default: :obj:`1.0`)
      learn (bool, optional): If set to :obj:`True`, will learn the value
          :obj:`p` for powermean aggregation dynamically.
          (default: :obj:`False`)
      channels (int, optional): Number of channels to learn from :math:`p`.
          If set to a value greater than :obj:`1`, :math:`p` will be learned
          per input feature channel. This requires compatible shapes for the
          input to the forward calculation. (default: :obj:`1`)
code: def __init__(
      self, p: float = 1.0, learn: bool = False, channels: int = 1
  ):
      super().__init__()
  
      if not learn and channels != 1:
          raise ValueError(
              f"Cannot set 'channels' greater than '1' in case "
              f"'{self.__class__.__name__}' is not trainable"
          )
  
      self._init_p = p
      self.learn = learn
      self.channels = channels
  
      self.p = Parameter(torch.empty(channels)) if learn else p
      self.reset_parameters()
  
imports: import math
  from typing import Optional
  import torch
  from torch import Tensor
  from torch.nn import Parameter
  from torch_geometric.nn.aggr import Aggregation
  from torch_geometric.utils import softmax
label_desc: Use image node_id 1 to create a new PowerMeanAggregation object from inherited base classes: Aggregation with example: obj = PowerMeanAggregation(p, learn, channels)