class_docstr: An implementation of GradCAM on graph in
  `Grad-CAM: Visual Explanations from Deep Networks via Gradient-based Localization <https://arxiv.org/abs/1610.02391>`_.
  
  Args:
      model (torch.nn.Module): The target model prepared to explain.
      explain_graph (bool, optional): Whether to explain graph classification model.
          (default: :obj:`False`)
  
  .. note::
      For node classification model, the :attr:`explain_graph` flag is False.
      For an example, see `benchmarks/xgraph
      <https://github.com/divelab/DIG/tree/dig/benchmarks/xgraph>`_.
class_docstr_tok: ["An","implementation","of","GradCAM","on","graph","in","`","Grad-CAM",":","Visual","Explanations","from","Deep","Networks","via","Gradient-based","Localization","<","https",":","\/\/arxiv.org\/abs\/1610.02391",">","`","_",".","Args",":","model","(","torch.nn.Module",")",":","The","target","model","prepared","to","explain",".","explain_graph","(","bool",",","optional",")",":","Whether","to","explain","graph","classification","model",".","(","default",":",":","obj",":","`","False","`",")","..","note",":",":","For","node","classification","model",",","the",":","attr",":","`","explain_graph","`","flag","is","False",".","For","an","example",",","see","`","benchmarks\/xgraph","<","https",":","\/\/github.com\/divelab\/DIG\/tree\/dig\/benchmarks\/xgraph",">","`","_","."]
docstr: Run the explainer for a specific graph instance.
  
  Args:
      x (torch.Tensor): The graph instance's input node features.
      edge_index (torch.Tensor): The graph instance's edge index.
      **kwargs (dict):
          :obj:`node_idx` （int): The index of node that is pending to be explained.
          (for node classification)
          :obj:`sparsity` (float): The Sparsity we need to control to transform a
          soft mask to a hard mask. (Default: :obj:`0.7`)
          :obj:`num_classes` (int): The number of task's classes.
  
  :rtype: (None, list, list)
  
  .. note::
      (None, edge_masks, related_predictions):
      edge_masks is a list of edge-level explanation for each class;
      related_predictions is a list of dictionary for each class
      where each dictionary includes 4 type predicted probabilities.
