Git Product home page Git Product logo

tf-explain's Introduction

tf-explain

Pypi Version DOI Build Status Documentation Status Python Versions Tensorflow Versions

tf-explain implements interpretability methods as Tensorflow 2.x callbacks to ease neural network's understanding. See Introducing tf-explain, Interpretability for Tensorflow 2.0

Documentation: https://tf-explain.readthedocs.io

Installation

tf-explain is available on PyPi. To install it:

virtualenv venv -p python3.8
pip install tf-explain

tf-explain is compatible with Tensorflow 2.x. It is not declared as a dependency to let you choose between full and standalone-CPU versions. Additionally to the previous install, run:

# For CPU or GPU
pip install tensorflow==2.6.0

Opencv is also a dependency. To install it, run:

# For CPU or GPU
pip install opencv-python

Quickstart

tf-explain offers 2 ways to apply interpretability methods. The full list of methods is the Available Methods section.

On trained model

The best option is probably to load a trained model and apply the methods on it.

# Load pretrained model or your own
model = tf.keras.applications.vgg16.VGG16(weights="imagenet", include_top=True)

# Load a sample image (or multiple ones)
img = tf.keras.preprocessing.image.load_img(IMAGE_PATH, target_size=(224, 224))
img = tf.keras.preprocessing.image.img_to_array(img)
data = ([img], None)

# Start explainer
explainer = GradCAM()
grid = explainer.explain(data, model, class_index=281)  # 281 is the tabby cat index in ImageNet

explainer.save(grid, ".", "grad_cam.png")

During training

If you want to follow your model during the training, you can also use it as a Keras Callback, and see the results directly in TensorBoard.

from tf_explain.callbacks.grad_cam import GradCAMCallback

model = [...]

callbacks = [
    GradCAMCallback(
        validation_data=(x_val, y_val),
        class_index=0,
        output_dir=output_dir,
    )
]

model.fit(x_train, y_train, batch_size=2, epochs=2, callbacks=callbacks)

Available Methods

  1. Activations Visualization
  2. Vanilla Gradients
  3. Gradients*Inputs
  4. Occlusion Sensitivity
  5. Grad CAM (Class Activation Maps)
  6. SmoothGrad
  7. Integrated Gradients

Activations Visualization

Visualize how a given input comes out of a specific activation layer

from tf_explain.callbacks.activations_visualization import ActivationsVisualizationCallback

model = [...]

callbacks = [
    ActivationsVisualizationCallback(
        validation_data=(x_val, y_val),
        layers_name=["activation_1"],
        output_dir=output_dir,
    ),
]

model.fit(x_train, y_train, batch_size=2, epochs=2, callbacks=callbacks)

Vanilla Gradients

Visualize gradients importance on input image

from tf_explain.callbacks.vanilla_gradients import VanillaGradientsCallback

model = [...]

callbacks = [
    VanillaGradientsCallback(
        validation_data=(x_val, y_val),
        class_index=0,
        output_dir=output_dir,
    ),
]

model.fit(x_train, y_train, batch_size=2, epochs=2, callbacks=callbacks)

Gradients*Inputs

Variant of Vanilla Gradients ponderating gradients with input values

from tf_explain.callbacks.gradients_inputs import GradientsInputsCallback

model = [...]

callbacks = [
    GradientsInputsCallback(
        validation_data=(x_val, y_val),
        class_index=0,
        output_dir=output_dir,
    ),
]

model.fit(x_train, y_train, batch_size=2, epochs=2, callbacks=callbacks)

Occlusion Sensitivity

Visualize how parts of the image affects neural network's confidence by occluding parts iteratively

from tf_explain.callbacks.occlusion_sensitivity import OcclusionSensitivityCallback

model = [...]

callbacks = [
    OcclusionSensitivityCallback(
        validation_data=(x_val, y_val),
        class_index=0,
        patch_size=4,
        output_dir=output_dir,
    ),
]

model.fit(x_train, y_train, batch_size=2, epochs=2, callbacks=callbacks)

Occlusion Sensitivity for Tabby class (stripes differentiate tabby cat from other ImageNet cat classes)

Grad CAM

Visualize how parts of the image affects neural network's output by looking into the activation maps

From Grad-CAM: Visual Explanations from Deep Networks via Gradient-based Localization

