class_docstr: A perturbation based approach to compute attribution, based on the concept
  of Shapley Values from cooperative game theory. This method involves taking
  a random permutation of the input features and adding them one-by-one to the
  given baseline. The output difference after adding each feature corresponds
  to its attribution, and these difference are averaged when repeating this
  process n_samples times, each time choosing a new random permutation of
  the input features.
  
  By default, each scalar value within
  the input tensors are taken as a feature and added independently. Passing
  a feature mask, allows grouping features to be added together. This can
  be used in cases such as images, where an entire segment or region
  can be grouped together, measuring the importance of the segment
  (feature group). Each input scalar in the group will be given the same
  attribution value equal to the change in output as a result of adding back
  the entire feature group.
  
  More details regarding Shapley Value sampling can be found in these papers:
  https://www.sciencedirect.com/science/article/pii/S0305054808000804
  https://pdfs.semanticscholar.org/7715/bb1070691455d1fcfc6346ff458dbca77b2c.pdf
class_docstr_tok: ["A","perturbation","based","approach","to","compute","attribution",",","based","on","the","concept","of","Shapley","Values","from","cooperative","game","theory",".","This","method","involves","taking","a","random","permutation","of","the","input","features","and","adding","them","one-by-one","to","the","given","baseline",".","The","output","difference","after","adding","each","feature","corresponds","to","its","attribution",",","and","these","difference","are","averaged","when","repeating","this","process","n_samples","times",",","each","time","choosing","a","new","random","permutation","of","the","input","features",".","By","default",",","each","scalar","value","within","the","input","tensors","are","taken","as","a","feature","and","added","independently",".","Passing","a","feature","mask",",","allows","grouping","features","to","be","added","together",".","This","can","be","used","in","cases","such","as","images",",","where","an","entire","segment","or","region","can","be","grouped","together",",","measuring","the","importance","of","the","segment","(","feature","group",")",".","Each","input","scalar","in","the","group","will","be","given","the","same","attribution","value","equal","to","the","change","in","output","as","a","result","of","adding","back","the","entire","feature","group",".","More","details","regarding","Shapley","Value","sampling","can","be","found","in","these","papers",":","https",":","\/\/www.sciencedirect.com\/science\/article\/pii\/S0305054808000804","https",":","\/\/pdfs.semanticscholar.org\/7715\/bb1070691455d1fcfc6346ff458dbca77b2c.pdf"]
docstr: This method is a generator which yields each perturbation to be evaluated
  including inputs, additional_forward_args, targets, and mask.
docstr_tok: ["This","method","is","a","generator","which","yields","each","perturbation","to","be","evaluated","including","inputs",",","additional_forward_args",",","targets",",","and","mask","."]
code: def _perturbation_generator(
      self,
      inputs: Tuple[Tensor, ...],
      additional_args: Any,
      target: TargetType,
      baselines: Tuple[Tensor, ...],
      input_masks: TensorOrTupleOfTensorsGeneric,
      feature_permutation: Sequence[int],
      perturbations_per_eval: int,
  ) -> Iterable[
      Tuple[Tuple[Tensor, ...], Any, TargetType, Tuple[Tensor, ...]]
  ]:
      """
      This method is a generator which yields each perturbation to be evaluated
      including inputs, additional_forward_args, targets, and mask.
      """
      # current_tensors starts at baselines and includes each additional feature as
      # added based on the permutation order.
      current_tensors = baselines
      current_tensors_list = []
      current_mask_list = []
  
      # Compute repeated additional args and targets
      additional_args_repeated = (
          _expand_additional_forward_args(
              additional_args, perturbations_per_eval
          )
          if additional_args is not None
          else None
      )
      target_repeated = _expand_target(target, perturbations_per_eval)
      for i in range(len(feature_permutation)):
          current_tensors = tuple(
              current
              * (~(mask == feature_permutation[i])).to(current.dtype)
              + input * (mask == feature_permutation[i]).to(input.dtype)
              for input, current, mask in zip(
                  inputs, current_tensors, input_masks
              )
          )
          current_tensors_list.append(current_tensors)
          current_mask_list.append(
              tuple(
                  mask == feature_permutation[i] for mask in input_masks
              )
          )
          if len(current_tensors_list) == perturbations_per_eval:
              combined_inputs = tuple(
                  torch.cat(aligned_tensors, dim=0)
                  for aligned_tensors in zip(*current_tensors_list)
              )
              combined_masks = tuple(
                  torch.stack(aligned_masks, dim=0)
                  for aligned_masks in zip(*current_mask_list)
              )
              yield (
                  combined_inputs,
                  additional_args_repeated,
                  target_repeated,
                  combined_masks,
              )
              current_tensors_list = []
              current_mask_list = []
  
      # Create batch with remaining evaluations, may not be a complete batch
      # (= perturbations_per_eval)
      if len(current_tensors_list) != 0:
          additional_args_repeated = (
              _expand_additional_forward_args(
                  additional_args, len(current_tensors_list)
              )
              if additional_args is not None
              else None
          )
          target_repeated = _expand_target(
              target, len(current_tensors_list)
          )
          combined_inputs = tuple(
              torch.cat(aligned_tensors, dim=0)
              for aligned_tensors in zip(*current_tensors_list)
          )
          combined_masks = tuple(
              torch.stack(aligned_masks, dim=0)
              for aligned_masks in zip(*current_mask_list)
          )
          yield (
              combined_inputs,
              additional_args_repeated,
              target_repeated,
              combined_masks,
          )
  
imports: import itertools
  import math
  import warnings
  from typing import Any, Callable, Iterable, Sequence, Tuple, Union
  import torch
  from captum._utils.common import _expand_additional_forward_args, _expand_target, _format_additional_forward_args, _format_feature_mask, _format_output, _format_tensor_into_tuples, _get_max_feature_index, _is_mask_valid, _is_tuple, _run_forward
  from captum._utils.progress import progress
  from captum._utils.typing import BaselineType, TargetType, TensorOrTupleOfTensorsGeneric
  from captum.attr._utils.attribution import PerturbationAttribution
  from captum.attr._utils.common import _find_output_mode_and_verify, _format_input_baseline, _tensorize_baseline
  from captum.log import log_usage
  from torch import Tensor
label_desc: Use image node_id 3 for calling the ShapleyValueSampling obj's underlying member method code with example usage: obj._perturbation_generator(inputs, additional_args, target, baselines, input_masks, feature_permutation, perturbations_per_eval) without return types