Skip to content

Commit

Permalink
Merge pull request #16 from keisen/issues/#15
Browse files Browse the repository at this point in the history
Fixes Issues #15 and #8
  • Loading branch information
keisen authored Jun 19, 2020
2 parents a5b52c0 + 3c2e2f6 commit 248d2f5
Show file tree
Hide file tree
Showing 8 changed files with 44 additions and 33 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ venv.bak/
*.swp
examples/core*
examples/sandbox.ipynb
examples/workspace.ipynb
/*.ipynb
.node-version
*.nbconvert.ipynb
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
env: TF_VERSION=2.2.0 TF_KERAS_VIS_MAX_STEPS=2
install:
- pip install -U pip
- pip install -U --force-reinstall -e .[development,examples] tensorflow==$TF_VERSION
- pip install -U --force-reinstall -e .[develop,examples] tensorflow==$TF_VERSION
script:
- PYTHONPATH=$PWD:$PYTHONPATH py.test
- jupyter-nbconvert --ExecutePreprocessor.timeout=600 --to notebook --execute examples/attentions.ipynb
Expand Down
25 changes: 13 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,7 @@
[![Build Status](https://travis-ci.org/keisen/tf-keras-vis.svg?branch=master)](https://travis-ci.org/keisen/tf-keras-vis)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

tf-keras-vis is a visualization toolkit for debugging `tf.keras` models in Tensorflow2.

The features of tf-keras-vis are based on [keras-vis](https://github.com/raghakot/keras-vis), but tf-keras-vis's APIs doesn't have compatibility with keras-vis's, because we prioritized to get following features for our expriments.

- Support processing multiple images at a time as a batch
- Support tf.keras.Model that has multiple inputs (and, of course, multiple outpus too)
- Allow to use optimizers that embeded in tf.keras

tf-keras-vis is a visualization toolkit for debugging `tf.keras` models in Tensorflow2.0+.

## Visualizations

Expand All @@ -25,7 +18,14 @@ The features of tf-keras-vis are based on [keras-vis](https://github.com/raghako

### Saliency Map and GradCAM

<img src='https://github.com/keisen/tf-keras-vis/raw/master/examples/images/gradcam.png' width='400px' />
<img src='https://github.com/keisen/tf-keras-vis/raw/master/examples/images/gradcam.png' width='600px' />


These features are based on ones of [keras-vis](https://github.com/raghakot/keras-vis), but tf-keras-vis APIs doesn't have compatibility with keras-vis, because we prioritized to get following features for our expriments.

- Support processing multiple images at a time as a batch
- Support tf.keras.Model that has multiple inputs (and, of course, multiple outpus too)
- Allow to use optimizers that embeded in tf.keras


## Requirements
Expand Down Expand Up @@ -65,15 +65,16 @@ Please see [examples/attentions.ipynb](https://github.com/keisen/tf-keras-vis/bl
## Known Issues

* With InceptionV3, ActivationMaximization doesn't work well, that's, it might generate meanninglessly bulr image.
* With cascading model, Gradcam doesn't work well, that's, it might occur some error.
* Unsupported `channels-first` models and datas.
* With cascading model, Gradcam and Gradcam++ don't work well, that's, it might occur some error.
* Unsupport `channels-first` models and datas.


## ToDo
* API documentations
* We're going to add some algorisms such as below.
- [GradCAM++](https://arxiv.org/abs/1710.11063)
- [SmoothGrad: removing noise by adding noise](https://arxiv.org/pdf/1706.03825.pdf) (DONE)
- [GradCAM++](https://arxiv.org/abs/1710.11063)
- [ScoreCAM](https://arxiv.org/pdf/1910.01279.pdf)
- Deep Dream
- Style transfer

29 changes: 15 additions & 14 deletions examples/attentions.ipynb

Large diffs are not rendered by default.

Binary file modified examples/images/gradcam.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 2 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

setup(
name="tf-keras-vis",
version="0.3.1",
version="0.3.2",
author="keisen",
author_email="[email protected]",
description="Neural network visualization toolkit for tf.keras",
Expand All @@ -21,8 +21,7 @@
python_requires='>=3.5, <3.9',
install_requires=['numpy', 'scipy', 'imageio', 'pillow'],
extras_require={
'development':
['flake8', 'isort', 'yapf', 'pytest', 'pytest-pep8', 'pytest-xdist', 'pytest-cov'],
'develop': ['flake8', 'isort', 'yapf', 'pytest', 'pytest-pep8', 'pytest-cov'],
'examples': ['jupyterlab', 'matplotlib'],
},
include_package_data=True,
Expand Down
11 changes: 10 additions & 1 deletion tf_keras_vis/gradcam.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ def __call__(self,
penultimate_layer=-1,
seek_penultimate_conv_layer=True,
activation_modifier=lambda cam: K.relu(cam),
normalize_gradient=True):
normalize_gradient=True,
expand_cam=True):
"""Generate a gradient based class activation map (CAM) by using positive gradient of
penultimate_layer with respect to loss.
Expand All @@ -34,6 +35,10 @@ def __call__(self,
If False, the penultimate layer is that was elected by penultimate_layer index.
normalize_gradient: True to normalize gradients.
activation_modifier: A function to modify gradients.
expand_cam: True to expand cam to same as input image size.
![Note] Even if the model has multiple inputs, this function return only one cam
value (That's, when `expand_cam` is True, multiple cam images are generated from
a model that has multiple inputs).
# Returns
The heatmap image or a list of their images that indicate the `seed_input` regions
whose change would most contribute the loss value,
Expand All @@ -60,6 +65,10 @@ def __call__(self,
cam = np.asarray([np.sum(o * w, axis=-1) for o, w in zip(penultimate_output, weights)])
if activation_modifier is not None:
cam = activation_modifier(cam)

if not expand_cam:
return cam

# Visualizing
cam = self._zoom_for_visualizing(seed_inputs, cam)
if len(self.model.inputs) == 1 and not isinstance(seed_input, list):
Expand Down
4 changes: 2 additions & 2 deletions tf_keras_vis/utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ def listify(value, return_empty_list_if_none=True, convert_tuple_to_list=True):


def normalize(array, value_range=(1., 0.)):
max_value = np.max(array)
min_value = np.min(array)
max_value = np.max(array, axis=tuple(np.arange(len(array.shape))[1:]), keepdims=True)
min_value = np.min(array, axis=tuple(np.arange(len(array.shape))[1:]), keepdims=True)
normalized_array = (array - min_value) / (max_value - min_value + K.epsilon())
if value_range is None:
return normalized_array
Expand Down

0 comments on commit 248d2f5

Please sign in to comment.