docstr: Creates graph operations to switch between normal input and 
  input-reference interpolations. 
  
  Args:
      batch_input_op: Tensor of shape (None, ...), where ... indicates
                      the input dimensions. 
      background_ref_op: A tensor of shape (None, k, ...) where ... indicates 
                         the input dimensions, and k represents the number of
                         background reference samples to draw per input in the batch,
                         or a function that returns such a tensor when called. Alternatively,
                         if set to the string 'shuffle' or 'roll', 
                         uses a shuffled/rolled version of the batch input as a background reference.
      k: An integer specifying the number of background references if background_ref_op is 'roll' or
         'shuffle'. Ignored if background_ref_op is a tensor.
  Returns: 
      cond_input_op: A tensor of shape (None, ...). Use this tensor to build your model.
      train_eg: A placeholder with default value False. Set to true to switch from normal inputs
                to interpolated reference inputs.
code: def input_to_samples_delta(
      self, batch_input_op, background_ref_op="roll", k=1
  ):
      """
      Creates graph operations to switch between normal input and
      input-reference interpolations.
  
      Args:
          batch_input_op: Tensor of shape (None, ...), where ... indicates
                          the input dimensions.
          background_ref_op: A tensor of shape (None, k, ...) where ... indicates
                             the input dimensions, and k represents the number of
                             background reference samples to draw per input in the batch,
                             or a function that returns such a tensor when called. Alternatively,
                             if set to the string 'shuffle' or 'roll',
                             uses a shuffled/rolled version of the batch input as a background reference.
          k: An integer specifying the number of background references if background_ref_op is 'roll' or
             'shuffle'. Ignored if background_ref_op is a tensor.
      Returns:
          cond_input_op: A tensor of shape (None, ...). Use this tensor to build your model.
          train_eg: A placeholder with default value False. Set to true to switch from normal inputs
                    to interpolated reference inputs.
      """
      input_dims = batch_input_op.get_shape().as_list()[1:]
      num_input_dims = len(input_dims)
  
      def samples_input_fn():
          if isinstance(
              background_ref_op,
              (tf.Tensor, tf.SparseTensor, tf.Variable),
          ):
              #             if tf.contrib.framework.is_tensor(background_ref_op):
              self.background_ref_op = background_ref_op
              if k is not None:
                  print(
                      "Warning: value `{}` of parameter k will be ignored because background_ref_op was an input tensor".format(
                          k
                      )
                  )
          elif callable(background_ref_op):
              self.background_ref_op = background_ref_op()
              if k is not None:
                  print(
                      "Warning: value `{}` of parameter k will be ignored because background_ref_op was callable".format(
                          k
                      )
                  )
          elif isinstance(background_ref_op, str):
              if background_ref_op == "shuffle":
                  self.background_ref_op = self._permuted_references(
                      batch_input_op, k, shuffle=True
                  )
              elif background_ref_op == "roll":
                  self.background_ref_op = self._permuted_references(
                      batch_input_op, k, shuffle=False
                  )
              else:
                  raise ValueError(
                      "Unrecognized string value `{}` for parameter `background_ref_op` (must be one of `shuffle`, `roll`)".format(
                          background_ref_op
                      )
                  )
          else:
              raise ValueError(
                  "Unrecognized value `{}` for parameter `background_ref_op`".format(
                      background_ref_op
                  )
              )
  
          batch_size = tf.shape(self.background_ref_op)[0]
          k_ = self.background_ref_op.shape[1]
  
          # Grab a [batch_size, k]-sized interpolation sample
          # Note that evaluating t_tensor will evaluate background_ref_op implicitly for shape information
          if self.random_alpha:
              t_tensor = tf.random_uniform(
                  shape=[batch_size, k_], name="t_tensor"
              )
              t_tensor = tf.cast(t_tensor, dtype=batch_input_op.dtype)
              t_tensor.set_shape([None, k_])
          else:
              t_tensor = tf.linspace(
                  start=0.0, stop=1.0, num=k_, name="linspace_t"
              )
              t_tensor = tf.expand_dims(t_tensor, axis=0)
              t_tensor = tf.tile(
                  t_tensor, [batch_size, 1], name="t_tensor"
              )
              t_tensor = tf.cast(t_tensor, dtype=batch_input_op.dtype)
              t_tensor.set_shape([None, k_])
  
          interp_coef = tf.reshape(
              t_tensor,
              [batch_size, k_] + [1] * num_input_dims,
              name="interp_coef",
          )
  
          # Evaluate the end points
          end_point_ref = tf.multiply(
              1.0 - interp_coef,
              self.background_ref_op,
              name="end_point_ref",
          )
  
          input_expand_mult = tf.expand_dims(batch_input_op, axis=1)
          end_point_input = tf.multiply(
              interp_coef, input_expand_mult, name="end_point_input"
          )
  
          # Add the end points together, because, you know, interpolation
          samples_input = tf.add(
              end_point_input, end_point_ref, name="samples_input"
          )
          return samples_input
  
      # Define operations to switch between interpolation and normal input
      train_eg = tf.placeholder_with_default(
          False, shape=(), name="train_eg"
      )
      cond_input_op = tf.cond(
          train_eg, samples_input_fn, lambda: batch_input_op
      )
      cond_input_op = tf.reshape(
          cond_input_op, shape=[-1] + input_dims, name="cond_input_op"
      )
  
      self.samples_delta = tf.subtract(
          tf.expand_dims(batch_input_op, axis=1),
          self.background_ref_op,
          name="samples_delta",
      )
  
      return cond_input_op, train_eg
  
file_path: attributionpriors/attributionpriors/ops.py
imports: import tensorflow
  import numpy
label_desc: Use image node_id 4 for calling the AttributionPriorExplainer obj's underlying member method code with example usage: obj.input_to_samples_delta(batch_input_op, background_ref_op, k) and returns: cond_input_op,  train_eg, samples_input