Esempio n. 1
0
def compute_tcav_with_losses(input_tensor, losses, seed_input, wrt_tensor=None, grad_modifier='absolute'):
    """
    Args:
        input_tensor: An input tensor of shape: `(samples, channels, image_dims...)` if `image_data_format=
            channels_first` or `(samples, image_dims..., channels)` if `image_data_format=channels_last`.
        losses: List of ([Loss](vis.losses#Loss), weight) tuples.
        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)
            ### NB. Here we can introduce our fl(x). The gradients will be computed wrt that tensor.

        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')

    Returns:
        The normalized gradients of `seed_input` with respect to weighted `losses`.
        ### NB. Here you will have to add the dot product with the normalized direction
            of the concept vector.
    """
    #print ('wrt_tensor', wrt_tensor)

    from keras.layers import Reshape
    #wrt_tensor = Reshape((14,14,1024,))(wrt_tensor)
    #print 'wrt_tensor', wrt_tensor
    #return

    opt = Optimizer(input_tensor, losses, wrt_tensor=wrt_tensor, norm_grads=False)
    grads = opt.minimize(seed_input=seed_input, max_iter=1, grad_modifier=grad_modifier, verbose=False)[1]

    channel_idx = 1 if K.image_data_format() == 'channels_first' else -1
    #grads = np.max(grads, axis=channel_idx)
    return utils.normalize(grads)[0]
Esempio n. 2
0
def plot_multiple_saliency(images,
                           model,
                           layer,
                           filter_idx=None,
                           backprop_modifier=None,
                           grad_modifier=None):
    fig, ax = plt.subplots(2, len(images), figsize=(4 * len(images), 4))
    ax = ax.flatten()
    for i, filename in enumerate(images):
        image = load_img(filename,
                         target_size=(config.IMAGE_SIZE, config.IMAGE_SIZE))
        ax[i].imshow(image)
        ax[i].axis('off')
    for i, filename in enumerate(images):
        grad = visualize_saliency(model,
                                  find_layer_idx(model, layer),
                                  filter_idx,
                                  normalize(image),
                                  backprop_modifier=backprop_modifier,
                                  grad_modifier=grad_modifier)
        image = load_img(filename,
                         target_size=(config.IMAGE_SIZE, config.IMAGE_SIZE))
        ax[i + len(images)].imshow(overlay(grad, image))
        ax[i + len(images)].axis('off')
    return fig
 def compute_visualisation_mask(self, img):
     grad_modifier = 'absolute'
     grads = self.opt.minimize(seed_input=img, max_iter=1, grad_modifier=grad_modifier, verbose=False)[1]
     channel_idx = 1 if K.image_data_format() == 'channels_first' else -1
     grads = np.max(grads, axis=channel_idx)
     res = utils.normalize(grads)[0]
     return res
Esempio n. 4
0
def visualize_saliency_with_losses(input_tensor, losses, seed_input,original_img, grad_modifier='absolute',save_path=''):
    if not os.path.exists(save_path):
        os.mkdir(save_path)
    opt = Optimizer(input_tensor, losses, norm_grads=False)
    grads = opt.minimize(seed_input=seed_input, max_iter=1, grad_modifier=grad_modifier, verbose=False)[1]
    # print (np.shape(grads))

    channel_idx = 1 if K.image_data_format() == 'channels_first' else -1
    grads = np.max(grads, axis=channel_idx)
    # if not os.path.exists('./image'):
    #     os.mkdir('./images')

    print (np.shape(grads))
    for i in range(np.shape(grads)[1]):
        temp_grads = utils.normalize(grads[:,i,...])
        # print ('temp_grads',np.shape(temp_grads))
        heatmap = np.uint8(cm.jet(temp_grads)[..., :3] * 255)[0]
        img = original_img[i,...]

        temp = image.array_to_img(overlay(img, heatmap,alpha=0.5))
        pil.Image.save(temp,save_path+'overlay{}.jpg'.format(i))

        temp = image.array_to_img(heatmap)
        pil.Image.save(temp,save_path+'heatmap{}.jpg'.format(i))

        temp = image.array_to_img(img)
        pil.Image.save(temp,save_path+'original{}.jpg'.format(i))
