signxai


Namesignxai JSON
Version 1.1.9.2 PyPI version JSON
download
home_pagehttps://github.com/nilsgumpfer/SIGN-XAI
SummarySIGNed explanations: Unveiling relevant features by reducing bias
upload_time2024-10-24 09:41:58
maintainerNils Gumpfer
docs_urlNone
authorNils Gumpfer
requires_pythonNone
licenseBSD 2-Clause License
keywords xai sign lrp
VCS
bugtrack_url
requirements matplotlib tensorflow setuptools version-parser
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # SIGNed explanations: Unveiling relevant features by reducing bias

This repository and python package has been published alongside the following journal article:
https://doi.org/10.1016/j.inffus.2023.101883

If you use the code from this repository in your work, please cite:
```bibtex
 @article{Gumpfer2023SIGN,
    title = {SIGNed explanations: Unveiling relevant features by reducing bias},
    author = {Nils Gumpfer and Joshua Prim and Till Keller and Bernhard Seeger and Michael Guckert and Jennifer Hannig},
    journal = {Information Fusion},
    pages = {101883},
    year = {2023},
    issn = {1566-2535},
    doi = {https://doi.org/10.1016/j.inffus.2023.101883},
    url = {https://www.sciencedirect.com/science/article/pii/S1566253523001999}
}
```

<img src="https://ars.els-cdn.com/content/image/1-s2.0-S1566253523001999-ga1_lrg.jpg" title="Graphical Abstract" width="900px"/>

## Experiments

To reproduce the experiments from our paper, please find a detailed description on https://github.com/nilsgumpfer/SIGN.


## Setup

To install the package in your environment, run:

```shell
 pip3 install signxai
```


## Usage

### VGG16

The below example illustrates the usage of the ```signxai``` package in combination with a VGG16 model trained on imagenet:

```python
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.keras.applications.vgg16 import VGG16
from signxai.methods.wrappers import calculate_relevancemap
from signxai.utils.utils import (load_image, aggregate_and_normalize_relevancemap_rgb, download_image, 
                                 calculate_explanation_innvestigate)

# Load model
model = VGG16(weights='imagenet')

#  Remove last layer's softmax activation (we need the raw values!)
model.layers[-1].activation = None

# Load example image
path = 'example.jpg'
download_image(path)
img, x = load_image(path)

# Calculate relevancemaps
R1 = calculate_relevancemap('lrpz_epsilon_0_1_std_x', np.array(x), model)
R2 = calculate_relevancemap('lrpsign_epsilon_0_1_std_x', np.array(x), model)

# Equivalent relevance maps as for R1 and R2, but with direct access to innvestigate and parameters
R3 = calculate_explanation_innvestigate(model, x, method='lrp.stdxepsilon', stdfactor=0.1, input_layer_rule='Z')
R4 = calculate_explanation_innvestigate(model, x, method='lrp.stdxepsilon', stdfactor=0.1, input_layer_rule='SIGN')

# Visualize heatmaps
fig, axs = plt.subplots(ncols=3, nrows=2, figsize=(18, 12))
axs[0][0].imshow(img)
axs[1][0].imshow(img)
axs[0][1].matshow(aggregate_and_normalize_relevancemap_rgb(R1), cmap='seismic', clim=(-1, 1))
axs[0][2].matshow(aggregate_and_normalize_relevancemap_rgb(R2), cmap='seismic', clim=(-1, 1))
axs[1][1].matshow(aggregate_and_normalize_relevancemap_rgb(R3), cmap='seismic', clim=(-1, 1))
axs[1][2].matshow(aggregate_and_normalize_relevancemap_rgb(R4), cmap='seismic', clim=(-1, 1))

plt.show()
```
(Image credit for example used in this code: Greg Gjerdingen from Willmar, USA)

### MNIST

The below example illustrates the usage of the ```signxai``` package in combination with a dense model trained on MNIST:

```python
import numpy as np
from matplotlib import pyplot as plt
from tensorflow.python.keras.datasets import mnist
from tensorflow.python.keras.models import load_model

from signxai.methods.wrappers import calculate_relevancemap
from signxai.utils.utils import normalize_heatmap, download_model

# Load train and test data
(x_train, y_train), (x_test, y_test) = mnist.load_data()

# Scale images to the [-1, 0] range
x_train = x_train.astype("float32") / -255.0
x_test = x_test.astype("float32") / -255.0
x_train = -(np.ones_like(x_train) + x_train)
x_test = -(np.ones_like(x_test) + x_test)

# Load model
path = 'model.h5'
download_model(path)
model = load_model(path)

# Remove softmax
model.layers[-1].activation = None

# Calculate relevancemaps
x = x_test[231]
R1 = calculate_relevancemap('gradient_x_input', np.array(x), model, neuron_selection=3)
R2 = calculate_relevancemap('gradient_x_sign_mu_neg_0_5', np.array(x), model, neuron_selection=3)
R3 = calculate_relevancemap('gradient_x_input', np.array(x), model, neuron_selection=8)
R4 = calculate_relevancemap('gradient_x_sign_mu_neg_0_5', np.array(x), model, neuron_selection=8)

# Visualize heatmaps
fig, axs = plt.subplots(ncols=3, nrows=2, figsize=(18, 12))
axs[0][0].imshow(x, cmap='seismic', clim=(-1, 1))
axs[1][0].imshow(x, cmap='seismic', clim=(-1, 1))
axs[0][1].matshow(normalize_heatmap(R1), cmap='seismic', clim=(-1, 1))
axs[0][2].matshow(normalize_heatmap(R2), cmap='seismic', clim=(-1, 1))
axs[1][1].matshow(normalize_heatmap(R3), cmap='seismic', clim=(-1, 1))
axs[1][2].matshow(normalize_heatmap(R4), cmap='seismic', clim=(-1, 1))

plt.show()
```

## Methods

