function inputGradientAscent(model, layerName, filterIndex, iterations = 40) {
  return tf.tidy(() => {
    const imageH = model.inputs[0].shape[1];
    const imageW = model.inputs[0].shape[2];
    const imageDepth = model.inputs[0].shape[3];

    // Create an auxiliary model of which input is the same as the original
    // model but the output is the output of the convolutional layer of
    // interest.
    const layerOutput = model.getLayer(layerName).output;
    const auxModel = tf.model({inputs: model.inputs, outputs: layerOutput});

    // This function calculates the value of the convolutional layer's
    // output at the designated filter index.
    const lossFunction = (input) =>
        auxModel.apply(input, {training: true}).gather([filterIndex], 3);

    // This returned function (`gradFunction`) calculates the gradient of the
    // convolutional filter's output with respect to the input image.
    const gradFunction = tf.grad(lossFunction);

    // Form a random image as the starting point of the gradient ascent.
    let image = tf.randomUniform([1, imageH, imageW, imageDepth], 0, 1)
                    .mul(20)
                    .add(128);

    for (let i = 0; i < iterations; ++i) {
      const scaledGrads = tf.tidy(() => {
        const grads = gradFunction(image);
        const norm =
            tf.sqrt(tf.mean(tf.square(grads))).add(tf.backend().epsilon());
        // Important trick: scale the gradient with the magnitude (norm)
        // of the gradient.
        return grads.div(norm);
      });
      // Perform one step of gradient ascent: Update the image along the
      // direction of the gradient.
      image = tf.clipByValue(image.add(scaledGrads), 0, 255);
    }
    return deprocessImage(image);
  });
}
Generate the maximally-activating input image for a conv2d layer filter.

Uses gradient ascent in input space.

@param {tf.Model} model The model that the convolutional layer of interest
  belongs to.
@param {string} layerName Name of the convolutional layer.
@param {number} filterIndex Index to the filter of interest. Must be
  < number of filters of the conv2d layer.
@param {number} iterations Number of gradient-ascent iterations.
@return {tf.Tensor} The maximally-activating input image as a tensor.