{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "### Counterfactual explanation on MNIST (Tensorflow)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This is an example of `CounterfactualExplainer` on MNIST with a Tensorflow model. `CounterfactualExplainer` is an optimization based method for generating counterfactual examples, supporting classification tasks only. If using this explainer, please cite the paper \"Counterfactual Explanations without Opening the Black Box: Automated Decisions and the GDPR, Sandra Wachter, Brent Mittelstadt, Chris Russell, https://arxiv.org/abs/1711.00399\"." ] }, { "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 CounterfactualExplainer" ] }, { "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.1696 - accuracy: 0.9492 - val_loss: 0.0436 - val_accuracy: 0.9855\n", "Epoch 2/10\n", "469/469 [==============================] - 2s 5ms/step - loss: 0.0478 - accuracy: 0.9856 - val_loss: 0.0352 - val_accuracy: 0.9882\n", "Epoch 3/10\n", "469/469 [==============================] - 2s 5ms/step - loss: 0.0324 - accuracy: 0.9896 - val_loss: 0.0315 - val_accuracy: 0.9892\n", "Epoch 4/10\n", "469/469 [==============================] - 2s 5ms/step - loss: 0.0223 - accuracy: 0.9929 - val_loss: 0.0320 - val_accuracy: 0.9887\n", "Epoch 5/10\n", "469/469 [==============================] - 2s 5ms/step - loss: 0.0179 - accuracy: 0.9940 - val_loss: 0.0314 - val_accuracy: 0.9901\n", "Epoch 6/10\n", "469/469 [==============================] - 2s 5ms/step - loss: 0.0141 - accuracy: 0.9952 - val_loss: 0.0365 - val_accuracy: 0.9888\n", "Epoch 7/10\n", "469/469 [==============================] - 2s 5ms/step - loss: 0.0113 - accuracy: 0.9960 - val_loss: 0.0324 - val_accuracy: 0.9903\n", "Epoch 8/10\n", "469/469 [==============================] - 2s 5ms/step - loss: 0.0109 - accuracy: 0.9965 - val_loss: 0.0297 - val_accuracy: 0.9918\n", "Epoch 9/10\n", "469/469 [==============================] - 2s 5ms/step - loss: 0.0083 - accuracy: 0.9972 - val_loss: 0.0337 - val_accuracy: 0.9918\n", "Epoch 10/10\n", "469/469 [==============================] - 2s 5ms/step - loss: 0.0072 - accuracy: 0.9976 - val_loss: 0.0382 - val_accuracy: 0.9895\n", "Test loss: 0.03824701905250549\n", "Test accuracy: 0.9894999861717224\n" ] } ], "source": [ "batch_size = 128\n", "num_classes = 10\n", "epochs = 10\n", "\n", "# Preprocess the training and test data\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 structure\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", "# Train the model\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 `CounterfactualExplainer`, 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 (a `Image` instance) into the inputs of `model`.\n", " - \"optimization parameters\": e.g., `binary_search_steps`, `num_iterations`. Please refer to the docs for more details." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "explainer = CounterfactualExplainer(\n", " model=model,\n", " preprocess_function=preprocess_func\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can simply call `explainer.explain` to generate counterfactual examples 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": [ "Binary step: 5 |███████████████████████████████████████-| 99.9% " ] }, { "data": { "image/png": "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AAECBAgQIECgTQGBt82+2TUBAgQIECBAgECmgMCbCaWMAAECBAgQIECgTQGBt82+2TUBAgQIECBAgECmgMCbCaWMAAECBAgQIECgTQGBt82+2TUBAgQIECBAgECmgMCbCaWMAAECBAgQIECgTQGBt82+2TUBAgQIECBAgECmgMCbCaWMAAECBAgQIECgTQGBt82+2TUBAgQIECBAgECmgMCbCaWMAAECBAgQIECgTQGBt82+2TUBAgQIECBAgECmgMCbCaWMAAECBAgQIECgTQGBt82+2TUBAgQIECBAgECmgMCbCaWMAAECBAgQIECgTQGBt82+2TUBAgQIECBAgECmgMCbCaWMAAECBAgQIECgTQGBt82+2TUBAgQIECBAgECmgMCbCaWMAAECBAgQIECgTQGBt82+2TUBAgQIECBAgECmgMCbCaWMAAECBAgQIECgTQGBt82+2TUBAgQIECBAgECmgMCbCaWMAAECBAgQIECgTQGBt82+2TUBAgQIECBAgECmgMCbCaWMAAECBAgQIECgTQGBt82+2TUBAgQIECBAgECmgMCbCaWMAAECBAgQIECgTQGBt82+2TUBAgQIECBAgECmgMCbCaWMAAECBAgQIECgTQGBt82+2TUBAgQIECBAgECmgMCbCaWMAAECBAgQIECgTQGBt82+2TUBAgQIECBAgECmgMCbCaWMAAECBAgQIECgTQGBt82+2TUBAgQIECBAgECmgMCbCaWMAAECBAgQIECgTQGBt82+2TUBAgQIECBAgECmgMCbCaWMAAECBAgQIECgTQGBt82+2TUBAgQIECBAgECmgMCbCaWMAAECBAgQIECgTQGBt82+2TUBAgQIECBAgECmgMCbCaWMAAECBAgQIECgTQGBt82+2TUBAgQIECBAgECmgMCbCaWMAAECBAgQIECgTQGBt82+2TUBAgQIECBAgECmgMCbCaWMAAECBAgQIECgTQGBt82+2TUBAgQIECBAgECmgMCbCaWMAAECBAgQIECgTQGBt82+2TUBAgQIECBAgECmgMCbCaWMAAECBAgQIECgTQGBt82+2TUBAgQIECBAgECmgMCbCaWMAAECBAgQIECgTQGBt82+2TUBAgQIECBAgECmgMCbCaWMAAECBAgQIECgTQGBt82+2TUBAgQIECBAgECmgMCbCaWMAAECBAgQIECg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CBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECki24LQAAADlJREFURQICbxGXYgIECBAgQIAAgdYEBN7WOma/BAgQIECAAAECRQICbxGXYgIECBAgQIAAgdYE/j9Kn2X2bw7bLgAAAABJRU5ErkJggg==" }, "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 }