from tf_explain.callbacks.grad_cam import GradCAMCallback

model = [...]

callbacks = [
    GradCAMCallback(
        validation_data=(x_val, y_val),
        class_index=0,
        output_dir=output_dir,
    )
]

model.fit(x_train, y_train, batch_size=2, epochs=2, callbacks=callbacks)

SmoothGrad

Visualize stabilized gradients on the inputs towards the decision

From SmoothGrad: removing noise by adding noise

from tf_explain.callbacks.smoothgrad import SmoothGradCallback

model = [...]

callbacks = [
    SmoothGradCallback(
        validation_data=(x_val, y_val),
        class_index=0,
        num_samples=20,
        noise=1.,
        output_dir=output_dir,
    )
]

model.fit(x_train, y_train, batch_size=2, epochs=2, callbacks=callbacks)

Integrated Gradients

Visualize an average of the gradients along the construction of the input towards the decision

From Axiomatic Attribution for Deep Networks

from tf_explain.callbacks.integrated_gradients import IntegratedGradientsCallback

model = [...]

callbacks = [
    IntegratedGradientsCallback(
        validation_data=(x_val, y_val),
        class_index=0,
        n_steps=20,
        output_dir=output_dir,
    )
]

model.fit(x_train, y_train, batch_size=2, epochs=2, callbacks=callbacks)

Roadmap

Contributing

To contribute to the project, please read the dedicated section.

Citation

A citation file is available for citing this work. Click the "Cite this repository" button on the right-side panel of Github to get a BibTeX-ready citation.

tf-explain's People

Contributors

alexkubiesa avatar andife avatar antoinetoubhans avatar boussoffara avatar craymichael avatar ghazalee70 avatar jpsimen avatar lmontier avatar lukewood avatar mrm8488 avatar nicolattuso avatar raphaelmeudec avatar sdonatti avatar tauranis avatar twsl avatar vamsiucss avatar ywolff avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tf-explain's Issues

Do I necessarily tell the class index

Hi Thanks for this nice code.

I have to tell the code:

CAT_CLASS_INDEX = 281

is there any way that the code get the class-index automatically?

Many thanks.

Tests clean-up

Clean up all tests on the repo. Split to unit testing (tests are too large atm). Add pytest.mark on integration tests.

Explain Tabular

Hey,
Amazing work!

However, it seems that your library only works for image related models.
Would it be possible to implement also the version for "tabular data" ? Indeed, original work on integrated gradients that you are using wasn't only reserved to image models (ie https://github.com/hiranumn/IntegratedGradients). It would be wonderful if your library could be also usable for non image related models since theory is not related to images only.

Thanks anyway for all the work done, it is really useful !

Which layer to choose when using gradCAM

I am not sure which layer should be selected when using gradCAM.

