{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "### SHAP on MNIST" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This is an example of SHAP on image data. If using this explainer, please cite the original work: https://github.com/slundberg/shap. `ShapImage` is not a model-agnostic method as `ShapTabular`. It only support Tensorflow or PyTorch models." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "# This default renderer is used for sphinx docs only. Please delete this cell in IPython.\n", "import plotly.io as pio\n", "pio.renderers.default = \"png\"" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import tensorflow as tf\n", "import matplotlib.pyplot as plt\n", "\n", "from omnixai.data.image import Image\n", "from omnixai.explainers.vision import ShapImage" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The following code loads the training and test datasets. We recommend using `Image` to represent a batch of images. `Image` can be constructed from a numpy array or a Pillow image. In this example, `Image` is constructed from a numpy array containing a batch of digit images." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "# Load the MNIST dataset\n", "img_rows, img_cols = 28, 28\n", "(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()\n", "\n", "if tf.keras.backend.image_data_format() == 'channels_first':\n", " x_train = x_train.reshape(x_train.shape[0], 1, img_rows, img_cols)\n", " x_test = x_test.reshape(x_test.shape[0], 1, img_rows, img_cols)\n", " input_shape = (1, img_rows, img_cols)\n", "else:\n", " x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1)\n", " x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1)\n", " input_shape = (img_rows, img_cols, 1)\n", "\n", "# Use `Image` objects to represent the training and test datasets\n", "train_imgs, train_labels = Image(x_train.astype('float32'), batched=True), y_train\n", "test_imgs, test_labels = Image(x_test.astype('float32'), batched=True), y_test" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The preprocessing function takes an `Image` instance as its input and outputs the processed features that the ML model consumes. In this example, the pixel values are normalized to [0, 1]." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "preprocess_func = lambda x: np.expand_dims(x.to_numpy() / 255, axis=-1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We train a simple convolutional neural network for this task. The network has two convolutional layers and one dense hidden layer. " ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Epoch 1/10\n", "469/469 [==============================] - 2s 5ms/step - loss: 0.1724 - accuracy: 0.9487 - val_loss: 0.0458 - val_accuracy: 0.9855\n", "Epoch 2/10\n", "469/469 [==============================] - 2s 5ms/step - loss: 0.0466 - accuracy: 0.9852 - val_loss: 0.0333 - val_accuracy: 0.9885\n", "Epoch 3/10\n", "469/469 [==============================] - 2s 5ms/step - loss: 0.0298 - accuracy: 0.9906 - val_loss: 0.0323 - val_accuracy: 0.9891\n", "Epoch 4/10\n", "469/469 [==============================] - 2s 5ms/step - loss: 0.0207 - accuracy: 0.9933 - val_loss: 0.0286 - val_accuracy: 0.9903\n", "Epoch 5/10\n", "469/469 [==============================] - 2s 5ms/step - loss: 0.0158 - accuracy: 0.9949 - val_loss: 0.0295 - val_accuracy: 0.9907\n", "Epoch 6/10\n", "469/469 [==============================] - 2s 5ms/step - loss: 0.0125 - accuracy: 0.9962 - val_loss: 0.0290 - val_accuracy: 0.9904\n", "Epoch 7/10\n", "469/469 [==============================] - 2s 5ms/step - loss: 0.0109 - accuracy: 0.9963 - val_loss: 0.0283 - val_accuracy: 0.9902\n", "Epoch 8/10\n", "469/469 [==============================] - 2s 5ms/step - loss: 0.0090 - accuracy: 0.9970 - val_loss: 0.0323 - val_accuracy: 0.9903\n", "Epoch 9/10\n", "469/469 [==============================] - 2s 5ms/step - loss: 0.0065 - accuracy: 0.9978 - val_loss: 0.0317 - val_accuracy: 0.9912\n", "Epoch 10/10\n", "469/469 [==============================] - 2s 5ms/step - loss: 0.0072 - accuracy: 0.9974 - val_loss: 0.0359 - val_accuracy: 0.9915\n", "Test loss: 0.03591015189886093\n", "Test accuracy: 0.9915000200271606\n" ] } ], "source": [ "batch_size = 128\n", "num_classes = 10\n", "epochs = 10\n", "\n", "x_train = preprocess_func(train_imgs)\n", "x_test = preprocess_func(test_imgs)\n", "y_train = tf.keras.utils.to_categorical(y_train, num_classes)\n", "y_test = tf.keras.utils.to_categorical(y_test, num_classes)\n", "\n", "model = tf.keras.models.Sequential()\n", "model.add(tf.keras.layers.Conv2D(\n", " 32, kernel_size=(3, 3), activation='relu', input_shape=input_shape))\n", "model.add(tf.keras.layers.Conv2D(64, (3, 3), activation='relu'))\n", "model.add(tf.keras.layers.MaxPooling2D(pool_size=(2, 2)))\n", "model.add(tf.keras.layers.Dropout(0.1))\n", "model.add(tf.keras.layers.Flatten())\n", "model.add(tf.keras.layers.Dense(128, activation='relu'))\n", "model.add(tf.keras.layers.Dropout(0.1))\n", "model.add(tf.keras.layers.Dense(num_classes))\n", "\n", "model.compile(\n", " loss=tf.keras.losses.CategoricalCrossentropy(from_logits=True),\n", " optimizer=tf.keras.optimizers.Adam(),\n", " metrics=['accuracy']\n", ")\n", "model.fit(\n", " x_train, y_train,\n", " batch_size=batch_size,\n", " epochs=epochs,\n", " verbose=1,\n", " validation_data=(x_test, y_test)\n", ")\n", "score = model.evaluate(x_test, y_test, verbose=0)\n", "print('Test loss:', score[0])\n", "print('Test accuracy:', score[1])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To initialize `ShapImage`, we need to set the following parameters:\n", " \n", " - `model`: The ML model to explain, e.g., `torch.nn.Module` or `tf.keras.Model`.\n", " - `preprocess_function`: The preprocessing function that converts the raw data into the inputs of `model`." ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "scrolled": true }, "outputs": [], "source": [ "explainer = ShapImage(\n", " model=model,\n", " preprocess_function=preprocess_func\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can simply call `explainer.explain` to generate explanations for this classification task. `ipython_plot` plots the generated explanations in IPython. Parameter `index` indicates which instance to plot, e.g., `index = 0` means plotting the first instance in `test_imgs[0:5]`." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "WARNING:tensorflow:From /home/ywz/anaconda3/lib/python3.7/site-packages/shap/explainers/_deep/deep_tf.py:239: set_learning_phase (from tensorflow.python.keras.backend) is deprecated and will be removed after 2020-10-11.\n", "Instructions for updating:\n", "Simply pass a True/False value to the `training` argument of the `__call__` method of your layer or model.\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "Using TensorFlow backend.\n", "keras is no longer supported, please use tf.keras instead.\n" ] }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAArwAAAH0CAYAAADfWf7fAAAgAElEQVR4Xu3defxvRV0/8GHfBFQQMTUXzBTT1BSN1DDcl0CQRRAQVFyRJUCwUNQkBXcSw8wFRDFTIQt3f26luWS5ppaGqBiSJQKy39/jfOxe7uX7ud+Z78xZ5/P8/tPDPjNzznnOnPe87uHzPd8NVq1atSr4IUCAAAECBAgQIFCpwAYCb6Uz67IIECBAgAABAgRmAgKvhUCAAAECBAgQIFC1gMBb9fS6OAIECBAgQIAAAYHXGiBAgAABAgQIEKhaQOCtenpdHAECBAgQIECAgMBrDRAgQIAAAQIECFQtIPBWPb0ujgABAgQIECBAQOC1BggQIECAAAECBKoWEHirnl4XR4AAAQIECBAgIPBaAwQIECBAgAABAlULCLxVT6+LI0CAAAECBAgQEHitAQIECBAgQIAAgaoFBN6qp9fFESBAgAABAgQICLzWAAECBAgQIECAQNUCAm/V0+viCBAgQIAAAQIEBF5rgAABAgQIECBAoGoBgbfq6XVxBAgQIECAAAECAq81QIAAAQIECBAgULWAwFv19Lo4AgQIECBAgAABgdcaIECAAAECBAgQqFpA4K16el0cAQIECBAgQICAwGsNECBAgAABAgQIVC0g8FY9vS6OAAECBAgQIEBA4LUGCBAgQIAAAQIEqhYQeKueXhdHgAABAgQIECAg8FoDBAgQIECAAAECVQsIvFVPr4sjQIAAAQIECBAQeK0BAgQIECBAgACBqgUE3qqn18URIECAAAECBAgIvNYAAQIECBAgQIBA1QICb9XT6+IIECBAgAABAgQEXmuAAAECBAgQIECgagGBt+rpdXEECBAgQIAAAQICrzVAgAABAgQIECBQtYDAW/X0ujgCBAgQIECAAAGB1xogQIAAAQIECBCoWkDgrXp6XRwBAgQIECBAgIDAaw0QIECAAAECBAhULSDwVj29Lo4AAQIECBAgQEDgtQYIECBAgAABAgSqFhB4q55eF0eAAAECBAgQICDwWgMECBAgQIAAAQJVCwi8VU+viyNAgAABAgQIEBB4rQECBAgQIECAAIGqBQTeqqfXxREgQIAAAQIECAi81gABAgQIECBAgEDVAgJv1dPr4ggQIECAAAECBARea4AAAQIECBAgQKBqAYG36ul1cQQIECBAgAAB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" }, "metadata": {}, "output_type": "display_data" } ], "source": [ "explanations = explainer.explain(test_imgs[0:5])\n", "explanations.ipython_plot(index=4)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.5" } }, "nbformat": 4, "nbformat_minor": 2 }