docstr_tok: ["Run","the","explainer","for","a","specific","graph","instance",".","Args",":","x","(","torch.Tensor",")",":","The","graph","instance","'s","input","node","features",".","edge_index","(","torch.Tensor",")",":","The","graph","instance","'s","edge","index",".","*","*","kwargs","(","dict",")",":",":","obj",":","`","node_idx","`","\uff08int",")",":","The","index","of","node","that","is","pending","to","be","explained",".","(","for","node","classification",")",":","obj",":","`","sparsity","`","(","float",")",":","The","Sparsity","we","need","to","control","to","transform","a","soft","mask","to","a","hard","mask",".","(","Default",":",":","obj",":","`","0.7","`",")",":","obj",":","`","num_classes","`","(","int",")",":","The","number","of","task","'s","classes",".",":","rtype",":","(","None",",","list",",","list",")","..","note",":",":","(","None",",","edge_masks",",","related_predictions",")",":","edge_masks","is","a","list","of","edge-level","explanation","for","each","class",";","related_predictions","is","a","list","of","dictionary","for","each","class","where","each","dictionary","includes","4","type","predicted","probabilities","."]
code: def forward(
      self, x: Tensor, edge_index: Tensor, **kwargs
  ) -> Union[
      Tuple[None, List, List[Dict]], Tuple[List, List, List[Dict]]
  ]:
      r"""
      Run the explainer for a specific graph instance.
  
      Args:
          x (torch.Tensor): The graph instance's input node features.
          edge_index (torch.Tensor): The graph instance's edge index.
          **kwargs (dict):
              :obj:`node_idx` （int): The index of node that is pending to be explained.
              (for node classification)
              :obj:`sparsity` (float): The Sparsity we need to control to transform a
              soft mask to a hard mask. (Default: :obj:`0.7`)
              :obj:`num_classes` (int): The number of task's classes.
  
      :rtype: (None, list, list)
  
      .. note::
          (None, edge_masks, related_predictions):
          edge_masks is a list of edge-level explanation for each class;
          related_predictions is a list of dictionary for each class
          where each dictionary includes 4 type predicted probabilities.
  
      """
      self.model.eval()
      super().forward(x, edge_index)
  
      labels = tuple(i for i in range(kwargs.get("num_classes")))
      ex_labels = tuple(
          torch.tensor([label]).to(self.device) for label in labels
      )
  
      self_loop_edge_index, _ = add_remaining_self_loops(
          edge_index, num_nodes=self.num_nodes
      )
  
      if not self.explain_graph:
          node_idx = kwargs.get("node_idx")
          if isinstance(node_idx, int):
              node_idx = torch.tensor(
                  [node_idx], device=self.device, dtype=torch.long
              )
          if not node_idx.dim():
              node_idx = node_idx.reshape(-1)
          node_idx = node_idx.to(self.device)
          assert node_idx is not None
          self.subset, _, _, self.hard_edge_mask = subgraph(
              node_idx,
              self.__num_hops__,
              self_loop_edge_index,
              relabel_nodes=True,
              num_nodes=None,
              flow=self.__flow__(),
          )
          self.new_node_idx = torch.where(self.subset == node_idx)[0]
  
      if kwargs.get("edge_masks"):
          edge_masks = kwargs.pop("edge_masks")
          hard_edge_masks = [
              self.control_sparsity(
                  mask, kwargs.get("sparsity")
              ).sigmoid()
              for mask in edge_masks
          ]
      else:
          # --- setting GradCAM ---
          class model_node(nn.Module):
              def __init__(self, cls):
                  super().__init__()
                  self.cls = cls
                  self.convs = cls.model.convs
  
              def forward(self, *args, **kwargs):
                  return self.cls.model(*args, **kwargs)[node_idx]
  
          if self.explain_graph:
              model = self.model
          else:
              model = model_node(self)
          self.explain_method = GraphLayerGradCam(
              model, model.convs[-1]
          )
          # --- setting end ---
  
          edge_masks = []
          hard_edge_masks = []
          for ex_label in ex_labels:
              attr_wo_relu = self.explain_method.attribute(
                  x, ex_label, additional_forward_args=edge_index
              ).detach()
              mask = normalize(attr_wo_relu.relu())
              mask = mask.squeeze()
              mask = (
                  mask[self_loop_edge_index[0]]
                  + mask[self_loop_edge_index[1]]
              ) / 2
              edge_masks.append(mask.detach())
              mask = self.control_sparsity(mask, kwargs.get("sparsity"))
              mask = mask.sigmoid()
              hard_edge_masks.append(mask.detach())
  
      # Store related predictions for further evaluation.
      with torch.no_grad():
          with self.connect_mask(self):
              related_preds = self.eval_related_pred(
                  x, edge_index, hard_edge_masks, **kwargs
              )
  
      return edge_masks, hard_edge_masks, related_preds
  
imports: from typing import Any, Callable, List, Tuple, Union, Dict
  import captum.attr
  import torch
  import torch.nn
  import torch.nn.functional
  from captum.attr._utils.common import _format_additional_forward_args, _format_attributions, _format_input
  from captum.attr._utils.gradient import apply_gradient_requirements, compute_layer_gradients_and_eval, undo_gradient_requirements
  from captum.attr._utils.typing import TargetType
  from torch import Tensor
  from torch.nn import Module
  from torch_geometric.utils.loop import add_remaining_self_loops
  from .base_explainer import WalkBase
  from ..models.utils import subgraph, normalize
label_desc: Use image node_id 2 for calling the GradCAM obj's underlying member method code with example usage: obj.forward(x, edge_index) and returns: edge_masks,  hard_edge_masks,  related_preds, self