code: def gradcam(weights, activations):
      # type: (np.ndarray, np.ndarray) -> np.ndarray
      """
      Generate a localization map (heatmap) using Gradient-weighted Class Activation Mapping
      (Grad-CAM) (https://arxiv.org/pdf/1610.02391.pdf).
  
      The values for the parameters can be obtained from
      :func:`eli5.keras.gradcam.gradcam_backend`.
  
      Parameters
      ----------
      weights : numpy.ndarray
          Activation weights, vector with one weight per map,
          rank 1.
  
      activations : numpy.ndarray
          Forward activation map values, vector of matrices,
          rank 3.
  
      Returns
      -------
      lmap : numpy.ndarray
          A Grad-CAM localization map,
          rank 2, with values normalized in the interval [0, 1].
  
      Notes
      -----
      We currently make two assumptions in this implementation
          * We are dealing with images as our input to ``model``.
          * We are doing a classification. ``model``'s output is a class scores or probabilities vector.
  
      Credits
          * Jacob Gildenblat for "https://github.com/jacobgil/keras-grad-cam".
          * Author of "https://github.com/PowerOfCreation/keras-grad-cam" for fixes to Jacob's implementation.
          * Kotikalapudi, Raghavendra and contributors for "https://github.com/raghakot/keras-vis".
      """
      # For reusability, this function should only use numpy operations
      # Instead of backend library operations
  
      # Perform a weighted linear combination
      # we need to multiply (dim1, dim2, maps,) by (maps,) over the first two axes
      # and add each result to (dim1, dim2,) results array
      # there does not seem to be an easy way to do this:
      # see: https://stackoverflow.com/questions/30031828/multiply-numpy-ndarray-with-1d-array-along-a-given-axis
      spatial_shape = activations.shape[:2]  # -> (dim1, dim2)
      lmap = np.zeros(spatial_shape, dtype=np.float64)
      # iterate through each activation map
      for i, w in enumerate(weights):
          # weight * spatial map
          # add result to the entire localization map (NOT pixel by pixel)
          lmap += w * activations[..., i]
  
      lmap = np.maximum(lmap, 0)  # ReLU
  
      # normalize lmap to [0, 1] ndarray
      # add eps to avoid division by zero in case lmap is 0's
      # this also means that lmap max will be slightly less than the 'true' max
      lmap = lmap / (np.max(lmap) + K.epsilon())
      return lmap
  
file_path: eli5/eli5/keras/gradcam.py
imports: from __future__ import absolute_import
  from typing import Union, Optional, Tuple, List
  import numpy
  import keras
  import keras.backend
  from keras.models import Model
  from keras.layers import Layer
label_desc: Use image node_id 1 for calling a global function with example usage: gradcam(weights, activations) and returns: lmap