class_docstr: The PGExplainer model from the `"Parameterized Explainer for Graph
  Neural Network" <https://arxiv.org/abs/2011.04573>`_ paper.
  
  Internally, it utilizes a neural network to identify subgraph structures
  that play a crucial role in the predictions made by a GNN.
  Importantly, the :class:`PGExplainer` needs to be trained via
  :meth:`~PGExplainer.train` before being able to generate explanations:
  
  .. code-block:: python
  
      explainer = Explainer(
          model=model,
          algorithm=PGExplainer(epochs=30, lr=0.003),
          explanation_type='phenomenon',
          edge_mask_type='object',
          model_config=ModelConfig(...),
      )
  
      # Train against a variety of node-level or graph-level predictions:
      for epoch in range(30):
          for index in [...]:  # Indices to train against.
              loss = explainer.algorithm.train(epoch, model, x, edge_index,
                                               target=target, index=index)
  
      # Get the final explanations:
      explanation = explainer(x, edge_index, target=target, index=0)
  
  Args:
      epochs (int): The number of epochs to train.
      lr (float, optional): The learning rate to apply.
          (default: :obj:`0.003`).
      **kwargs (optional): Additional hyper-parameters to override default
          settings in
          :attr:`~torch_geometric.explain.algorithm.PGExplainer.coeffs`.
code: def forward(
      self,
      model: torch.nn.Module,
      x: Tensor,
      edge_index: Tensor,
      *,
      target: Tensor,
      index: Optional[Union[int, Tensor]] = None,
      **kwargs,
  ) -> Explanation:
      if isinstance(x, dict) or isinstance(edge_index, dict):
          raise ValueError(
              f"Heterogeneous graphs not yet supported in "
              f"'{self.__class__.__name__}'"
          )
  
      if self._curr_epoch < self.epochs - 1:  # Safety check:
          raise ValueError(
              f"'{self.__class__.__name__}' is not yet fully "
              f"trained (got {self._curr_epoch + 1} epochs "
              f"from {self.epochs} epochs). Please first train "
              f"the underlying explainer model by running "
              f"`explainer.algorithm.train(...)`."
          )
  
      hard_edge_mask = None
      if self.model_config.task_level == ModelTaskLevel.node:
          if index is None:
              raise ValueError(
                  f"The 'index' argument needs to be provided "
                  f"in '{self.__class__.__name__}' for "
                  f"node-level explanations"
              )
          if isinstance(index, Tensor) and index.numel() > 1:
              raise ValueError(
                  f"Only scalars are supported for the 'index' "
                  f"argument in '{self.__class__.__name__}'"
              )
  
          # We need to compute hard masks to properly clean up edges and
          # nodes attributions not involved during message passing:
          _, hard_edge_mask = self._get_hard_masks(
              model, index, edge_index, num_nodes=x.size(0)
          )
  
      z = get_embeddings(model, x, edge_index, **kwargs)[-1]
  
      inputs = self._get_inputs(z, edge_index, index)
      logits = self.mlp(inputs).view(-1)
  
      edge_mask = self._post_process_mask(
          logits, hard_edge_mask, apply_sigmoid=True
      )
  
      return Explanation(edge_mask=edge_mask)
  
imports: import logging
  from typing import Optional, Union
  import torch
  from torch import Tensor
  from torch.nn import ReLU, Sequential
  from torch_geometric.explain import Explanation
  from torch_geometric.explain.algorithm import ExplainerAlgorithm
  from torch_geometric.explain.algorithm.utils import clear_masks, set_masks
  from torch_geometric.explain.config import ExplanationType, ModelMode, ModelTaskLevel
  from torch_geometric.nn import Linear
  from torch_geometric.nn.inits import reset
  from torch_geometric.utils import get_embeddings
label_desc: Use image node_id 4 for calling the PGExplainer obj's underlying member method code with example usage: obj.forward(model, x, edge_index) and returns: Explanation