code: def gradients_multi_output(
      inputs, model, num_classes, multiply_by_input=False
  ):
      """
      Computes the gradients of the output with respect to the input. Optionally mulitplies those
      gradients by the input to the model.
  
      Args:
          inputs: A [batch_size, ...]-shaped tensor. The input to a model.
          model:  A tf.keras.Model object, or a subclass object thereof.
          num_classes: The numver of classes to take the gradient with respect to
          multiply_by_input: Whether or not to multiply the gradients by the input to the model.
              Defaults to False.
      Returns:
          A tensor the same shape as the input representing the gradients of the output with
          respect to the input.
      """
      with tf.GradientTape(persistent=True) as tape:
          tape.watch(inputs)
          predictions = model(inputs, training=True)
  
          predictions_indexed = []
          for output_class in range(num_classes):
              predictions_indexed.append(predictions[:, output_class])
  
      gradients_array = []
      for output_class in range(num_classes):
          input_gradients = tape.gradient(
              predictions_indexed[output_class], inputs
          )
          if multiply_by_input:
              input_gradients = input_gradients * inputs
  
          gradients_array.append(input_gradients)
  
      del tape
      stacked_gradients = tf.stack(gradients_array, axis=1)
  
      return stacked_gradients
  
file_path: attributionpriors/attributionpriors/eager_ops.py
imports: import tensorflow
  import numpy
label_desc: Use image node_id 3 for calling a global function with example usage: gradients_multi_output(inputs, model, num_classes, multiply_by_input) and returns: stacked_gradients