Ejemplo n.º 1
0
    def explain(self, validation_data, model, class_index, patch_size):
        """
        Compute Occlusion Sensitivity maps for a specific class index.

        Args:
            validation_data (Tuple[np.ndarray, Optional[np.ndarray]]): Validation data
                to perform the method on. Tuple containing (x, y).
            model (tf.keras.Model): tf.keras model to inspect
            class_index (int): Index of targeted class
            patch_size (int): Size of patch to apply on the image

        Returns:
            np.ndarray: Grid of all the sensitivity maps with shape (batch_size, H, W, 3)
        """
        images, _ = validation_data
        sensitivity_maps = np.array([
            self.get_sensitivity_map(model, image, class_index, patch_size)
            for image in images
        ])

        heatmaps = np.array([
            heatmap_display(heatmap, image)
            for heatmap, image in zip(sensitivity_maps, images)
        ])

        grid = grid_display(heatmaps)

        return grid
Ejemplo n.º 2
0
    def explain(self, validation_data, model, layer_name, class_index):
        """
        Compute GradCAM for a specific class index.

        Args:
            validation_data (Tuple[np.ndarray, Optional[np.ndarray]]): Validation data
                to perform the method on. Tuple containing (x, y).
            model (tf.keras.Model): tf.keras model to inspect
            layer_name (str): Targeted layer for GradCAM
            class_index (int): Index of targeted class

        Returns:
            numpy.ndarray: Grid of all the GradCAM
        """
        images, _ = validation_data

        outputs, guided_grads = GradCAM.get_gradients_and_filters(
            model, images, layer_name, class_index
        )

        cams = GradCAM.generate_ponderated_output(outputs, guided_grads)

        heatmaps = np.array(
            [heatmap_display(cam.numpy(), image) for cam, image in zip(cams, images)]
        )

        grid = grid_display(heatmaps)

        return grid
Ejemplo n.º 3
0
    def explain(
        self,
        validation_data,
        model,
        class_index,
        layer_name=None,
        use_guided_grads=True,
        colormap=cv2.COLORMAP_VIRIDIS,
        image_weight=0.7,
        mean_transform=None,
        std_dev_transform=None,
    ):
        """
        Compute GradCAM for a specific class index.

        Args:
            validation_data (Tuple[np.ndarray, Optional[np.ndarray]]): Validation data
                to perform the method on. Tuple containing (x, y).
            model (tf.keras.Model): tf.keras model to inspect
            class_index (int): Index of targeted class
            layer_name (str): Targeted layer for GradCAM. If no layer is provided, it is
                automatically infered from the model architecture.
            colormap (int): OpenCV Colormap to use for heatmap visualization
            image_weight (float): An optional `float` value in range [0,1] indicating the weight of
                the input image to be overlaying the calculated attribution maps. Defaults to `0.7`.
            use_guided_grads (boolean): Whether to use guided grads or raw gradients

        Returns:
            numpy.ndarray: Grid of all the GradCAM
        """
        images, _ = validation_data

        if layer_name is None:
            layer_name = self.infer_grad_cam_target_layer(model)

        outputs, grads = GradCAM.get_gradients_and_filters(
            model, images, layer_name, class_index, use_guided_grads
        )

        cams = GradCAM.generate_ponderated_output(outputs, grads)

        heatmaps = np.array(
            [
                # not showing the actual image if image_weight=0
                heatmap_display(
                    cam.numpy(),
                    image,
                    colormap,
                    image_weight,
                    mean_transform,
                    std_dev_transform,
                )
                for cam, image in zip(cams, images)
            ]
        )

        grid = grid_display(heatmaps)

        return grid
Ejemplo n.º 4
0
def test_should_display_heatmap(mocker):
    mock_add_weighted = mocker.patch(
        "tf_explain.utils.display.cv2.addWeighted")
    mock_apply_color_map = mocker.patch(
        "tf_explain.utils.display.cv2.applyColorMap")
    mock_cvt_color = mocker.patch("tf_explain.utils.display.cv2.cvtColor",
                                  return_value=mocker.sentinel.heatmap)

    heatmap = np.random.random((3, 3))
    original_image = np.zeros((10, 10, 3))

    output = heatmap_display(heatmap, original_image)

    assert output == mocker.sentinel.heatmap
    assert mock_add_weighted.call_count == 1
    assert mock_apply_color_map.call_count == 1
    assert mock_cvt_color.call_count == 3
Ejemplo n.º 5
0
    def explain(self,
                model_input,
                model,
                layer_name,
                class_index,
                colormap=cv2.COLORMAP_INFERNO):
        """
        Compute GradCAM for a specific class index.

        Args:
            model_input (tf.tensor): Data to perform the evaluation on.
            model (tf.keras.Model): tf.keras model to inspect
            layer_name (str): Targeted layer for GradCAM
            class_index (int, None): Index of targeted class
            colormap (int): Used in parent method signature, but ignored here

        Returns:
            tf.cams: The gradcams
        """
        outputs, guided_grads, predictions = FEGradCAM.get_gradients_and_filters(
            model, model_input, layer_name, class_index)
        cams = GradCAM.generate_ponderated_output(outputs, guided_grads)

        input_min = tf.reduce_min(model_input)
        input_max = tf.reduce_max(model_input)

        # Need to move input image into the 0-255 range
        adjust_sum = 0.0
        adjust_factor = 1.0
        if input_min < 0:
            adjust_sum = 1.0
            adjust_factor /= 2.0
        if input_max <= 1:
            adjust_factor *= 255.0

        heatmaps = [
            heatmap_display(cam.numpy(),
                            (inp.numpy() + adjust_sum) * adjust_factor,
                            colormap) for cam, inp in zip(cams, model_input)
        ]

        return heatmaps, predictions
Ejemplo n.º 6
0
    def explain(
        self,
        validation_data,
        model,
        class_index,
        layer_name=None,
        colormap=cv2.COLORMAP_VIRIDIS,
    ):
        """
        Compute GradCAM for a specific class index.

        Args:
            validation_data (Tuple[np.ndarray, Optional[np.ndarray]]): Validation data
                to perform the method on. Tuple containing (x, y).
            model (tf.keras.Model): tf.keras model to inspect
            class_index (int): Index of targeted class
            layer_name (str): Targeted layer for GradCAM. If no layer is provided, it is
                automatically infered from the model architecture.
            colormap (int): OpenCV Colormap to use for heatmap visualization

        Returns:
            numpy.ndarray: Grid of all the GradCAM
        """
        images, _ = validation_data

        if layer_name is None:
            layer_name = self.infer_grad_cam_target_layer(model)

        outputs, guided_grads = GradCAM.get_gradients_and_filters(
            model, images, layer_name, class_index)

        cams = GradCAM.generate_ponderated_output(outputs, guided_grads)

        heatmaps = np.array([
            heatmap_display(cam.numpy(), image, colormap)
            for cam, image in zip(cams, images)
        ])

        grid = grid_display(heatmaps)

        return grid, outputs, guided_grads