Esempio n. 5
0
def plot_multiple_grad_cam(
        images,
        model,
        layer,
        penultimate_layer=None,
        filter_idx=None,
        backprop_modifier=None,
        grad_modifier=None,
        experts=None,
        expert_spacing=0.1,
):
    rows = 2
    if experts is not None:
        rows = 3
    fig, ax = plt.subplots(
        rows, len(images), figsize=(4 * len(images), 4 * rows))
    ax = ax.flatten()
    penultimate_layer_idx = None
    if penultimate_layer:
        penultimate_layer_idx = find_layer_idx(model, penultimate_layer)
    for i, filename in enumerate(images):
        image = load_img(
            filename, target_size=(config.IMAGE_SIZE, config.IMAGE_SIZE))
        ax[i].imshow(image)
        ax[i].axis('off')
    for i, filename in enumerate(images):
        image = load_img(
            filename, target_size=(config.IMAGE_SIZE, config.IMAGE_SIZE))
        grad = visualize_cam(
            model,
            find_layer_idx(model, layer),
            filter_idx,
            normalize(image),
            penultimate_layer_idx=penultimate_layer_idx,
            backprop_modifier=backprop_modifier,
            grad_modifier=grad_modifier)
        ax[i + len(images)].imshow(overlay(grad, image))
        ax[i + len(images)].axis('off')
    if experts:
        for i, filename in enumerate(images):
            for j, expert in enumerate(experts):
                if i == 0:
                    message = "expert {}: {}".format(j + 1, expert[i])
                    ax[i + 2 * len(images)].text(
                        0.3,
                        1 - (expert_spacing * j),
                        message,
                        horizontalalignment='left',
                        verticalalignment='center')
                else:
                    message = "{}".format(expert[i])
                    ax[i + 2 * len(images)].text(
                        0.5,
                        1 - (expert_spacing * j),
                        message,
                        horizontalalignment='center',
                        verticalalignment='center')
            ax[i + 2 * len(images)].axis('off')
    return fig, ax
Esempio n. 6
0
def plot_grad_cam(image_file,
                  model,
                  layer,
                  filter_idx=None,
                  backprop_modifier="relu"):
    image = load_img(image_file,
                     target_size=(config.IMAGE_SIZE, config.IMAGE_SIZE))
    grad = visualize_cam(model,
                         find_layer_idx(model, layer),
                         filter_idx,
                         normalize(image),
                         backprop_modifier=backprop_modifier)
    fig, ax = plt.subplots(1, 2)
    ax[0].imshow(overlay(grad, image))
    ax[0].axis('off')
    ax[1].imshow(image)
    ax[1].axis('off')
    return fig
def visualize_cam_with_losses(input_tensor,
                              losses,
                              seed_input,
                              penultimate_layer,
                              grad_modifier=None):
    """Generates a gradient based class activation map (CAM) by using positive gradients of `input_tensor`
    with respect to weighted `losses`.

    For details on grad-CAM, see the paper:
    [Grad-CAM: Why did you say that? Visual Explanations from Deep Networks via Gradient-based Localization]
    (https://arxiv.org/pdf/1610.02391v1.pdf).

    Unlike [class activation mapping](https://arxiv.org/pdf/1512.04150v1.pdf), which requires minor changes to
    network architecture in some instances, grad-CAM has a more general applicability.

    Compared to saliency maps, grad-CAM is class discriminative; i.e., the 'cat' explanation exclusively highlights
    cat regions and not the 'dog' region and vice-versa.

    Args:
        input_tensor: An input tensor of shape: `(samples, channels, image_dims...)` if `image_data_format=
            channels_first` or `(samples, image_dims..., channels)` if `image_data_format=channels_last`.
        losses: List of ([Loss](vis.losses#Loss), weight) tuples.
        seed_input: The model input for which activation map needs to be visualized.
        penultimate_layer: The pre-layer to `layer_idx` whose feature maps should be used to compute gradients
            with respect to filter output.
        grad_modifier: gradient modifier to use. See [grad_modifiers](vis.grad_modifiers.md). If you don't
            specify anything, gradients are unchanged (Default value = None)

    Returns:
        The normalized gradients of `seed_input` with respect to weighted `losses`.
    """
    penultimate_output = penultimate_layer.output
    opt = Optimizer(input_tensor,
                    losses,
                    wrt_tensor=penultimate_output,
                    norm_grads=False)
    _, grads, penultimate_output_value = opt.minimize(
        seed_input, max_iter=1, grad_modifier=grad_modifier, verbose=False)

    # For numerical stability. Very small grad values along with small penultimate_output_value can cause
    # w * penultimate_output_value to zero out, even for reasonable fp precision of float32.
    grads = grads / (np.max(grads) + K.epsilon())

    # Average pooling across all feature maps.
    # This captures the importance of feature map (channel) idx to the output.
    channel_idx = 1 if K.image_data_format() == 'channels_first' else -1
    other_axis = np.delete(np.arange(len(grads.shape)), channel_idx)
    weights = np.mean(grads, axis=tuple(other_axis))

    # Generate heatmap by computing weight * output over feature maps
    output_dims = utils.get_img_shape(penultimate_output)[2:]
    heatmap = np.zeros(shape=output_dims, dtype=K.floatx())
    for i, w in enumerate(weights):
        if channel_idx == -1:
            heatmap += w * penultimate_output_value[0, ..., i]
        else:
            heatmap += w * penultimate_output_value[0, i, ...]

    # ReLU thresholding to exclude pattern mismatch information (negative gradients).
    heatmap = np.maximum(heatmap, 0)

    # The penultimate feature map size is definitely smaller than input image.
    input_dims = utils.get_img_shape(input_tensor)[2:]

    # Figure out the zoom factor.
    zoom_factor = [
        i / (j * 1.0) for i, j in iter(zip(input_dims, output_dims))
    ]
    heatmap = zoom(heatmap, zoom_factor)
    return utils.normalize(heatmap)