This is my model description (from a YOLOv3 example - repo: https://github.com/YunYang1994/TensorFlow2.0-Examples/tree/master/4-Object_Detection/YOLOV3)

https://www.codepile.net/pile/mqk0b0yQ

If it is better I can also post the model description directly, but i think it looks messy like that.

#97 is related, if that would be added, someone casually using this wouldn't have to know, although it would still be cool that it is mentioned somewhere while starting execution and also some comments on this in documentation.

Any help would be great!!!

Normalize SmoothGrad by element instead of by grid

At the moment, SmoothGrad.transform_to_grayscale computes the min and max of the whole grid and normalizes it. This isn't great because it introduces a competition between images. Normalization should be done image by image.

Add cache on CI

Tox reinstall all dependencies at each run. This is taking most of the time of the CI and should be fixed by setting up some cache.

Heatmap display fails with rescaled image

In the heatmap_display function, original_image is assumed to be [0, 255]. For GradCAM, when running explain, the original image is passed to the model as well as heatmap_display. However, if the model takes a rescaled input, such as [0, 1], then the output will not display the image since it's using the rescaled image.

In the GradCAM example, change this line to:

img = tf.keras.preprocessing.image.img_to_array(img) / 255

and observe the output.

Centralize heatmap visualizations

At the moment, each callback implements its own visualization part. The objective is to centralize all those visualizations in a utils (like the grid_display)

Possible offset on Grad CAM visualization

When running the example on fashion mnist with a Grad CAM callback, it seems there could be a small offset (1 or 2 pixels) on the left.

image

To reproduce, just run the example with 5 epochs and observer Tensorboard

Validation Data Handle

Currently, there is no explanation on what validation_data is. This issue should tackle :

  • unification of validation_data between callbacks - make sure it has the same signature
  • callbacks currently process 1 image from validation data, it should process all of it

name 'GradCAM' is not defined

NameError Traceback (most recent call last)
in
----> 1 explainer = GradCAM()
2 grid = explainer.explain(data, model, class_index=np.argmax(preds[0]))

NameError: name 'GradCAM' is not defined

Compatibility with recursive models

Hi. First of all, kudos for the amazing initiative. Having something like as a Callback option in tf.keras is just amazing. However, as there are not any demo notebooks available currently to enable an interested developer to try out tf-explain, I was preparing one with a fine-tuned model using the CIFAR10 dataset. However, due to the lack of clarity on what to exactly specify in the layers_name argument while defining a callback, maybe I am getting an error after one epoch (error trace is attached
error_trace.txt
).

callbacks = [
    ActivationsVisualizationCallback(
        validation_data=(X_val, y_val),
        layers_name=["block5_conv1"],
        output_dir="logs",
    ),
] 

My notebook is available via Colab if you want to see. Let me know why is this happening if possible and I shall be able to prepare the notebook.

Callbacks Performance

Right now, predictions are generally done one by one instead of by batch. This issue should tackle this performance issue by predicting in batches.

Import Error for certain classes

  • Hi. I am trying to import from tf_explain.core.gradients_inputs but facing an error

image

The other imports such as
from tf_explain.core.grad_cam import GradCAM from tf_explain.core.activations import ExtractActivations

are working fine.

Unlink callbacks from the inner logic

At the moment, algorithm logic is implemented inside the callbacks, which makes it hard to use the algorithm logic outside of it. The idea is to create a core module with all the logic, and callbacks should call those modules instead of implementing it

GradCAM Gradients all zeros

GradientTape in the GradCAM method often outputs only zeros (in examples/callbacks/mnist.py), resulting in None heatmaps. This has to be investigated.

Capture d’écran de 2019-07-29 17-20-38

Opacity in heatmap_display causing improper display of gradCAM for small images(Ex:- CIFAR10)

Hi,

It appears the opacity parameter settings in heatmap_display are causing gradCAM to not properly superimpose on original images. This is specifically being seen when using CIFAR10 and small size data sets.

I think the following line needs a review in display.py file for heatmap_display function.

output = cv2.addWeighted(cv2.cvtColor(image, cv2.COLOR_RGB2BGR), 0.7, heatmap, 1, 0)

Thanks and Regards,
Sasikanth

No multiplicaton with inputs in integrated gradient?

In the integrated gradient paper, the formula for the ith dimension is:

image

But in your implementation, it looks like you never multiply with images (since you assume a zero-baseline). Is that intended? If so, could you explain the reasoning behind this?

Preprocessing image

Hi, thanks for great project. It works very well.

I have technical question about preprocessing the image for the cnn.

I looked into your examples, but normally every image which is input to VGG, ResNet, ... should be normalized before inferencing.

Why normalization is not applied here? The result of pretrained network in examples folder on not-normalized images can be wrong ....

Thank you!

Receive `validation_data` from `fit` argument

When validation_data is given to the model.fit method, it is also accessible in each callback with self.validation_data. We should gain from this, and pass our own validation_data argument as optional

Apply tf-explain to Cnn+LSTM model

Hello,
Thank for the work, very useful.
I am using a network like: CNN (feature extraction) + LSTM (sequence classification) and I would like to apply tf-explain to it. Is that possible in some way? How can I extend the idea of Grad-Cam (for example) to such a network?
Thanks in advance for the help,
Gabriele

Data is apparently uint8, causing an error for me

After loading MNIST or FASHION-MNIST, training proceeds to almost the and of the batch, then crashes with an error that uint8 provided as "input" is not in list of allowed datatypes.

Inserting after:

(train_images, train_labels), (test_images, test_labels) = dataset.load_data()

train_images = train_images.astype(np.float32)
test_images = test_images.astype(np.float32)

all works.

Support for Binary Classification Models

Hi, first of all thank you for tf-explain.

Currently I'm trying to use tf-explain with a model like this one:

model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Conv2D(initial_filters, kernel_size, activation='relu', input_shape=(256, 256, 3), padding="same")) 
model.add(tf.keras.layers.MaxPooling2D((2, 2))) # 128, 128
model.add(tf.keras.layers.Conv2D(initial_filters*2, kernel_size, activation='relu', padding="same"))
model.add(tf.keras.layers.MaxPooling2D((2, 2))) # 64, 64
model.add(tf.keras.layers.Conv2D(initial_filters*4, kernel_size, activation='relu', padding="same"))
model.add(tf.keras.layers.MaxPooling2D((2, 2))) # 32, 32
model.add(tf.keras.layers.Conv2D(initial_filters*8, kernel_size, activation='relu', padding="same"))
model.add(tf.keras.layers.MaxPooling2D((2, 2))) # 16, 16
model.add(tf.keras.layers.Conv2D(initial_filters*16, kernel_size, activation='relu', padding="same"))
model.add(tf.keras.layers.MaxPooling2D((2, 2))) # 8, 8
model.add(tf.keras.layers.Conv2D(initial_filters*32, kernel_size, activation='relu', padding="same"))
model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(64, activation="relu"))
model.add(tf.keras.layers.Dense(1))

