class_docstr: A perturbation based approach to computing attribution, involving
  replacing each input feature with a given baseline / reference, and
  computing the difference in output. By default, each scalar value within
  each input tensor is taken as a feature and replaced independently. Passing
  a feature mask, allows grouping features to be ablated together. This can
  be used in cases such as images, where an entire segment or region
  can be ablated, 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 target as a result of ablating the entire feature
  group.
  
  The forward function can either return a scalar per example or a tensor
  of a fixed sized tensor (or scalar value) for the full batch, i.e. the
  output does not grow as the batch size increase. If the output is fixed
  we consider this model to be an "aggregation" of the inputs. In the fixed
  sized output mode we require `perturbations_per_eval == 1` and the
  `feature_mask` to be either `None` or for all of them to have 1 as their
  first dimension (i.e. a feature mask requires to be applied to all inputs).
class_docstr_tok: ["A","perturbation","based","approach","to","computing","attribution",",","involving","replacing","each","input","feature","with","a","given","baseline","\/","reference",",","and","computing","the","difference","in","output",".","By","default",",","each","scalar","value","within","each","input","tensor","is","taken","as","a","feature","and","replaced","independently",".","Passing","a","feature","mask",",","allows","grouping","features","to","be","ablated","together",".","This","can","be","used","in","cases","such","as","images",",","where","an","entire","segment","or","region","can","be","ablated",",","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","target","as","a","result","of","ablating","the","entire","feature","group",".","The","forward","function","can","either","return","a","scalar","per","example","or","a","tensor","of","a","fixed","sized","tensor","(","or","scalar","value",")","for","the","full","batch",",","i.e",".","the","output","does","not","grow","as","the","batch","size","increase",".","If","the","output","is","fixed","we","consider","this","model","to","be","an","``","aggregation","''","of","the","inputs",".","In","the","fixed","sized","output","mode","we","require","`","perturbations_per_eval","==","1","`","and","the","`","feature_mask","`","to","be","either","`","None","`","or","for","all","of","them","to","have","1","as","their","first","dimension","(","i.e",".","a","feature","mask","requires","to","be","applied","to","all","inputs",")","."]
docstr: This method returns a generator of ablation perturbations of the i-th input
  
  Returns:
      ablation_iter (Generator): yields each perturbation to be evaluated
                  as a tuple (inputs, additional_forward_args, targets, mask).
docstr_tok: ["This","method","returns","a","generator","of","ablation","perturbations","of","the","i-th","input","Returns",":","ablation_iter","(","Generator",")",":","yields","each","perturbation","to","be","evaluated","as","a","tuple","(","inputs",",","additional_forward_args",",","targets",",","mask",")","."]
code: def _ith_input_ablation_generator(
      self,
      i,
      inputs,
      additional_args,
      target,
      baselines,
      input_mask,
      perturbations_per_eval,
      **kwargs,
  ):
      """
      This method returns a generator of ablation perturbations of the i-th input
  
      Returns:
          ablation_iter (Generator): yields each perturbation to be evaluated
                      as a tuple (inputs, additional_forward_args, targets, mask).
      """
      extra_args = {}
      for key, value in kwargs.items():
          # For any tuple argument in kwargs, we choose index i of the tuple.
          if isinstance(value, tuple):
              extra_args[key] = value[i]
          else:
              extra_args[key] = value
  
      input_mask = input_mask[i] if input_mask is not None else None
      (
          min_feature,
          num_features,
          input_mask,
      ) = self._get_feature_range_and_mask(
          inputs[i], input_mask, **extra_args
      )
      num_examples = inputs[0].shape[0]
      perturbations_per_eval = min(perturbations_per_eval, num_features)
      baseline = (
          baselines[i] if isinstance(baselines, tuple) else baselines
      )
      if isinstance(baseline, torch.Tensor):
          baseline = baseline.reshape((1,) + baseline.shape)
  
      if perturbations_per_eval > 1:
          # Repeat features and additional args for batch size.
          all_features_repeated = [
              torch.cat([inputs[j]] * perturbations_per_eval, dim=0)
              for j in range(len(inputs))
          ]
          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
          )
      else:
          all_features_repeated = list(inputs)
          additional_args_repeated = additional_args
          target_repeated = target
  
      num_features_processed = min_feature
      while num_features_processed < num_features:
          current_num_ablated_features = min(
              perturbations_per_eval,
              num_features - num_features_processed,
          )
  
          # Store appropriate inputs and additional args based on batch size.
          if current_num_ablated_features != perturbations_per_eval:
              current_features = [
                  feature_repeated[
                      0 : current_num_ablated_features * num_examples
                  ]
                  for feature_repeated in all_features_repeated
              ]
              current_additional_args = (
                  _expand_additional_forward_args(
                      additional_args, current_num_ablated_features
                  )
                  if additional_args is not None
                  else None
              )
              current_target = _expand_target(
                  target, current_num_ablated_features
              )
          else:
              current_features = all_features_repeated
              current_additional_args = additional_args_repeated
              current_target = target_repeated
  
          # Store existing tensor before modifying
          original_tensor = current_features[i]
          # Construct ablated batch for features in range num_features_processed
          # to num_features_processed + current_num_ablated_features and return
          # mask with same size as ablated batch. ablated_features has dimension
          # (current_num_ablated_features, num_examples, inputs[i].shape[1:])
          # Note that in the case of sparse tensors, the second dimension
          # may not necessarilly be num_examples and will match the first
          # dimension of this tensor.
          current_reshaped = current_features[i].reshape(
              (current_num_ablated_features, -1)
              + current_features[i].shape[1:]
          )
  
          (
              ablated_features,
              current_mask,
          ) = self._construct_ablated_input(
              current_reshaped,
              input_mask,
              baseline,
              num_features_processed,
              num_features_processed + current_num_ablated_features,
              **extra_args,
          )
  
          # current_features[i] has dimension
          # (current_num_ablated_features * num_examples, inputs[i].shape[1:]),
          # which can be provided to the model as input.
          current_features[i] = ablated_features.reshape(
              (-1,) + ablated_features.shape[2:]
          )
          yield tuple(
              current_features
          ), current_additional_args, current_target, current_mask
          # Replace existing tensor at index i.
          current_features[i] = original_tensor
          num_features_processed += current_num_ablated_features
  
file_path: captum/captum/attr/_core/feature_ablation.py
imports: import math
  from typing import Any, Callable, cast, Tuple, Union
  import torch
  from captum._utils.common import _expand_additional_forward_args, _expand_target, _format_additional_forward_args, _format_feature_mask, _format_output, _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 _format_input_baseline
  from captum.log import log_usage
  from torch import dtype, Tensor
label_desc: Use image node_id 3 for calling the FeatureAblation obj's underlying member method code with example usage: obj._ith_input_ablation_generator(i, inputs, additional_args, target, baselines, input_mask, perturbations_per_eval) without return types