class_docstr: This is a utility class that combines a model, a masker object, and a current input.
  
  The combination of a model, a masker object, and a current input produces a binary set
  function that can be called to mask out any set of inputs. This class attempts to be smart
  about only evaluating the model for background samples when the inputs changed (note this
  requires the masker object to have a .invariants method).
class_docstr_tok: ["This","is","a","utility","class","that","combines","a","model",",","a","masker","object",",","and","a","current","input",".","The","combination","of","a","model",",","a","masker","object",",","and","a","current","input","produces","a","binary","set","function","that","can","be","called","to","mask","out","any","set","of","inputs",".","This","class","attempts","to","be","smart","about","only","evaluating","the","model","for","background","samples","when","the","inputs","changed","(","note","this","requires","the","masker","object","to","have","a",".invariants","method",")","."]
code: def _delta_masking_call(
      self, masks, zero_index=None, batch_size=None
  ):
      # TODO: we need to do batching here
  
      assert (
          getattr(self.masker, "supports_delta_masking", None)
          is not None
      ), "Masker must support delta masking!"
  
      masked_inputs, varying_rows = self.masker(masks, *self.args)
      num_varying_rows = varying_rows.sum(1)
  
      subset_masked_inputs = [
          arg[varying_rows.reshape(-1)] for arg in masked_inputs
      ]
  
      batch_positions = np.zeros(len(varying_rows) + 1, dtype=int)
      for i in range(len(varying_rows)):
          batch_positions[i + 1] = (
              batch_positions[i] + num_varying_rows[i]
          )
  
      # joined_masked_inputs = self._stack_inputs(all_masked_inputs)
      outputs = self.model(*subset_masked_inputs)
      _assert_output_input_match(subset_masked_inputs, outputs)
  
      if (
          self.linearize_link
          and self.link != links.identity
          and self._linearizing_weights is None
      ):
          self.background_outputs = outputs[
              batch_positions[zero_index] : batch_positions[
                  zero_index + 1
              ]
          ]
          self._linearizing_weights = link_reweighting(
              self.background_outputs, self.link
          )
  
      averaged_outs = np.zeros(
          (varying_rows.shape[0],) + outputs.shape[1:]
      )
      last_outs = np.zeros((varying_rows.shape[1],) + outputs.shape[1:])
      # print("link", self.link)
      _build_fixed_output(
          averaged_outs,
          last_outs,
          outputs,
          batch_positions,
          varying_rows,
          num_varying_rows,
          self.link,
          self._linearizing_weights,
      )
  
      return averaged_outs
  
imports: import copy
  import numpy
  import scipy.sparse
  from numba import njit
  from ..None import links
label_desc: Use image node_id 4 for calling the MaskedModel obj's underlying member method code with example usage: obj._delta_masking_call(masks, zero_index, batch_size) and returns: averaged_outs