This is a model used for a binary classification task for the cat vs dog dataset.
Using the tf-explain callback GradCAM does not seem to provide correct result.

I think this is due to the following line in the code:

https://github.com/sicara/tf-explain/blob/master/tf_explain/core/grad_cam.py#L85

where basically you take the index corresponding to the selected class.
A better approach would be to check the shape of the model output and:

  • if the class is 1 you can simply take the gradient of the output
  • if the class is 0 you can take the gradient of -output

What do you think about this issue and this (possible) fix?

Example or support for .fit_generator

I'm currently using the tensorflow.keras.preprocessing.image.ImageDataGenerator and the .flow_from_directory, which generates batches of data in order to finally use .fit_generator instead of .fit and I'm not too sure, how to implement the subset. An example would be awesome!

Lucid and your lib, tf-explain

Hi, I Found very interesting your lib and its interpretability approach, with callbacks, what allows for in training/testing interpretations.

Do you know Lucid, from Deep-Dream creators ?
https://github.com/tensorflow/lucid/

It seems that you two can contribute to each other, i also plan to do something in your direction for the future ...

thank you (there is mailing list for this type of message ?) sorry if it wasnt the right place

Smooth occlusion sensitivity map

At the moment, occlusion sensitivity callback generate an image with an output shape equal to the input shape. Part of the image are built directly by block. The objective is to smooth the visualization by generating only a map of size (H/patch_size, W/patch_size) and then resize it

[Grad-CAM] I'm continuously getting this error

The following is the model:

base_model = tf.keras.applications.vgg16.VGG16(weights='imagenet', include_top=False, input_shape = (48,52,3),classes = 11)
inputs = tf.keras.Input(shape=(48,52,3))
x = base_model.get_layer('block1_conv1')(inputs)
x = base_model.get_layer('block1_conv2')(x)
x = base_model.get_layer('block1_pool')(x)
x = base_model.get_layer('block2_conv1')(x)
y = Flatten()(x)
outputs = tf.keras.layers.Dense(11, activation=tf.nn.softmax)(y)
model = tf.keras.Model(inputs=inputs, outputs=outputs)
model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.001, decay=0.0002),
              loss=tf.keras.losses.SparseCategoricalCrossentropy(),
              metrics=[tf.keras.metrics.SparseCategoricalAccuracy()])

I tried both:

from tf_explain.callbacks.grad_cam import GradCAMCallback

callbacks = [
    GradCAMCallback(
      validation_data=(x_val,y_val),
        class_index=1,
        output_dir='../grad_cam'
    )]

model.fit(x1, y1, batch_size = 32, epochs = 1, verbose = True, callbacks = callbacks)

and also using model1 = tf.keras.models.Model([model.inputs],[model.get_layer('block2_conv1').output, model.output]) but I always get:

ValueError: Graph disconnected: cannot obtain value for tensor Tensor("input_1:0", shape=(None, 48, 52, 3), dtype=float32) at layer "input_1". The following previous layers were accessed without issue: ['input_2']

Gradients*Inputs

Explanation

This issue aims at implementing the Gradients*Inputs method.

