<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def visualize_saliency(model, layer_idx, filter_indices, seed_input, wrt_tensor=None, backprop_modifier=None, grad_modifier='absolute', keepdims=False):
 """Generates an attention heatmap over the `seed_input` for maximizing `filter_indices` output in the given `layer_idx`. Args: `image_data_format=channels_last`. layer_idx: The layer index within `model.layers` whose filters needs to be visualized. filter_indices: filter indices within the layer to be maximized. If None, all filters are visualized. (Default value = None) For `keras.layers.Dense` layer, `filter_idx` is interpreted as the output index. If you are visualizing final `keras.layers.Dense` layer, consider switching 'softmax' activation for 'linear' using [utils.apply_modifications](vis.utils.utils#apply_modifications) for better results. seed_input: The model input for which activation map needs to be visualized. wrt_tensor: Short for, with respect to. The gradients of losses are computed with respect to this tensor. When None, this is assumed to be the same as `input_tensor` (Default value: None) backprop_modifier: backprop modifier to use. See [backprop_modifiers](vis.backprop_modifiers.md). If you don't specify anything, no backprop modification is applied. (Default value = None) grad_modifier: gradient modifier to use. See [grad_modifiers](vis.grad_modifiers.md). By default `absolute` value of gradients are used. To visualize positive or negative gradients, use `relu` and `negate` respectively. (Default value = 'absolute') keepdims: A boolean, whether to keep the dimensions or not. If keepdims is False, the channels axis is deleted. If keepdims is True, the grad with same shape as input_tensor is returned. (Default value: False) Example: If you wanted to visualize attention over 'bird' category, say output index 22 on the final `keras.layers.Dense` layer, then, `filter_indices = [22]`, `layer = dense_layer`. One could also set filter indices to more than one value. For example, `filter_indices = [22, 23]` should (hopefully) show attention map that corresponds to both 22, 23 output categories. Returns: The heatmap image indicating the `seed_input` regions whose change would most contribute towards maximizing the output of `filter_indices`. """

    if backprop_modifier is not None:
        modifier_fn = get(backprop_modifier)
        model = modifier_fn(model)

    # `ActivationMaximization` loss reduces as outputs get large, hence negative gradients indicate the direction
    # for increasing activations. Multiply with -1 so that positive gradients indicate increase instead.
    losses = [
        (ActivationMaximization(model.layers[layer_idx], filter_indices), -1)
    ]
    return visualize_saliency_with_losses(model.input, losses, seed_input, wrt_tensor, grad_modifier, keepdims)