-
Notifications
You must be signed in to change notification settings - Fork 989
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for AIX360 explanations #1094
Merged
k8s-ci-robot
merged 50 commits into
kserve:master
from
drewbutlerbb4:trusted-ai-explainer
Sep 29, 2020
Merged
Changes from 21 commits
Commits
Show all changes
50 commits
Select commit
Hold shift + click to select a range
b6b4f22
Rebase AIX explainer on KFServing
drewbutlerbb4 185ab97
Add AIXExplainer to function
drewbutlerbb4 4d96fa5
Add AIX explainer implementation
drewbutlerbb4 c05a106
Add AIX explainer server
drewbutlerbb4 1b48186
Fix link with local reference
drewbutlerbb4 b00d2db
aix api patch
Tomcli 2b19c46
aix api patch
drewbutlerbb4 0684791
Add random forest predictor
drewbutlerbb4 071d7e5
Fix link
drewbutlerbb4 b3ed924
Update aix-explainer image version
drewbutlerbb4 dba8834
Pull master
drewbutlerbb4 a40fe6f
Clean up example readme
Tomcli fe0a3c7
Clean up example readme
drewbutlerbb4 7d270b6
Refactor rfserver and update image
drewbutlerbb4 48612e3
Update inferenceservice.yaml
Tomcli 64fd254
Update aix-explainer.yaml
Tomcli 74d9e16
update version format to match with KFServing
drewbutlerbb4 fa97fb2
update v1beta1 spec and tests
Tomcli b665823
update v1beta1 spec and tests for rebase
drewbutlerbb4 4bdf8fe
Refactor sample content and rework notebook
drewbutlerbb4 a078ecd
Add newline at EOF
drewbutlerbb4 41a056b
generate aix SDK spec and add predictor test
Tomcli e0c267b
generate aix SDK spec and add predictor test
Tomcli b25d5f3
Merge pull request #7 from Tomcli/sdk-gen
drewbutlerbb4 4bda3af
add aix explainer build test
Tomcli 449b25e
Merge pull request #8 from Tomcli/sdk-gen
drewbutlerbb4 2a3b8a4
add missing __init__.py
Tomcli d9ded20
Merge pull request #9 from Tomcli/sdk-gen
drewbutlerbb4 bfe2a26
Add explanation e2e check
drewbutlerbb4 2a07d03
Add explanation e2e check
drewbutlerbb4 f2c4cf6
fix containerv1 spec
Tomcli 1c0a9f3
fix conflicts
Tomcli ddd0b8f
rebase api spec
Tomcli 08995e7
fix empty uri for aix framework
Tomcli ab5155d
Merge pull request #12 from Tomcli/trusted-ai-rebase
drewbutlerbb4 39d8239
Merge pull request #11 from Tomcli/sdk-gen
drewbutlerbb4 62b5366
remove testing logs
Tomcli 5153c0a
Merge pull request #13 from Tomcli/trusted-ai-explainer
drewbutlerbb4 cb3f00e
update e2e test to match with the v1beta1 controller changes
Tomcli e3215d2
Merge pull request #14 from Tomcli/trusted-ai-explainer
drewbutlerbb4 afdeadb
Fix logging
drewbutlerbb4 9f13ca9
address comments on ci config
Tomcli 5308c14
Merge pull request #15 from Tomcli/trusted-ai-explainer
drewbutlerbb4 645eca3
Make aixexplainer account for asynchronous predict calls
drewbutlerbb4 eb7625e
Fix e2e test response parsing
drewbutlerbb4 15d7444
updated generated hack files to align with existing format
Tomcli f7af3ab
update samples to use v1beta1 api
Tomcli d37f1f4
Merge pull request #16 from Tomcli/trusted-ai-explainer
drewbutlerbb4 d2ce61b
Apply suggestions from code review
drewbutlerbb4 fe6d5d2
Rebase to master
drewbutlerbb4 File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
# Using AIX to get explanations for MNIST classifications | ||
|
||
This is an example of how to explain model outputs using [AIX360](https://github.com/Trusted-AI/AIX360) on KFServing. We will be using mnist, a dataset for handwritten digits, for this model and explain how the model decides the predicted results. | ||
drewbutlerbb4 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
To deploy the inferenceservice | ||
|
||
`kubectl apply -f aix-explainer.yaml` | ||
|
||
Then find the url. | ||
|
||
`kubectl get inferenceservice` | ||
|
||
``` | ||
NAME URL READY DEFAULT TRAFFIC CANARY TRAFFIC AGE | ||
aixserver http://aixserver.somecluster/v1/models/aixserver True 100 40m | ||
``` | ||
|
||
## Prediction | ||
The first step is to [determine the ingress IP and ports](../../../../../README.md#determine-the-ingress-ip-and-ports) and set `INGRESS_HOST` and `INGRESS_PORT` | ||
|
||
``` | ||
MODEL_NAME=aix-explainer | ||
SERVICE_HOSTNAME=$(kubectl get inferenceservice ${MODEL_NAME} -o jsonpath='{.status.url}' | cut -d "/" -f 3) | ||
python query_explain.py http://${INGRESS_HOST}:${INGRESS_PORT}/v1/models/$MODEL_NAME:explain ${SERVICE_HOSTNAME} | ||
``` | ||
|
||
To try a different MNIST example add an integer to the end of the query between 0-10,000. The integer chosen will be the index of the image to be chosen in the MNIST dataset. | ||
|
||
``` | ||
python query_explain.py http://${INGRESS_HOST}:${INGRESS_PORT}/v1/models/$MODEL_NAME:explain ${SERVICE_HOSTNAME} 100 | ||
``` | ||
|
||
## Stopping the Inference Service | ||
|
||
`kubectl delete -f aix-explainer.yaml` | ||
|
||
## Troubleshooting | ||
|
||
`<504> Gateway Timeout <504>` - the explainer is probably taking to long and not sending a response back quickly enough. Either there aren't enough resources allocated or the number of samples the explainer is allowed to take needs to be reduced. To fix this go to aix-explainer.yaml and increase resources. Or to lower the number of allowed samples go to aix-explainer.yaml and add a flag to `explainer: command:` '--num_samples' (the default number of samples is 1000) | ||
drewbutlerbb4 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
If you see `Configuration "aixserver-explainer-default" does not have any ready Revision` the container may have taken too long to download. If you run `kubectl get revision` and see your revision is stuck in `ContainerCreating` try deleting the inferenceservice and redeploying. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
apiVersion: "serving.kubeflow.org/v1alpha2" | ||
kind: "InferenceService" | ||
metadata: | ||
name: "aix-explainer" | ||
namespace: default | ||
spec: | ||
default: | ||
predictor: | ||
custom: | ||
container: | ||
name: predictor | ||
image: aipipeline/rf-predictor:0.4.0 | ||
command: ["python", "-m", "rfserver", "--model_name", "aix-explainer"] | ||
imagePullPolicy: Always | ||
resources: | ||
requests: | ||
memory: "2Gi" | ||
cpu: "1" | ||
limits: | ||
memory: "2Gi" | ||
cpu: "1" | ||
explainer: | ||
aix: | ||
type: LimeImages | ||
config: | ||
num_samples: "100" | ||
top_labels: "10" | ||
min_weight: "0.01" | ||
resources: | ||
requests: | ||
cpu: 1 | ||
memory: 2Gi |
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
import os | ||
import sys | ||
import requests | ||
import json | ||
from matplotlib import pyplot as plt | ||
import numpy as np | ||
from aix360.datasets import MNISTDataset | ||
from keras.applications import inception_v3 as inc_net | ||
from keras.preprocessing import image | ||
from keras.applications.imagenet_utils import decode_predictions | ||
import time | ||
from skimage.color import gray2rgb, rgb2gray, label2rgb # since the code wants color images | ||
|
||
print('************************************************************') | ||
print('************************************************************') | ||
print('************************************************************') | ||
print("starting query") | ||
|
||
if len(sys.argv) < 3: | ||
raise Exception("No endpoint specified. ") | ||
endpoint = sys.argv[1] | ||
headers = { | ||
'Host': sys.argv[2] | ||
} | ||
test_num = 1002 | ||
is_file = False | ||
if len(sys.argv) > 3: | ||
try: | ||
test_num = int(sys.argv[2]) | ||
except: | ||
is_file = True | ||
|
||
if is_file: | ||
inputs = open(sys.argv[2]) | ||
inputs = json.load(inputs) | ||
actual = "unk" | ||
else: | ||
data = MNISTDataset() | ||
inputs = data.test_data[test_num] | ||
labels = data.test_labels[test_num] | ||
actual = 0 | ||
for x in range(1, len(labels)): | ||
if labels[x] != 0: | ||
actual = x | ||
inputs = gray2rgb(inputs.reshape((-1, 28, 28))) | ||
inputs = np.reshape(inputs, (28,28,3)) | ||
input_image = {"instances": [inputs.tolist()]} | ||
print("Sending Explain Query") | ||
|
||
x = time.time() | ||
|
||
res = requests.post(endpoint, json=input_image, headers=headers) | ||
|
||
print("TIME TAKEN: ", time.time() - x) | ||
|
||
print(res) | ||
if not res.ok: | ||
res.raise_for_status() | ||
res_json = res.json() | ||
temp = np.array(res_json["explanations"]["temp"]) | ||
masks = np.array(res_json["explanations"]["masks"]) | ||
top_labels = np.array(res_json["explanations"]["top_labels"]) | ||
|
||
fig, m_axs = plt.subplots(2,5, figsize = (12,6)) | ||
for i, c_ax in enumerate(m_axs.flatten()): | ||
mask = masks[i] | ||
c_ax.imshow(label2rgb(mask, temp, bg_label = 0), interpolation = 'nearest') | ||
c_ax.set_title('Positive for {}\nActual {}'.format(top_labels[i], actual)) | ||
c_ax.axis('off') | ||
plt.show() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
absl-py==0.9.0 | ||
aix360==0.2.0 | ||
appnope==0.1.0 | ||
asgiref==3.2.7 | ||
astor==0.8.1 | ||
attrs==19.3.0 | ||
backcall==0.1.0 | ||
bleach==3.1.4 | ||
certifi==2020.4.5.1 | ||
chardet==3.0.4 | ||
cvxopt==1.2.4 | ||
cvxpy==1.0.29 | ||
cycler==0.10.0 | ||
decorator==4.4.2 | ||
defusedxml==0.6.0 | ||
dill==0.3.1.1 | ||
Django==3.0.5 | ||
docutils==0.16 | ||
ecos==2.0.7.post1 | ||
entrypoints==0.3 | ||
future==0.18.2 | ||
gast==0.3.3 | ||
google-pasta==0.2.0 | ||
grpcio==1.28.1 | ||
h5py==2.10.0 | ||
idna==2.9 | ||
image==1.5.28 | ||
imageio==2.8.0 | ||
importlib-metadata==1.6.0 | ||
ipykernel==5.2.0 | ||
ipython==7.13.0 | ||
ipython-genutils==0.2.0 | ||
jedi==0.16.0 | ||
Jinja2==2.11.1 | ||
joblib==0.14.1 | ||
json5==0.9.4 | ||
jsonschema==3.2.0 | ||
jupyter-client==6.1.2 | ||
jupyter-core==4.6.3 | ||
jupyterlab==2.0.1 | ||
jupyterlab-server==1.0.7 | ||
Keras==2.3.1 | ||
Keras-Applications==1.0.8 | ||
Keras-Preprocessing==1.1.0 | ||
kiwisolver==1.2.0 | ||
lime==0.2.0.0 | ||
Markdown==3.2.1 | ||
MarkupSafe==1.1.1 | ||
matplotlib==3.2.1 | ||
mistune==0.8.4 | ||
multiprocess==0.70.9 | ||
nbconvert==5.6.1 | ||
nbformat==5.0.5 | ||
networkx==2.4 | ||
notebook==6.0.3 | ||
numpy==1.18.2 | ||
osqp==0.6.1 | ||
pandas==1.0.3 | ||
pandocfilters==1.4.2 | ||
parso==0.6.2 | ||
pexpect==4.8.0 | ||
pickleshare==0.7.5 | ||
Pillow==5.4.1 | ||
prometheus-client==0.7.1 | ||
prompt-toolkit==3.0.5 | ||
protobuf==3.11.3 | ||
ptyprocess==0.6.0 | ||
Pygments==2.6.1 | ||
pyparsing==2.4.7 | ||
pyrsistent==0.16.0 | ||
python-dateutil==2.8.1 | ||
pytz==2019.3 | ||
PyWavelets==1.1.1 | ||
PyYAML==5.3.1 | ||
pyzmq==19.0.0 | ||
requests==2.23.0 | ||
scikit-image==0.16.2 | ||
scikit-learn==0.22.2.post1 | ||
scipy==1.4.1 | ||
scs==2.1.2 | ||
Send2Trash==1.5.0 | ||
shap==0.35.0 | ||
six==1.14.0 | ||
sqlparse==0.3.1 | ||
tensorboard==1.14.0 | ||
tensorflow==1.14.0 | ||
tensorflow-estimator==1.14.0 | ||
termcolor==1.1.0 | ||
terminado==0.8.3 | ||
testpath==0.4.4 | ||
torch==1.4.0 | ||
torchvision==0.5.0 | ||
tornado==6.0.4 | ||
tqdm==4.45.0 | ||
traitlets==4.3.3 | ||
urllib3==1.25.8 | ||
wcwidth==0.1.9 | ||
webencodings==0.5.1 | ||
Werkzeug==1.0.1 | ||
wrapt==1.12.1 | ||
xgboost==1.0.2 | ||
xport==2.0.2 | ||
zipp==3.1.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# Random Forest for MNIST on kfserving |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
FROM python:3.7 | ||
|
||
COPY . . | ||
RUN pip install --upgrade pip && pip install kfserving==0.4.0 | ||
RUN pip install -e . | ||
ENTRYPOINT ["python", "-m", "rfserver", "--model_name", "aixserver"] |
Binary file not shown.
15 changes: 15 additions & 0 deletions
15
docs/samples/explanation/aix/mnist/rfserver/rfserver/__init__.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# Copyright 2019 kubeflow.org. | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
from .model import RFModel |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please also change here which is used for KFServing CI https://github.com/kubeflow/kfserving/blob/master/config/overlays/test/configmap/inferenceservice.yaml#L39
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the pointer.