At the moment, there is only the Vanilla Gradients which is implemented. The difference between Vanilla Gradients (VG) and GradientsInputs (GI) is that instead of returning the pure gradients for a given inputs, it returns the gradients ponderated by the input values.

The operation to perform is to take the input (shape HW3) and the gradients (shape HW3), and multiple each of the 3 channels to obtain the ponderated gradients (shape HW3). From there, we create a visualization (either HW3 or HW1).

How

Part 1: Create the core algorithm

  • Create a gradients_inputs.py file
  • Create a GradientsInputs class
  • Implement the .explain method
    • Signature should be (validation_data, model, class_index)
    • Complete docstring
    • Decompose images, _ = validation_data
    • Add a compute_gradients_dot_inputs() method in the class
    • This method should look familiar to the pure gradients one
    • Instead of returning the gradient.tape, multiply it by the inputs
    • Add the tf.function decorator
  • Implement the save method (check this PR)
  • Add unit test
  • Black / Linter
  • Add the method to tf_explain.core.__init__

Part 2: Add the corresponding callback

  • Add a tf_explain.callbacks.gradients_inputs
  • Implementation should be nearly the same as tf_explain.callbacks.gradients
  • Add it to tf_explain.callbacks.__init__
  • Unit test
  • Add the callback in tests/integration/test_keras_api.py
  • Black / Linter

Part 3: Examples, Docs

  • In examples.mnist, add the implemented callback
  • Run the mnist example and load Tensorboard. Make sure that the outputs seem relevant in the Images section of Tensorboard
  • Add a examples.core file for this method
  • Run the example and put the output image in docs/assets
  • Add the method in the README.md (follow the existing scheme)
  • Add the method in docs/source/methods

Checks

  • Test coverage is 100%
  • CI is running on Python 3.6 & 3.7
  • Docs build locally (cd docs/ & make html, then open build/html/index.html)
  • Screenshot of Tensorboard on the PR

OcclusionSensitivity callback issue - get stucks or index error

TF 2.1, tf-explain 0.2.0

Hello,

I'm using tf-explain (callbacks) on about 70.000 images, 56563, and two labels (0: 13%, 1: 87%), in order to explain class 0 classification. Whereas GradCAM works perfectly, I systematically have issues with OcclusionSensitivity.
With class_index=0, it gets stuck forever, with class_index=1 I get the following error message.

cb_gradcam = GradCAMCallback(
validation_data=(X_val, y_val),
class_index=1,
output_dir=log_dir)

cb_occlusion = OcclusionSensitivityCallback(
validation_data=(X_val, y_val),
class_index=1,
patch_size=4,
output_dir=log_dir)

model.fit(x=X_train_sc, y=y_train,
epochs=1,
batch_size=batch_size,
validation_split=0.2,
validation_freq=1,
use_multiprocessing=True,
callbacks=[tensorboard_callback, cb_occlusion],
)
--> with cb_gradcam I get good results in TensorBoard

Error for class_index=1 (and for class_index=0, just get stucks, no error message, but I have to kill the code) :


