class_docstr: The GNN-Explainer model from the `"GNNExplainer: Generating
  Explanations for Graph Neural Networks"
  <https://arxiv.org/abs/1903.03894>`_ paper for identifying compact subgraph
  structures and node features that play a crucial role in the predictions
  made by a GNN.
  
  .. note::
  
      For an example of using :class:`GNNExplainer`, see
      `examples/explain/gnn_explainer.py <https://github.com/pyg-team/
      pytorch_geometric/blob/master/examples/explain/gnn_explainer.py>`_,
      `examples/explain/gnn_explainer_ba_shapes.py <https://github.com/
      pyg-team/pytorch_geometric/blob/master/examples/
      explain/gnn_explainer_ba_shapes.py>`_, and `examples/explain/
      gnn_explainer_link_pred.py <https://github.com/pyg-team/
      pytorch_geometric/blob/master/examples/explain/gnn_explainer_link_pred.py>`_.
  
  .. note::
  
      The :obj:`edge_size` coefficient is multiplied by the number of nodes
      in the explanation at every iteration, and the resulting value is added
      to the loss as a regularization term, with the goal of producing
      compact explanations.
      A higher value will push the algorithm towards explanations with less
      elements.
      Consider adjusting the :obj:`edge_size` coefficient according to the
      average node degree in the dataset, especially if this value is bigger
      than in the datasets used in the original paper.
  
  Args:
      epochs (int, optional): The number of epochs to train.
          (default: :obj:`100`)
      lr (float, optional): The learning rate to apply.
          (default: :obj:`0.01`)
      **kwargs (optional): Additional hyper-parameters to override default
          settings in
          :attr:`~torch_geometric.explain.algorithm.GNNExplainer.coeffs`.
code: def _train(
      self,
      model: torch.nn.Module,
      x: Tensor,
      edge_index: Tensor,
      *,
      target: Tensor,
      index: Optional[Union[int, Tensor]] = None,
      **kwargs,
  ):
      self._initialize_masks(x, edge_index)
  
      parameters = []
      if self.node_mask is not None:
          parameters.append(self.node_mask)
      if self.edge_mask is not None:
          set_masks(
              model, self.edge_mask, edge_index, apply_sigmoid=True
          )
          parameters.append(self.edge_mask)
  
      optimizer = torch.optim.Adam(parameters, lr=self.lr)
  
      for i in range(self.epochs):
          optimizer.zero_grad()
  
          h = (
              x
              if self.node_mask is None
              else x * self.node_mask.sigmoid()
          )
          y_hat, y = model(h, edge_index, **kwargs), target
  
          if index is not None:
              y_hat, y = y_hat[index], y[index]
  
          loss = self._loss(y_hat, y)
  
          loss.backward()
          optimizer.step()
  
          # In the first iteration, we collect the nodes and edges that are
          # involved into making the prediction. These are all the nodes and
          # edges with gradient != 0 (without regularization applied).
          if i == 0 and self.node_mask is not None:
              if self.node_mask.grad is None:
                  raise ValueError(
                      "Could not compute gradients for node "
                      "features. Please make sure that node "
                      "features are used inside the model or "
                      "disable it via `node_mask_type=None`."
                  )
              self.hard_node_mask = self.node_mask.grad != 0.0
          if i == 0 and self.edge_mask is not None:
              if self.edge_mask.grad is None:
                  raise ValueError(
                      "Could not compute gradients for edges. "
                      "Please make sure that edges are used "
                      "via message passing inside the model or "
                      "disable it via `edge_mask_type=None`."
                  )
              self.hard_edge_mask = self.edge_mask.grad != 0.0
  
imports: from math import sqrt
  from typing import Optional, Tuple, Union
  import torch
  from torch import Tensor
  from torch.nn.parameter import Parameter
  from torch_geometric.explain import ExplainerConfig, Explanation, ModelConfig
  from torch_geometric.explain.algorithm import ExplainerAlgorithm
  from torch_geometric.explain.algorithm.utils import clear_masks, set_masks
  from torch_geometric.explain.config import MaskType, ModelMode, ModelTaskLevel
label_desc: Use image node_id 4 for calling the GNNExplainer obj's underlying member method code with example usage: obj._train(model, x, edge_index) without return types