Ejemplo n.º 1
0
    def explain(self,
                validation_data,
                model,
                class_index,
                num_samples=5,
                noise=1.0):
        """
        Compute SmoothGrad 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
            num_samples (int): Number of noisy samples to generate for each input image
            noise (float): Standard deviation for noise normal distribution

        Returns:
            np.ndarray: Grid of all the smoothed gradients
        """
        images, _ = validation_data

        noisy_images = SmoothGrad.generate_noisy_images(
            images, num_samples, noise)

        smoothed_gradients = SmoothGrad.get_averaged_gradients(
            noisy_images, model, class_index, num_samples)

        grayscale_gradients = transform_to_normalized_grayscale(
            tf.abs(smoothed_gradients)).numpy()

        grid = grid_display(grayscale_gradients)

        return grid
Ejemplo n.º 2
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.º 3
0
    def explain(self, validation_data, model, class_index, n_steps=10):
        """
        Compute Integrated Gradients 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
            n_steps (int): Number of steps in the path

        Returns:
            np.ndarray: Grid of all the integrated gradients
        """
        images, _ = validation_data

        interpolated_images = IntegratedGradients.generate_interpolations(
            np.array(images), n_steps)

        integrated_gradients = IntegratedGradients.get_integrated_gradients(
            interpolated_images, model, class_index, n_steps)

        grayscale_integrated_gradients = transform_to_normalized_grayscale(
            tf.abs(integrated_gradients)).numpy()

        grid = grid_display(grayscale_integrated_gradients)

        return grid
Ejemplo n.º 4
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.º 5
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.º 6
0
def test_should_raise_warning_if_grid_size_is_too_small(array_to_display):
    with pytest.warns(Warning) as w:
        grid = grid_display(array_to_display, num_rows=1, num_columns=1)

    assert (
        w[0].message.args[0] ==
        "Given values for num_rows and num_columns doesn't allow to display all images. Values have been overrided to respect at least num_columns"
    )
    assert grid.shape == (28 * 7, 28, 3)
Ejemplo n.º 7
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
Ejemplo n.º 8
0
    def explain_score_model(self, validation_data, score_model, class_index):
        """
        Perform gradients backpropagation for a given input

        Args:
            validation_data (Tuple[np.ndarray, Optional[np.ndarray]]): Validation data
                to perform the method on. Tuple containing (x, y).
            score_model (tf.keras.Model): tf.keras model to inspect. The last layer
            should not have any activation function.
            class_index (int): Index of targeted class

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

        gradients = self.compute_gradients(images, score_model, class_index)

        grayscale_gradients = transform_to_normalized_grayscale(
            tf.abs(gradients)).numpy()

        grid = grid_display(grayscale_gradients)

        return grid
Ejemplo n.º 9
0
def plot_well_gradCAM(X,
                      days,
                      segment_labels,
                      classify_labels,
                      model,
                      save_root='.'):
    explainer = GradCAM()
    _model = Model(
        model.input,
        model.classify_out)  # model instance for explain classify output

    X = X[:9]
    days = days[:9]

    n_r = 3 if len(X) > 4 else 2

    input_grid = grid_display(X[..., 0], num_rows=n_r, num_columns=n_r)
    pos_cam_grid = explainer.explain((list(X), None),
                                     _model,
                                     class_index=3,
                                     image_weight=0.)
    neg_cam_grid = explainer.explain((list(X), None),
                                     _model,
                                     class_index=0,
                                     image_weight=0.)

    preds = model.predict(X)
    classify_preds = preds[1][...,
                              1] + preds[1][..., 2] * 2 + preds[1][..., 3] * 3
    segment_preds = preds[0][...,
                             1] + preds[0][..., 2] * 2 + preds[0][..., 3] * 3
    segment_pred_grid = grid_display(segment_preds,
                                     num_rows=n_r,
                                     num_columns=n_r)
    classify_pred_grid = grid_display(classify_preds.reshape((-1, 1, 1)),
                                      num_rows=n_r,
                                      num_columns=n_r)

    plt.clf()
    plt.figure(figsize=(15, 10))

    plt.subplot(2, 3, 1)
    plt.imshow(input_grid)
    plt.title("Input Phase Contrast\ndays: %s\nsegment_label: %s" %
              (str(days), str(classify_labels)))
    plt.axis('off')

    plt.subplot(2, 3, 2)
    plt.imshow(pos_cam_grid)
    plt.title("Grad CAM on class 3")
    plt.axis('off')

    plt.subplot(2, 3, 3)
    plt.imshow(neg_cam_grid)
    plt.title("Grad CAM on class 0")
    plt.axis('off')

    plt.subplot(2, 3, 4)
    plt.imshow(classify_pred_grid, vmin=0., vmax=3., cmap='viridis')
    plt.title("Classification prediction")
    plt.axis('off')

    plt.subplot(2, 3, 5)
    plt.imshow(segment_pred_grid, vmin=0., vmax=3., cmap='viridis')
    plt.title("Segmentation prediction")
    plt.axis('off')

    if not segment_labels[0] is None:
        plt.subplot(2, 3, 6)
        y = segment_labels[0]
        segment_mat = y[..., 1] + y[..., 2] * 2 + y[..., 3] * 3
        plt.imshow(segment_mat, vmin=0., vmax=3., cmap='viridis')
        plt.title("Final fluorescence, class %d" % class_index)
        plt.axis('off')

    plt.savefig(os.path.join(save_root, '%s-explain.png' % ('-'.join(w))),
                dpi=300)
    return pos_cam_grid, neg_cam_grid
Ejemplo n.º 10
0
def test_should_fill_with_zeros_if_missing_elements(array_to_display):
    grid = grid_display(array_to_display)

    assert grid.shape == (28 * 3, 28 * 3, 3)
    np.testing.assert_equal(grid[56:, 28:, :], np.zeros((28, 56, 3)))
Ejemplo n.º 11
0
def test_should_return_a_grid_square_by_default(grid_display_kwargs,
                                                expected_shape,
                                                array_to_display):
    grid = grid_display(array_to_display, **grid_display_kwargs)

    assert grid.shape == expected_shape