IndexError Traceback (most recent call last)
in
5 validation_freq=1,
6 use_multiprocessing=True,
----> 7 callbacks=[tensorboard_callback, cb_occlusion],
8
9 )

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/tensorflow_core/python/keras/engine/training.py in fit(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, validation_freq, max_queue_size, workers, use_multiprocessing, **kwargs)
817 max_queue_size=max_queue_size,
818 workers=workers,
--> 819 use_multiprocessing=use_multiprocessing)
820
821 def evaluate(self,

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/tensorflow_core/python/keras/engine/training_v2.py in fit(self, model, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, validation_freq, max_queue_size, workers, use_multiprocessing, **kwargs)
395 total_epochs=1)
396 cbks.make_logs(model, epoch_logs, eval_result, ModeKeys.TEST,
--> 397 prefix='val_')
398
399 return model.history

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/contextlib.py in exit(self, type, value, traceback)
117 if type is None:
118 try:
--> 119 next(self.gen)
120 except StopIteration:
121 return False

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/tensorflow_core/python/keras/engine/training_v2.py in on_epoch(self, epoch, mode)
769 if mode == ModeKeys.TRAIN:
770 # Epochs only apply to fit.
--> 771 self.callbacks.on_epoch_end(epoch, epoch_logs)
772 self.progbar.on_epoch_end(epoch, epoch_logs)
773

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/tensorflow_core/python/keras/callbacks.py in on_epoch_end(self, epoch, logs)
300 logs = logs or {}
301 for callback in self.callbacks:
--> 302 callback.on_epoch_end(epoch, logs)
303
304 def on_train_batch_begin(self, batch, logs=None):

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/tf_explain/callbacks/occlusion_sensitivity.py in on_epoch_end(self, epoch, logs)
54 explainer = OcclusionSensitivity()
55 grid = explainer.explain(
---> 56 self.validation_data, self.model, self.class_index, self.patch_size
57 )
58

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/tf_explain/core/occlusion_sensitivity.py in explain(self, validation_data, model, class_index, patch_size, colormap)
47 [
48 self.get_sensitivity_map(model, image, class_index, patch_size)
---> 49 for image in images
50 ]
51 )

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/tf_explain/core/occlusion_sensitivity.py in (.0)
47 [
48 self.get_sensitivity_map(model, image, class_index, patch_size)
---> 49 for image in images
50 ]
51 )

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/tf_explain/core/occlusion_sensitivity.py in get_sensitivity_map(self, model, image, class_index, patch_size)
96 predictions = model.predict(np.array(patches), batch_size=self.batch_size)
97 target_class_predictions = [
---> 98 prediction[class_index] for prediction in predictions
99 ]
100

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/tf_explain/core/occlusion_sensitivity.py in (.0)
96 predictions = model.predict(np.array(patches), batch_size=self.batch_size)
97 target_class_predictions = [
---> 98 prediction[class_index] for prediction in predictions
99 ]
100

IndexError: index 1 is out of bounds for axis 0 with size 1


Any help would be much appreciated ! Thanks

Error in transform_to_normalized_grayscale

I have been debugging some functions and I noticed that transform_to_normalized_grayscale defined in tf_explain/utils/image doesn't return a 4D tensor as described in function.

I think the channels axis is being totally disconsidered. So, the keepdims argument inside reduce_sum must be set to True, furthermore tf.reduce_sum would be properly changed by tf.math.reduce_sum.

In other words:

grayscale_tensor = tf.math.reduce_sum(tensor, axis=-1, keepdims=True)
instead of
grayscale_tensor = tf.reduce_sum(tensor, axis=-1)

Gradient is of type None

I'm trying to un GradCAM on my own model (modified VGG16 with input shape (1,100,100,3) and 5 classes).

When I try to run :

`# Instantiation of the explainer
explainer = GradCAM()

Call to explain() method

output = explainer.explain(validation_data, model, 'block5_conv3', 2)`

Then in the function get_gradients_and_filters(model, images, layer_name, class_index):

grads = tape.gradient(loss, conv_outputs)

grads is 'NoneType' so it cannot continue.

I'm not sure why I get this error.

Change image size on Tensorboard

Is there a way to change the images size on Tensorboard? I think they are very small to me and I can't have a good visualization.

Unguided Grad CAM

Atm, guided backpropagation is included in Grad CAM automatically (see here). The objective of this issue is to make optional this behaviour (but selected by default).

How to do so?

  • If you're not at ease with what Guided Backpropagation is, check the Class Activation Maps section in this article
  • Add a use_guided argument (boolean, default value True) to the .explain() method of Grad CAM
  • Pass the argument to the get_gradients_and_filters() method
  • Compute guidance only is use_guided is True
  • Add the argument use_guided to the corresponding callback, and pass it as argument to the explain() method
  • Add unit tests

When opening your PR, make sure to add some resulting visualizations.

Preprocessing function argument needed?

Hi, and thanks for the work on interpretability!

It may be a dumb question, but shouldn't the methods like OcclusionSensitivity, SmoothGrad and any interpretability method which use modified inputs have a preprocess_function argument?
I mean, technically, the preprocessing may be a step before the model (such as the preprocess function in keras for VGG-16) but change the distribution of the images.
And usually images are normalized, so applying a grey patch on them (for OcclusionSensitivity) does not make sense (for instance, if we have pixels with range between 0 and 1, the grey patch gives images with pixels equal to 127.5).

So I think a preprocess argument may be needed when a model relies on it before training, but I may have missed something.

In all cases, thanks for the hard work!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.