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`.
docstr: Trains the underlying explainer model.
  Needs to be called before being able to make predictions.
  
  Args:
      epoch (int): The current epoch of the training phase.
      model (torch.nn.Module): The model to explain.
      x (torch.Tensor): The input node features of a
          homogeneous graph.
      edge_index (torch.Tensor): The input edge indices of a homogeneous
          graph.
      target (torch.Tensor): The target of the model.
      index (int or torch.Tensor, optional): The index of the model
          output to explain. Needs to be a single index.
          (default: :obj:`None`)
      **kwargs (optional): Additional keyword arguments passed to
          :obj:`model`.
docstr_tok: ["Trains","the","underlying","explainer","model",".","Needs","to","be","called","before","being","able","to","make","predictions",".","Args",":","epoch","(","int",")",":","The","current","epoch","of","the","training","phase",".","model","(","torch.nn.Module",")",":","The","model","to","explain",".","x","(","torch.Tensor",")",":","The","input","node","features","of","a","homogeneous","graph",".","edge_index","(","torch.Tensor",")",":","The","input","edge","indices","of","a","homogeneous","graph",".","target","(","torch.Tensor",")",":","The","target","of","the","model",".","index","(","int","or","torch.Tensor",",","optional",")",":","The","index","of","the","model","output","to","explain",".","Needs","to","be","a","single","index",".","(","default",":",":","obj",":","`","None","`",")","*","*","kwargs","(","optional",")",":","Additional","keyword","arguments","passed","to",":","obj",":","`","model","`","."]
code: def train(
      self,
      epoch: int,
      model: torch.nn.Module,
      x: Tensor,
      edge_index: Tensor,
      *,
      target: Tensor,
      index: Optional[Union[int, Tensor]] = None,
      **kwargs,
  ):
      r"""Trains the underlying explainer model.
      Needs to be called before being able to make predictions.
  
      Args:
          epoch (int): The current epoch of the training phase.
          model (torch.nn.Module): The model to explain.
          x (torch.Tensor): The input node features of a
              homogeneous graph.
          edge_index (torch.Tensor): The input edge indices of a homogeneous
              graph.
          target (torch.Tensor): The target of the model.
          index (int or torch.Tensor, optional): The index of the model
              output to explain. Needs to be a single index.
              (default: :obj:`None`)
          **kwargs (optional): Additional keyword arguments passed to
              :obj:`model`.
      """
      if isinstance(x, dict) or isinstance(edge_index, dict):
          raise ValueError(
              f"Heterogeneous graphs not yet supported in "
              f"'{self.__class__.__name__}'"
          )
  
      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__}'"
              )
  
      z = get_embeddings(model, x, edge_index, **kwargs)[-1]
  
      self.optimizer.zero_grad()
      temperature = self._get_temperature(epoch)
  
      inputs = self._get_inputs(z, edge_index, index)
      logits = self.mlp(inputs).view(-1)
      edge_mask = self._concrete_sample(logits, temperature)
      set_masks(model, edge_mask, edge_index, apply_sigmoid=True)
  
      if self.model_config.task_level == ModelTaskLevel.node:
          _, hard_edge_mask = self._get_hard_masks(
              model, index, edge_index, num_nodes=x.size(0)
          )
          edge_mask = edge_mask[hard_edge_mask]
  
      y_hat, y = model(x, edge_index, **kwargs), target
  
      if index is not None:
          y_hat, y = y_hat[index], y[index]
  
      loss = self._loss(y_hat, y, edge_mask)
      loss.backward()
      self.optimizer.step()
  
      clear_masks(model)
      self._curr_epoch = epoch
  
      return float(loss)
  
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 3 for calling the PGExplainer obj's underlying member method code with example usage: obj.train(epoch, model, x, edge_index) and returns: float