| Method | Base| Parameters |
|--------|-----------------------------------------|--------------------------------|
| gradient | Gradient | |
| input_t_gradient | Gradient x Input | |
| gradient_x_input | Gradient x Input | |
| gradient_x_sign | Gradient x SIGN  | mu = 0 |
| gradient_x_sign_mu | Gradient x SIGN  | requires *mu* parameter |
| gradient_x_sign_mu_0 | Gradient x SIGN  | mu = 0 |
| gradient_x_sign_mu_0_5 | Gradient x SIGN  | mu = 0.5 |
| gradient_x_sign_mu_neg_0_5 | Gradient x SIGN  | mu = -0.5 |
| guided_backprop | Guided Backpropagation | |
| guided_backprop_x_sign | Guided Backpropagation x SIGN  | mu = 0 |
| guided_backprop_x_sign_mu | Guided Backpropagation x SIGN  | requires *mu* parameter |
| guided_backprop_x_sign_mu_0 | Guided Backpropagation x SIGN  | mu = 0 |
| guided_backprop_x_sign_mu_0_5 | Guided Backpropagation x SIGN  | mu = 0.5 |
| guided_backprop_x_sign_mu_neg_0_5 | Guided Backpropagation x SIGN  | mu = -0.5 |
| integrated_gradients | Integrated Gradients | |
| smoothgrad | SmoothGrad | |
| smoothgrad_x_sign | SmoothGrad x SIGN  | mu = 0 |
| smoothgrad_x_sign_mu | SmoothGrad x SIGN  | requires *mu* parameter |
| smoothgrad_x_sign_mu_0 | SmoothGrad x SIGN  | mu = 0 |
| smoothgrad_x_sign_mu_0_5 | SmoothGrad x SIGN  | mu = 0.5  |
| smoothgrad_x_sign_mu_neg_0_5 | SmoothGrad x SIGN  | mu = -0.5  |
| vargrad | VarGrad  | |
| deconvnet | DeconvNet  | |
| deconvnet_x_sign | DeconvNet x SIGN | mu = 0 |
| deconvnet_x_sign_mu | DeconvNet x SIGN | requires *mu* parameter |
| deconvnet_x_sign_mu_0 | DeconvNet x SIGN | mu = 0 |
| deconvnet_x_sign_mu_0_5 | DeconvNet x SIGN | mu = 0.5 |
| deconvnet_x_sign_mu_neg_0_5 | DeconvNet x SIGN | mu = -0.5 |
| grad_cam | Grad-CAM| requires *last_conv* parameter |
| grad_cam_timeseries | Grad-CAM| (for time series data), requires *last_conv* parameter |
| grad_cam_VGG16ILSVRC | | *last_conv* based on VGG16 |
| guided_grad_cam_VGG16ILSVRC | | *last_conv* based on VGG16 |
| lrp_z | LRP-z  | |
| lrpsign_z | LRP-z / LRP-SIGN (Inputlayer-Rule) | |
| zblrp_z_VGG16ILSVRC | LRP-z / LRP-ZB (Inputlayer-Rule) | bounds based on ImageNet |
| w2lrp_z | LRP-z / LRP-w² (Inputlayer-Rule) | |
| flatlrp_z | LRP-z / LRP-flat (Inputlayer-Rule) | |
| lrp_epsilon_0_001 | LRP-epsilon | epsilon = 0.001 |
| lrpsign_epsilon_0_001 | LRP-epsilon / LRP-SIGN (Inputlayer-Rule) | epsilon = 0.001 |
| zblrp_epsilon_0_001_VGG16ILSVRC | LRP-epsilon / LRP-ZB (Inputlayer-Rule) | bounds based on ImageNet, epsilon = 0.001 |
| lrpz_epsilon_0_001 |LRP-epsilon / LRP-z (Inputlayer-Rule)  | epsilon = 0.001 |
| lrp_epsilon_0_01 | LRP-epsilon | epsilon = 0.01 |
| lrpsign_epsilon_0_01 | LRP-epsilon / LRP-SIGN (Inputlayer-Rule) | epsilon = 0.01 |
| zblrp_epsilon_0_01_VGG16ILSVRC | LRP-epsilon / LRP-ZB (Inputlayer-Rule) | bounds based on ImageNet, epsilon = 0.01 |
| lrpz_epsilon_0_01 | LRP-epsilon / LRP-z (Inputlayer-Rule)  | epsilon = 0.01 |
| w2lrp_epsilon_0_01 | LRP-epsilon / LRP-w² (Inputlayer-Rule)  | epsilon = 0.01 |
| flatlrp_epsilon_0_01 | LRP-epsilon / LRP-flat (Inputlayer-Rule)  | epsilon = 0.01 |
| lrp_epsilon_0_1 | LRP-epsilon | epsilon = 0.1 |
| lrpsign_epsilon_0_1 | LRP-epsilon / LRP-SIGN (Inputlayer-Rule) | epsilon = 0.1 |
| zblrp_epsilon_0_1_VGG16ILSVRC | LRP-epsilon / LRP-ZB (Inputlayer-Rule) | bounds based on ImageNet, epsilon = 0.1 |
| lrpz_epsilon_0_1 | LRP-epsilon / LRP-z (Inputlayer-Rule)  | epsilon = 0.1 |
| w2lrp_epsilon_0_1 | LRP-epsilon / LRP-w² (Inputlayer-Rule)  | epsilon = 0.1 |
| flatlrp_epsilon_0_1 | LRP-epsilon / LRP-flat (Inputlayer-Rule)  | epsilon = 0.1 |
| lrp_epsilon_0_2 | LRP-epsilon | epsilon = 0.2 |
| lrpsign_epsilon_0_2 | LRP-epsilon / LRP-SIGN (Inputlayer-Rule) | epsilon = 0.2 |
| zblrp_epsilon_0_2_VGG16ILSVRC | LRP-epsilon / LRP-ZB (Inputlayer-Rule) | bounds based on ImageNet, epsilon = 0.2 |
| lrpz_epsilon_0_2 | LRP-epsilon / LRP-z (Inputlayer-Rule)  | epsilon = 0.2 |
| lrp_epsilon_0_5 | LRP-epsilon | epsilon = 0.5 |
| lrpsign_epsilon_0_5 | LRP-epsilon / LRP-SIGN (Inputlayer-Rule) | epsilon = 0.5 |
| zblrp_epsilon_0_5_VGG16ILSVRC | LRP-epsilon / LRP-ZB (Inputlayer-Rule) | bounds based on ImageNet, epsilon = 0.5 |
| lrpz_epsilon_0_5 | LRP-epsilon / LRP-z (Inputlayer-Rule)  | epsilon = 0.5 |
| lrp_epsilon_1 | LRP-epsilon | epsilon = 1 |
| lrpsign_epsilon_1 | LRP-epsilon / LRP-SIGN (Inputlayer-Rule) | epsilon = 1 |
| zblrp_epsilon_1_VGG16ILSVRC | LRP-epsilon / LRP-ZB (Inputlayer-Rule) | bounds based on ImageNet, epsilon = 1 |
| lrpz_epsilon_1 | LRP-epsilon / LRP-z (Inputlayer-Rule)  | epsilon = 1 |
| w2lrp_epsilon_1 | LRP-epsilon / LRP-w² (Inputlayer-Rule)  | epsilon = 1 |
| flatlrp_epsilon_1 | LRP-epsilon / LRP-flat (Inputlayer-Rule)  | epsilon = 1 |
| lrp_epsilon_5 | LRP-epsilon | epsilon = 5 |
| lrpsign_epsilon_5 | LRP-epsilon / LRP-SIGN (Inputlayer-Rule) | epsilon = 5 |
| zblrp_epsilon_5_VGG16ILSVRC | LRP-epsilon / LRP-ZB (Inputlayer-Rule) | bounds based on ImageNet, epsilon = 5 |
| lrpz_epsilon_5 | LRP-epsilon / LRP-z (Inputlayer-Rule)  | epsilon = 5 |
| lrp_epsilon_10 | LRP-epsilon | epsilon = 10 |
| lrpsign_epsilon_10 | LRP-epsilon / LRP-SIGN (Inputlayer-Rule) | epsilon = 10 |
| zblrp_epsilon_10_VGG106ILSVRC | LRP-epsilon / LRP-ZB (Inputlayer-Rule) | bounds based on ImageNet, epsilon = 10 |
| lrpz_epsilon_10 | LRP-epsilon / LRP-z (Inputlayer-Rule)  | epsilon = 10 |
| w2lrp_epsilon_10 | LRP-epsilon / LRP-w² (Inputlayer-Rule)  | epsilon = 10 |
| flatlrp_epsilon_10 | LRP-epsilon / LRP-flat (Inputlayer-Rule)  | epsilon = 10 |
| lrp_epsilon_20 | LRP-epsilon | epsilon = 20 |
| lrpsign_epsilon_20 | LRP-epsilon / LRP-SIGN (Inputlayer-Rule) | epsilon = 20 |
| zblrp_epsilon_20_VGG206ILSVRC | LRP-epsilon / LRP-ZB (Inputlayer-Rule) | bounds based on ImageNet, epsilon = 20 |
| lrpz_epsilon_20 | LRP-epsilon / LRP-z (Inputlayer-Rule)  | epsilon = 20 |
| w2lrp_epsilon_20 | LRP-epsilon / LRP-w² (Inputlayer-Rule)  | epsilon = 20 |
| flatlrp_epsilon_20 | LRP-epsilon / LRP-flat (Inputlayer-Rule)  | epsilon = 20 |
| lrp_epsilon_50 | LRP-epsilon | epsilon = 50 |
| lrpsign_epsilon_50 | LRP-epsilon / LRP-SIGN (Inputlayer-Rule) | epsilon = 50 |
| lrpz_epsilon_50 | LRP-epsilon / LRP-z (Inputlayer-Rule)  | epsilon = 50 |
| lrp_epsilon_75 | LRP-epsilon | epsilon = 75 |
| lrpsign_epsilon_75 | LRP-epsilon / LRP-SIGN (Inputlayer-Rule) | epsilon = 75 |
| lrpz_epsilon_75 | LRP-epsilon / LRP-z (Inputlayer-Rule)  | epsilon = 75 |
| lrp_epsilon_100 | LRP-epsilon | epsilon = 100 |
| lrpsign_epsilon_100 | LRP-epsilon / LRP-SIGN (Inputlayer-Rule) | epsilon = 100, mu = 0 |
| lrpsign_epsilon_100_mu_0 | LRP-epsilon / LRP-SIGN (Inputlayer-Rule) | epsilon = 100, mu = 0 |
| lrpsign_epsilon_100_mu_0_5 | LRP-epsilon / LRP-SIGN (Inputlayer-Rule) | epsilon = 100, mu = 0.5 |
| lrpsign_epsilon_100_mu_neg_0_5 | LRP-epsilon / LRP-SIGN (Inputlayer-Rule) | epsilon = 100, mu = -0.5 |
| lrpz_epsilon_100 | LRP-epsilon / LRP-z (Inputlayer-Rule) | epsilon = 100 |
| zblrp_epsilon_100_VGG16ILSVRC | LRP-epsilon / LRP-ZB (Inputlayer-Rule) | bounds based on ImageNet, epsilon = 100 |
| w2lrp_epsilon_100 | LRP-epsilon / LRP-w² (Inputlayer-Rule) | epsilon = 100 |
| flatlrp_epsilon_100 | LRP-epsilon / LRP-flat (Inputlayer-Rule) | epsilon = 100 |
| lrp_epsilon_0_1_std_x | LRP-epsilon | epsilon = 0.1 * std(x) |
| lrpsign_epsilon_0_1_std_x | LRP-epsilon / LRP-SIGN (Inputlayer-Rule) | epsilon = 0.1 * std(x) |
| lrpz_epsilon_0_1_std_x | LRP-epsilon / LRP-z (Inputlayer-Rule) | epsilon = 0.1 * std(x) |
| zblrp_epsilon_0_1_std_x_VGG16ILSVRC | LRP-epsilon / LRP-ZB (Inputlayer-Rule) | bounds based on ImageNet, epsilon = 0.1 * std(x) |
| w2lrp_epsilon_0_1_std_x | LRP-epsilon / LRP-w² (Inputlayer-Rule) | epsilon = 0.1 * std(x) |
| flatlrp_epsilon_0_1_std_x | LRP-epsilon / LRP-flat (Inputlayer-Rule) | epsilon = 0.1 * std(x) |
| lrp_epsilon_0_25_std_x | LRP-epsilon | epsilon = 0.25 * std(x) |
| lrpsign_epsilon_0_25_std_x | LRP-epsilon / LRP-SIGN (Inputlayer-Rule) | epsilon = 0.25 * std(x), mu = 0 |
| lrpz_epsilon_0_25_std_x | LRP-epsilon / LRP-z (Inputlayer-Rule) | epsilon = 0.25 * std(x) |
| zblrp_epsilon_0_25_std_x_VGG256ILSVRC | LRP-epsilon / LRP-ZB (Inputlayer-Rule) | bounds based on ImageNet, epsilon = 0.25 * std(x) |
| w2lrp_epsilon_0_25_std_x | LRP-epsilon / LRP-w² (Inputlayer-Rule) | epsilon = 0.25 * std(x) |
| flatlrp_epsilon_0_25_std_x | LRP-epsilon / LRP-flat (Inputlayer-Rule) | epsilon = 0.25 * std(x) |
| lrpsign_epsilon_0_25_std_x_mu_0 | LRP-epsilon / LRP-SIGN (Inputlayer-Rule) | epsilon = 0.25 * std(x), mu = 0 |
| lrpsign_epsilon_0_25_std_x_mu_0_5 | LRP-epsilon / LRP-SIGN (Inputlayer-Rule) | epsilon = 0.25 * std(x), mu = 0.5 |
| lrpsign_epsilon_0_25_std_x_mu_neg_0_5 | LRP-epsilon / LRP-SIGN (Inputlayer-Rule) | epsilon = 0.25 * std(x), mu = -0.5 |
| lrp_epsilon_0_5_std_x | LRP-epsilon | epsilon = 0.5 * std(x) |
| lrpsign_epsilon_0_5_std_x | LRP-epsilon / LRP-SIGN (Inputlayer-Rule) | epsilon = 0.5 * std(x) |
| lrpz_epsilon_0_5_std_x | LRP-epsilon / LRP-z (Inputlayer-Rule) | epsilon = 0.5 * std(x) |
| zblrp_epsilon_0_5_std_x_VGG56ILSVRC | LRP-epsilon / LRP-ZB (Inputlayer-Rule) | bounds based on ImageNet, epsilon = 0.5 * std(x) |
| w2lrp_epsilon_0_5_std_x | LRP-epsilon / LRP-w² (Inputlayer-Rule) | epsilon = 0.5 * std(x) |
| flatlrp_epsilon_0_5_std_x | LRP-epsilon / LRP-flat (Inputlayer-Rule) | epsilon = 0.5 * std(x) |
| lrp_epsilon_1_std_x | LRP-epsilon | epsilon = 1 * std(x) |
| lrpsign_epsilon_1_std_x | LRP-epsilon / LRP-SIGN (Inputlayer-Rule) | epsilon = 1 * std(x), mu = 0 |
| lrpz_epsilon_1_std_x | LRP-epsilon / LRP-z (Inputlayer-Rule) | epsilon = 1 * std(x) |
| lrp_epsilon_2_std_x | LRP-epsilon | epsilon = 2 * std(x) |
| lrpsign_epsilon_2_std_x | LRP-epsilon / LRP-SIGN (Inputlayer-Rule) | epsilon = 2 * std(x), mu = 0 |
| lrpz_epsilon_2_std_x | LRP-epsilon / LRP-z (Inputlayer-Rule) | epsilon = 2 * std(x) |
| lrp_epsilon_3_std_x | LRP-epsilon | epsilon = 3 * std(x) |
| lrpsign_epsilon_3_std_x | LRP-epsilon / LRP-SIGN (Inputlayer-Rule) | epsilon = 3 * std(x), mu = 0 |
| lrpz_epsilon_3_std_x | LRP-epsilon / LRP-z (Inputlayer-Rule) | epsilon = 3 * std(x) |
| lrp_alpha_1_beta_0 | LRP-alpha-beta | alpha = 1, beta = 0 |
| lrpsign_alpha_1_beta_0 | LRP-alpha-beta / LRP-SIGN (Inputlayer-Rule) | alpha = 1, beta = 0, mu = 0 |
| lrpz_alpha_1_beta_0 | LRP-alpha-beta / LRP-z (Inputlayer-Rule) | alpha = 1, beta = 0 |
| zblrp_alpha_1_beta_0_VGG16ILSVRC |  | bounds based on ImageNet, alpha = 1, beta = 0 |
| w2lrp_alpha_1_beta_0 | LRP-alpha-beta / LRP-ZB (Inputlayer-Rule) | alpha = 1, beta = 0 |
| flatlrp_alpha_1_beta_0 | LRP-alpha-beta / LRP-flat (Inputlayer-Rule) | alpha = 1, beta = 0 |
| lrp_sequential_composite_a | LRP Comosite Variant A |  |
| lrpsign_sequential_composite_a | LRP Comosite Variant A / LRP-SIGN (Inputlayer-Rule) |  mu = 0 |
| lrpz_sequential_composite_a | LRP Comosite Variant A / LRP-z (Inputlayer-Rule) |  |
| zblrp_sequential_composite_a_VGG16ILSVRC |  | bounds based on ImageNet  |
| w2lrp_sequential_composite_a | LRP Comosite Variant A / LRP-ZB (Inputlayer-Rule) |  |
| flatlrp_sequential_composite_a | LRP Comosite Variant A / LRP-flat (Inputlayer-Rule) |  |
| lrp_sequential_composite_b | LRP Comosite Variant B |  |
| lrpsign_sequential_composite_b | LRP Comosite Variant B / LRP-SIGN (Inputlayer-Rule) |  mu = 0 |
| lrpz_sequential_composite_b | LRP Comosite Variant B / LRP-z (Inputlayer-Rule) |  |
| zblrp_sequential_composite_b_VGG16ILSVRC |  | bounds based on ImageNet  |
| w2lrp_sequential_composite_b | LRP Comosite Variant B / LRP-ZB (Inputlayer-Rule) |  |
| flatlrp_sequential_composite_b | LRP Comosite Variant B / LRP-flat (Inputlayer-Rule) |  |

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/nilsgumpfer/SIGN-XAI",
    "name": "signxai",
    "maintainer": "Nils Gumpfer",
    "docs_url": null,
    "requires_python": null,
    "maintainer_email": "nils.gumpfer@kite.thm.de",
    "keywords": "XAI, SIGN, LRP",
    "author": "Nils Gumpfer",
    "author_email": "nils.gumpfer@kite.thm.de",
    "download_url": "https://files.pythonhosted.org/packages/26/10/aaf16ed799dc1f4c25588d4f898c3ffe520bab3c547b12b0469437a71294/signxai-1.1.9.2.tar.gz",
    "platform": null,
    "description": "# SIGNed explanations: Unveiling relevant features by reducing bias\n\nThis repository and python package has been published alongside the following journal article:\nhttps://doi.org/10.1016/j.inffus.2023.101883\n\nIf you use the code from this repository in your work, please cite:\n```bibtex\n @article{Gumpfer2023SIGN,\n    title = {SIGNed explanations: Unveiling relevant features by reducing bias},\n    author = {Nils Gumpfer and Joshua Prim and Till Keller and Bernhard Seeger and Michael Guckert and Jennifer Hannig},\n    journal = {Information Fusion},\n    pages = {101883},\n    year = {2023},\n    issn = {1566-2535},\n    doi = {https://doi.org/10.1016/j.inffus.2023.101883},\n    url = {https://www.sciencedirect.com/science/article/pii/S1566253523001999}\n}\n```\n\n<img src=\"https://ars.els-cdn.com/content/image/1-s2.0-S1566253523001999-ga1_lrg.jpg\" title=\"Graphical Abstract\" width=\"900px\"/>\n\n## Experiments\n\nTo reproduce the experiments from our paper, please find a detailed description on https://github.com/nilsgumpfer/SIGN.\n\n\n## Setup\n\nTo install the package in your environment, run:\n\n```shell\n pip3 install signxai\n```\n\n\n## Usage\n\n### VGG16\n\nThe below example illustrates the usage of the ```signxai``` package in combination with a VGG16 model trained on imagenet:\n\n```python\nimport numpy as np\nimport matplotlib.pyplot as plt\nfrom tensorflow.keras.applications.vgg16 import VGG16\nfrom signxai.methods.wrappers import calculate_relevancemap\nfrom signxai.utils.utils import (load_image, aggregate_and_normalize_relevancemap_rgb, download_image, \n                                 calculate_explanation_innvestigate)\n\n# Load model\nmodel = VGG16(weights='imagenet')\n\n#  Remove last layer's softmax activation (we need the raw values!)\nmodel.layers[-1].activation = None\n\n# Load example image\npath = 'example.jpg'\ndownload_image(path)\nimg, x = load_image(path)\n\n# Calculate relevancemaps\nR1 = calculate_relevancemap('lrpz_epsilon_0_1_std_x', np.array(x), model)\nR2 = calculate_relevancemap('lrpsign_epsilon_0_1_std_x', np.array(x), model)\n\n# Equivalent relevance maps as for R1 and R2, but with direct access to innvestigate and parameters\nR3 = calculate_explanation_innvestigate(model, x, method='lrp.stdxepsilon', stdfactor=0.1, input_layer_rule='Z')\nR4 = calculate_explanation_innvestigate(model, x, method='lrp.stdxepsilon', stdfactor=0.1, input_layer_rule='SIGN')\n\n# Visualize heatmaps\nfig, axs = plt.subplots(ncols=3, nrows=2, figsize=(18, 12))\naxs[0][0].imshow(img)\naxs[1][0].imshow(img)\naxs[0][1].matshow(aggregate_and_normalize_relevancemap_rgb(R1), cmap='seismic', clim=(-1, 1))\naxs[0][2].matshow(aggregate_and_normalize_relevancemap_rgb(R2), cmap='seismic', clim=(-1, 1))\naxs[1][1].matshow(aggregate_and_normalize_relevancemap_rgb(R3), cmap='seismic', clim=(-1, 1))\naxs[1][2].matshow(aggregate_and_normalize_relevancemap_rgb(R4), cmap='seismic', clim=(-1, 1))\n\nplt.show()\n```\n(Image credit for example used in this code: Greg Gjerdingen from Willmar, USA)\n\n### MNIST\n\nThe below example illustrates the usage of the ```signxai``` package in combination with a dense model trained on MNIST:\n\n```python\nimport numpy as np\nfrom matplotlib import pyplot as plt\nfrom tensorflow.python.keras.datasets import mnist\nfrom tensorflow.python.keras.models import load_model\n\nfrom signxai.methods.wrappers import calculate_relevancemap\nfrom signxai.utils.utils import normalize_heatmap, download_model\n\n# Load train and test data\n(x_train, y_train), (x_test, y_test) = mnist.load_data()\n\n# Scale images to the [-1, 0] range\nx_train = x_train.astype(\"float32\") / -255.0\nx_test = x_test.astype(\"float32\") / -255.0\nx_train = -(np.ones_like(x_train) + x_train)\nx_test = -(np.ones_like(x_test) + x_test)\n\n# Load model\npath = 'model.h5'\ndownload_model(path)\nmodel = load_model(path)\n\n# Remove softmax\nmodel.layers[-1].activation = None\n\n# Calculate relevancemaps\nx = x_test[231]\nR1 = calculate_relevancemap('gradient_x_input', np.array(x), model, neuron_selection=3)\nR2 = calculate_relevancemap('gradient_x_sign_mu_neg_0_5', np.array(x), model, neuron_selection=3)\nR3 = calculate_relevancemap('gradient_x_input', np.array(x), model, neuron_selection=8)\nR4 = calculate_relevancemap('gradient_x_sign_mu_neg_0_5', np.array(x), model, neuron_selection=8)\n\n# Visualize heatmaps\nfig, axs = plt.subplots(ncols=3, nrows=2, figsize=(18, 12))\naxs[0][0].imshow(x, cmap='seismic', clim=(-1, 1))\naxs[1][0].imshow(x, cmap='seismic', clim=(-1, 1))\naxs[0][1].matshow(normalize_heatmap(R1), cmap='seismic', clim=(-1, 1))\naxs[0][2].matshow(normalize_heatmap(R2), cmap='seismic', clim=(-1, 1))\naxs[1][1].matshow(normalize_heatmap(R3), cmap='seismic', clim=(-1, 1))\naxs[1][2].matshow(normalize_heatmap(R4), cmap='seismic', clim=(-1, 1))\n\nplt.show()\n```\n\n## Methods\n\n| Method | Base| Parameters |\n|--------|-----------------------------------------|--------------------------------|\n| gradient | Gradient | |\n| input_t_gradient | Gradient x Input | |\n| gradient_x_input | Gradient x Input | |\n| gradient_x_sign | Gradient x SIGN  | mu = 0 |\n| gradient_x_sign_mu | Gradient x SIGN  | requires *mu* parameter |\n| gradient_x_sign_mu_0 | Gradient x SIGN  | mu = 0 |\n| gradient_x_sign_mu_0_5 | Gradient x SIGN  | mu = 0.5 |\n| gradient_x_sign_mu_neg_0_5 | Gradient x SIGN  | mu = -0.5 |\n| guided_backprop | Guided Backpropagation | |\n| guided_backprop_x_sign | Guided Backpropagation x SIGN  | mu = 0 |\n| guided_backprop_x_sign_mu | Guided Backpropagation x SIGN  | requires *mu* parameter |\n| guided_backprop_x_sign_mu_0 | Guided Backpropagation x SIGN  | mu = 0 |\n| guided_backprop_x_sign_mu_0_5 | Guided Backpropagation x SIGN  | mu = 0.5 |\n| guided_backprop_x_sign_mu_neg_0_5 | Guided Backpropagation x SIGN  | mu = -0.5 |\n| integrated_gradients | Integrated Gradients | |\n| smoothgrad | SmoothGrad | |\n| smoothgrad_x_sign | SmoothGrad x SIGN  | mu = 0 |\n| smoothgrad_x_sign_mu | SmoothGrad x SIGN  | requires *mu* parameter |\n| smoothgrad_x_sign_mu_0 | SmoothGrad x SIGN  | mu = 0 |\n| smoothgrad_x_sign_mu_0_5 | SmoothGrad x SIGN  | mu = 0.5  |\n| smoothgrad_x_sign_mu_neg_0_5 | SmoothGrad x SIGN  | mu = -0.5  |\n| vargrad | VarGrad  | |\n| deconvnet | DeconvNet  | |\n| deconvnet_x_sign | DeconvNet x SIGN | mu = 0 |\n| deconvnet_x_sign_mu | DeconvNet x SIGN | requires *mu* parameter |\n| deconvnet_x_sign_mu_0 | DeconvNet x SIGN | mu = 0 |\n| deconvnet_x_sign_mu_0_5 | DeconvNet x SIGN | mu = 0.5 |\n| deconvnet_x_sign_mu_neg_0_5 | DeconvNet x SIGN | mu = -0.5 |\n| grad_cam | Grad-CAM| requires *last_conv* parameter |\n| grad_cam_timeseries | Grad-CAM| (for time series data), requires *last_conv* parameter |\n| grad_cam_VGG16ILSVRC | | *last_conv* based on VGG16 |\n| guided_grad_cam_VGG16ILSVRC | | *last_conv* based on VGG16 |\n| lrp_z | LRP-z  | |\n| lrpsign_z | LRP-z / LRP-SIGN (Inputlayer-Rule) | |\n| zblrp_z_VGG16ILSVRC | LRP-z / LRP-ZB (Inputlayer-Rule) | bounds based on ImageNet |\n| w2lrp_z | LRP-z / LRP-w\u00b2 (Inputlayer-Rule) | |\n| flatlrp_z | LRP-z / LRP-flat (Inputlayer-Rule) | |\n| lrp_epsilon_0_001 | LRP-epsilon | epsilon = 0.001 |\n| lrpsign_epsilon_0_001 | LRP-epsilon / LRP-SIGN (Inputlayer-Rule) | epsilon = 0.001 |\n| zblrp_epsilon_0_001_VGG16ILSVRC | LRP-epsilon / LRP-ZB (Inputlayer-Rule) | bounds based on ImageNet, epsilon = 0.001 |\n| lrpz_epsilon_0_001 |LRP-epsilon / LRP-z (Inputlayer-Rule)  | epsilon = 0.001 |\n| lrp_epsilon_0_01 | LRP-epsilon | epsilon = 0.01 |\n| lrpsign_epsilon_0_01 | LRP-epsilon / LRP-SIGN (Inputlayer-Rule) | epsilon = 0.01 |\n| zblrp_epsilon_0_01_VGG16ILSVRC | LRP-epsilon / LRP-ZB (Inputlayer-Rule) | bounds based on ImageNet, epsilon = 0.01 |\n| lrpz_epsilon_0_01 | LRP-epsilon / LRP-z (Inputlayer-Rule)  | epsilon = 0.01 |\n| w2lrp_epsilon_0_01 | LRP-epsilon / LRP-w\u00b2 (Inputlayer-Rule)  | epsilon = 0.01 |\n| flatlrp_epsilon_0_01 | LRP-epsilon / LRP-flat (Inputlayer-Rule)  | epsilon = 0.01 |\n| lrp_epsilon_0_1 | LRP-epsilon | epsilon = 0.1 |\n| lrpsign_epsilon_0_1 | LRP-epsilon / LRP-SIGN (Inputlayer-Rule) | epsilon = 0.1 |\n| zblrp_epsilon_0_1_VGG16ILSVRC | LRP-epsilon / LRP-ZB (Inputlayer-Rule) | bounds based on ImageNet, epsilon = 0.1 |\n| lrpz_epsilon_0_1 | LRP-epsilon / LRP-z (Inputlayer-Rule)  | epsilon = 0.1 |\n| w2lrp_epsilon_0_1 | LRP-epsilon / LRP-w\u00b2 (Inputlayer-Rule)  | epsilon = 0.1 |\n| flatlrp_epsilon_0_1 | LRP-epsilon / LRP-flat (Inputlayer-Rule)  | epsilon = 0.1 |\n| lrp_epsilon_0_2 | LRP-epsilon | epsilon = 0.2 |\n| lrpsign_epsilon_0_2 | LRP-epsilon / LRP-SIGN (Inputlayer-Rule) | epsilon = 0.2 |\n| zblrp_epsilon_0_2_VGG16ILSVRC | LRP-epsilon / LRP-ZB (Inputlayer-Rule) | bounds based on ImageNet, epsilon = 0.2 |\n| lrpz_epsilon_0_2 | LRP-epsilon / LRP-z (Inputlayer-Rule)  | epsilon = 0.2 |\n| lrp_epsilon_0_5 | LRP-epsilon | epsilon = 0.5 |\n| lrpsign_epsilon_0_5 | LRP-epsilon / LRP-SIGN (Inputlayer-Rule) | epsilon = 0.5 |\n| zblrp_epsilon_0_5_VGG16ILSVRC | LRP-epsilon / LRP-ZB (Inputlayer-Rule) | bounds based on ImageNet, epsilon = 0.5 |\n| lrpz_epsilon_0_5 | LRP-epsilon / LRP-z (Inputlayer-Rule)  | epsilon = 0.5 |\n| lrp_epsilon_1 | LRP-epsilon | epsilon = 1 |\n| lrpsign_epsilon_1 | LRP-epsilon / LRP-SIGN (Inputlayer-Rule) | epsilon = 1 |\n| zblrp_epsilon_1_VGG16ILSVRC | LRP-epsilon / LRP-ZB (Inputlayer-Rule) | bounds based on ImageNet, epsilon = 1 |\n| lrpz_epsilon_1 | LRP-epsilon / LRP-z (Inputlayer-Rule)  | epsilon = 1 |\n| w2lrp_epsilon_1 | LRP-epsilon / LRP-w\u00b2 (Inputlayer-Rule)  | epsilon = 1 |\n| flatlrp_epsilon_1 | LRP-epsilon / LRP-flat (Inputlayer-Rule)  | epsilon = 1 |\n| lrp_epsilon_5 | LRP-epsilon | epsilon = 5 |\n| lrpsign_epsilon_5 | LRP-epsilon / LRP-SIGN (Inputlayer-Rule) | epsilon = 5 |\n| zblrp_epsilon_5_VGG16ILSVRC | LRP-epsilon / LRP-ZB (Inputlayer-Rule) | bounds based on ImageNet, epsilon = 5 |\n| lrpz_epsilon_5 | LRP-epsilon / LRP-z (Inputlayer-Rule)  | epsilon = 5 |\n| lrp_epsilon_10 | LRP-epsilon | epsilon = 10 |\n| lrpsign_epsilon_10 | LRP-epsilon / LRP-SIGN (Inputlayer-Rule) | epsilon = 10 |\n| zblrp_epsilon_10_VGG106ILSVRC | LRP-epsilon / LRP-ZB (Inputlayer-Rule) | bounds based on ImageNet, epsilon = 10 |\n| lrpz_epsilon_10 | LRP-epsilon / LRP-z (Inputlayer-Rule)  | epsilon = 10 |\n| w2lrp_epsilon_10 | LRP-epsilon / LRP-w\u00b2 (Inputlayer-Rule)  | epsilon = 10 |\n| flatlrp_epsilon_10 | LRP-epsilon / LRP-flat (Inputlayer-Rule)  | epsilon = 10 |\n| lrp_epsilon_20 | LRP-epsilon | epsilon = 20 |\n| lrpsign_epsilon_20 | LRP-epsilon / LRP-SIGN (Inputlayer-Rule) | epsilon = 20 |\n| zblrp_epsilon_20_VGG206ILSVRC | LRP-epsilon / LRP-ZB (Inputlayer-Rule) | bounds based on ImageNet, epsilon = 20 |\n| lrpz_epsilon_20 | LRP-epsilon / LRP-z (Inputlayer-Rule)  | epsilon = 20 |\n| w2lrp_epsilon_20 | LRP-epsilon / LRP-w\u00b2 (Inputlayer-Rule)  | epsilon = 20 |\n| flatlrp_epsilon_20 | LRP-epsilon / LRP-flat (Inputlayer-Rule)  | epsilon = 20 |\n| lrp_epsilon_50 | LRP-epsilon | epsilon = 50 |\n| lrpsign_epsilon_50 | LRP-epsilon / LRP-SIGN (Inputlayer-Rule) | epsilon = 50 |\n| lrpz_epsilon_50 | LRP-epsilon / LRP-z (Inputlayer-Rule)  | epsilon = 50 |\n| lrp_epsilon_75 | LRP-epsilon | epsilon = 75 |\n| lrpsign_epsilon_75 | LRP-epsilon / LRP-SIGN (Inputlayer-Rule) | epsilon = 75 |\n| lrpz_epsilon_75 | LRP-epsilon / LRP-z (Inputlayer-Rule)  | epsilon = 75 |\n| lrp_epsilon_100 | LRP-epsilon | epsilon = 100 |\n| lrpsign_epsilon_100 | LRP-epsilon / LRP-SIGN (Inputlayer-Rule) | epsilon = 100, mu = 0 |\n| lrpsign_epsilon_100_mu_0 | LRP-epsilon / LRP-SIGN (Inputlayer-Rule) | epsilon = 100, mu = 0 |\n| lrpsign_epsilon_100_mu_0_5 | LRP-epsilon / LRP-SIGN (Inputlayer-Rule) | epsilon = 100, mu = 0.5 |\n| lrpsign_epsilon_100_mu_neg_0_5 | LRP-epsilon / LRP-SIGN (Inputlayer-Rule) | epsilon = 100, mu = -0.5 |\n| lrpz_epsilon_100 | LRP-epsilon / LRP-z (Inputlayer-Rule) | epsilon = 100 |\n| zblrp_epsilon_100_VGG16ILSVRC | LRP-epsilon / LRP-ZB (Inputlayer-Rule) | bounds based on ImageNet, epsilon = 100 |\n| w2lrp_epsilon_100 | LRP-epsilon / LRP-w\u00b2 (Inputlayer-Rule) | epsilon = 100 |\n| flatlrp_epsilon_100 | LRP-epsilon / LRP-flat (Inputlayer-Rule) | epsilon = 100 |\n| lrp_epsilon_0_1_std_x | LRP-epsilon | epsilon = 0.1 * std(x) |\n| lrpsign_epsilon_0_1_std_x | LRP-epsilon / LRP-SIGN (Inputlayer-Rule) | epsilon = 0.1 * std(x) |\n| lrpz_epsilon_0_1_std_x | LRP-epsilon / LRP-z (Inputlayer-Rule) | epsilon = 0.1 * std(x) |\n| zblrp_epsilon_0_1_std_x_VGG16ILSVRC | LRP-epsilon / LRP-ZB (Inputlayer-Rule) | bounds based on ImageNet, epsilon = 0.1 * std(x) |\n| w2lrp_epsilon_0_1_std_x | LRP-epsilon / LRP-w\u00b2 (Inputlayer-Rule) | epsilon = 0.1 * std(x) |\n| flatlrp_epsilon_0_1_std_x | LRP-epsilon / LRP-flat (Inputlayer-Rule) | epsilon = 0.1 * std(x) |\n| lrp_epsilon_0_25_std_x | LRP-epsilon | epsilon = 0.25 * std(x) |\n| lrpsign_epsilon_0_25_std_x | LRP-epsilon / LRP-SIGN (Inputlayer-Rule) | epsilon = 0.25 * std(x), mu = 0 |\n| lrpz_epsilon_0_25_std_x | LRP-epsilon / LRP-z (Inputlayer-Rule) | epsilon = 0.25 * std(x) |\n| zblrp_epsilon_0_25_std_x_VGG256ILSVRC | LRP-epsilon / LRP-ZB (Inputlayer-Rule) | bounds based on ImageNet, epsilon = 0.25 * std(x) |\n| w2lrp_epsilon_0_25_std_x | LRP-epsilon / LRP-w\u00b2 (Inputlayer-Rule) | epsilon = 0.25 * std(x) |\n| flatlrp_epsilon_0_25_std_x | LRP-epsilon / LRP-flat (Inputlayer-Rule) | epsilon = 0.25 * std(x) |\n| lrpsign_epsilon_0_25_std_x_mu_0 | LRP-epsilon / LRP-SIGN (Inputlayer-Rule) | epsilon = 0.25 * std(x), mu = 0 |\n| lrpsign_epsilon_0_25_std_x_mu_0_5 | LRP-epsilon / LRP-SIGN (Inputlayer-Rule) | epsilon = 0.25 * std(x), mu = 0.5 |\n| lrpsign_epsilon_0_25_std_x_mu_neg_0_5 | LRP-epsilon / LRP-SIGN (Inputlayer-Rule) | epsilon = 0.25 * std(x), mu = -0.5 |\n| lrp_epsilon_0_5_std_x | LRP-epsilon | epsilon = 0.5 * std(x) |\n| lrpsign_epsilon_0_5_std_x | LRP-epsilon / LRP-SIGN (Inputlayer-Rule) | epsilon = 0.5 * std(x) |\n| lrpz_epsilon_0_5_std_x | LRP-epsilon / LRP-z (Inputlayer-Rule) | epsilon = 0.5 * std(x) |\n| zblrp_epsilon_0_5_std_x_VGG56ILSVRC | LRP-epsilon / LRP-ZB (Inputlayer-Rule) | bounds based on ImageNet, epsilon = 0.5 * std(x) |\n| w2lrp_epsilon_0_5_std_x | LRP-epsilon / LRP-w\u00b2 (Inputlayer-Rule) | epsilon = 0.5 * std(x) |\n| flatlrp_epsilon_0_5_std_x | LRP-epsilon / LRP-flat (Inputlayer-Rule) | epsilon = 0.5 * std(x) |\n| lrp_epsilon_1_std_x | LRP-epsilon | epsilon = 1 * std(x) |\n| lrpsign_epsilon_1_std_x | LRP-epsilon / LRP-SIGN (Inputlayer-Rule) | epsilon = 1 * std(x), mu = 0 |\n| lrpz_epsilon_1_std_x | LRP-epsilon / LRP-z (Inputlayer-Rule) | epsilon = 1 * std(x) |\n| lrp_epsilon_2_std_x | LRP-epsilon | epsilon = 2 * std(x) |\n| lrpsign_epsilon_2_std_x | LRP-epsilon / LRP-SIGN (Inputlayer-Rule) | epsilon = 2 * std(x), mu = 0 |\n| lrpz_epsilon_2_std_x | LRP-epsilon / LRP-z (Inputlayer-Rule) | epsilon = 2 * std(x) |\n| lrp_epsilon_3_std_x | LRP-epsilon | epsilon = 3 * std(x) |\n| lrpsign_epsilon_3_std_x | LRP-epsilon / LRP-SIGN (Inputlayer-Rule) | epsilon = 3 * std(x), mu = 0 |\n| lrpz_epsilon_3_std_x | LRP-epsilon / LRP-z (Inputlayer-Rule) | epsilon = 3 * std(x) |\n| lrp_alpha_1_beta_0 | LRP-alpha-beta | alpha = 1, beta = 0 |\n| lrpsign_alpha_1_beta_0 | LRP-alpha-beta / LRP-SIGN (Inputlayer-Rule) | alpha = 1, beta = 0, mu = 0 |\n| lrpz_alpha_1_beta_0 | LRP-alpha-beta / LRP-z (Inputlayer-Rule) | alpha = 1, beta = 0 |\n| zblrp_alpha_1_beta_0_VGG16ILSVRC |  | bounds based on ImageNet, alpha = 1, beta = 0 |\n| w2lrp_alpha_1_beta_0 | LRP-alpha-beta / LRP-ZB (Inputlayer-Rule) | alpha = 1, beta = 0 |\n| flatlrp_alpha_1_beta_0 | LRP-alpha-beta / LRP-flat (Inputlayer-Rule) | alpha = 1, beta = 0 |\n| lrp_sequential_composite_a | LRP Comosite Variant A |  |\n| lrpsign_sequential_composite_a | LRP Comosite Variant A / LRP-SIGN (Inputlayer-Rule) |  mu = 0 |\n| lrpz_sequential_composite_a | LRP Comosite Variant A / LRP-z (Inputlayer-Rule) |  |\n| zblrp_sequential_composite_a_VGG16ILSVRC |  | bounds based on ImageNet  |\n| w2lrp_sequential_composite_a | LRP Comosite Variant A / LRP-ZB (Inputlayer-Rule) |  |\n| flatlrp_sequential_composite_a | LRP Comosite Variant A / LRP-flat (Inputlayer-Rule) |  |\n| lrp_sequential_composite_b | LRP Comosite Variant B |  |\n| lrpsign_sequential_composite_b | LRP Comosite Variant B / LRP-SIGN (Inputlayer-Rule) |  mu = 0 |\n| lrpz_sequential_composite_b | LRP Comosite Variant B / LRP-z (Inputlayer-Rule) |  |\n| zblrp_sequential_composite_b_VGG16ILSVRC |  | bounds based on ImageNet  |\n| w2lrp_sequential_composite_b | LRP Comosite Variant B / LRP-ZB (Inputlayer-Rule) |  |\n| flatlrp_sequential_composite_b | LRP Comosite Variant B / LRP-flat (Inputlayer-Rule) |  |\n",
    "bugtrack_url": null,
    "license": "BSD 2-Clause License",
    "summary": "SIGNed explanations: Unveiling relevant features by reducing bias",
    "version": "1.1.9.2",
    "project_urls": {
        "Homepage": "https://github.com/nilsgumpfer/SIGN-XAI"
    },
    "split_keywords": [
        "xai",
        " sign",
        " lrp"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "95de861d8859fe3191359cc37a0936d265c85a4a50c913e833d2f70dbd5ee87c",
                "md5": "9eae6eebf5a4fb63053e0947e2cc63a8",
                "sha256": "2625875a73ffbb261def39a4640f2bd7c5497ca9181f9177e67156933ef6c181"
            },
            "downloads": -1,
            "filename": "signxai-1.1.9.2-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "9eae6eebf5a4fb63053e0947e2cc63a8",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": null,
            "size": 111614,
            "upload_time": "2024-10-24T09:41:57",
            "upload_time_iso_8601": "2024-10-24T09:41:57.079302Z",
            "url": "https://files.pythonhosted.org/packages/95/de/861d8859fe3191359cc37a0936d265c85a4a50c913e833d2f70dbd5ee87c/signxai-1.1.9.2-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "2610aaf16ed799dc1f4c25588d4f898c3ffe520bab3c547b12b0469437a71294",
                "md5": "f2cc1d92e02b3e3ff8eaa9852f58b4d7",
                "sha256": "b6b4bb1da00be3f3590e8c4b69553604abecd318cfdfc6a146d618508c36d274"
            },
            "downloads": -1,
            "filename": "signxai-1.1.9.2.tar.gz",
            "has_sig": false,
            "md5_digest": "f2cc1d92e02b3e3ff8eaa9852f58b4d7",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 89091,
            "upload_time": "2024-10-24T09:41:58",
            "upload_time_iso_8601": "2024-10-24T09:41:58.430705Z",
            "url": "https://files.pythonhosted.org/packages/26/10/aaf16ed799dc1f4c25588d4f898c3ffe520bab3c547b12b0469437a71294/signxai-1.1.9.2.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-10-24 09:41:58",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "nilsgumpfer",
    "github_project": "SIGN-XAI",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "requirements": [
        {
            "name": "matplotlib",
            "specs": [
                [
                    "~=",
                    "3.7.2"
                ]
            ]
        },
        {
            "name": "tensorflow",
            "specs": [
                [
                    "~=",
                    "2.8.4"
                ]
            ]
        },
        {
            "name": "setuptools",
            "specs": [
                [
                    "~=",
                    "68.2.2"
                ]
            ]
        },
        {
            "name": "version-parser",
            "specs": [
                [
                    "~=",
                    "1.0.1"
                ]
            ]
        }
    ],
    "lcname": "signxai"
}
        
Elapsed time: 0.43117s