Skip to content

Commit 5cf3859

Browse files
feat: xai samples (#83)
1 parent 6096ce7 commit 5cf3859

6 files changed

+381
-0
lines changed
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# Copyright 2020 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
# [START aiplatform_explain_tabular_sample]
16+
from typing import Dict
17+
18+
from google.cloud import aiplatform
19+
from google.protobuf import json_format
20+
from google.protobuf.struct_pb2 import Value
21+
22+
23+
def explain_tabular_sample(
24+
project: str,
25+
endpoint_id: str,
26+
instance_dict: Dict,
27+
location: str = "us-central1",
28+
api_endpoint: str = "us-central1-prediction-aiplatform.googleapis.com",
29+
):
30+
client_options = {"api_endpoint": api_endpoint}
31+
# Initialize client that will be used to create and send requests.
32+
# This client only needs to be created once, and can be reused for multiple requests.
33+
client = aiplatform.gapic.PredictionServiceClient(client_options=client_options)
34+
# The format of each instance should conform to the deployed model's prediction input schema.
35+
instance = json_format.ParseDict(instance_dict, Value())
36+
instances = [instance]
37+
# tabular models do not have additional parameters
38+
parameters_dict = {}
39+
parameters = json_format.ParseDict(parameters_dict, Value())
40+
endpoint = client.endpoint_path(
41+
project=project, location=location, endpoint=endpoint_id
42+
)
43+
response = client.explain(
44+
endpoint=endpoint, instances=instances, parameters=parameters
45+
)
46+
print("response")
47+
print(" deployed_model_id:", response.deployed_model_id)
48+
explanations = response.explanations
49+
for explanation in explanations:
50+
print(" explanation")
51+
# Feature attributions.
52+
attributions = explanation.attributions
53+
for attribution in attributions:
54+
print(" attribution")
55+
print(" baseline_output_value:", attribution.baseline_output_value)
56+
print(" instance_output_value:", attribution.instance_output_value)
57+
print(" output_display_name:", attribution.output_display_name)
58+
print(" approximation_error:", attribution.approximation_error)
59+
print(" output_name:", attribution.output_name)
60+
output_index = attribution.output_index
61+
for output_index in output_index:
62+
print(" output_index:", output_index)
63+
predictions = response.predictions
64+
for prediction in predictions:
65+
print(" prediction:", dict(prediction))
66+
67+
68+
# [END aiplatform_explain_tabular_sample]
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Copyright 2020 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import os
16+
17+
import explain_tabular_sample
18+
19+
ENDPOINT_ID = "4966625964059525120" # iris 1000
20+
PROJECT_ID = os.getenv("BUILD_SPECIFIC_GCLOUD_PROJECT")
21+
22+
INSTANCE = {
23+
"petal_length": "1.4",
24+
"petal_width": "1.3",
25+
"sepal_length": "5.1",
26+
"sepal_width": "2.8",
27+
}
28+
29+
30+
def test_ucaip_generated_explain_tabular_sample(capsys):
31+
32+
explain_tabular_sample.explain_tabular_sample(
33+
instance_dict=INSTANCE, project=PROJECT_ID, endpoint_id=ENDPOINT_ID
34+
)
35+
36+
out, _ = capsys.readouterr()
37+
assert 'attribution' in out
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# Copyright 2020 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
# [START aiplatform_upload_model_explain_image_managed_container_sample]
16+
from google.cloud import aiplatform
17+
18+
19+
def upload_model_explain_image_managed_container_sample(
20+
project: str,
21+
display_name: str,
22+
container_spec_image_uri: str,
23+
artifact_uri: str,
24+
input_tensor_name: str,
25+
output_tensor_name: str,
26+
location: str = "us-central1",
27+
api_endpoint: str = "us-central1-aiplatform.googleapis.com",
28+
timeout: int = 300,
29+
):
30+
client_options = {"api_endpoint": api_endpoint}
31+
# Initialize client that will be used to create and send requests.
32+
# This client only needs to be created once, and can be reused for multiple requests.
33+
client = aiplatform.gapic.ModelServiceClient(client_options=client_options)
34+
35+
# Container specification for deploying the model
36+
container_spec = {"image_uri": container_spec_image_uri, "command": [], "args": []}
37+
38+
# The explainabilty method and corresponding parameters
39+
parameters = aiplatform.gapic.ExplanationParameters(
40+
{"xrai_attribution": {"step_count": 1}}
41+
)
42+
43+
# The input tensor for feature attribution to the output
44+
# For single input model, y = f(x), this will be the serving input layer.
45+
input_metadata = aiplatform.gapic.ExplanationMetadata.InputMetadata(
46+
{
47+
"input_tensor_name": input_tensor_name,
48+
# Input is image data
49+
"modality": "image",
50+
}
51+
)
52+
53+
# The output tensor to explain
54+
# For single output model, y = f(x), this will be the serving output layer.
55+
output_metadata = aiplatform.gapic.ExplanationMetadata.OutputMetadata(
56+
{"output_tensor_name": output_tensor_name}
57+
)
58+
59+
# Assemble the explanation metadata
60+
metadata = aiplatform.gapic.ExplanationMetadata(
61+
inputs={"image": input_metadata}, outputs={"prediction": output_metadata}
62+
)
63+
64+
# Assemble the explanation specification
65+
explanation_spec = aiplatform.gapic.ExplanationSpec(
66+
parameters=parameters, metadata=metadata
67+
)
68+
69+
model = aiplatform.gapic.Model(
70+
display_name=display_name,
71+
# The Cloud Storage location of the custom model
72+
artifact_uri=artifact_uri,
73+
explanation_spec=explanation_spec,
74+
container_spec=container_spec,
75+
)
76+
parent = f"projects/{project}/locations/{location}"
77+
response = client.upload_model(parent=parent, model=model)
78+
print("Long running operation:", response.operation.name)
79+
upload_model_response = response.result(timeout=timeout)
80+
print("upload_model_response:", upload_model_response)
81+
82+
83+
# [END aiplatform_upload_model_explain_image_managed_container_sample]
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Copyright 2020 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import os
16+
17+
from uuid import uuid4
18+
19+
import pytest
20+
21+
import helpers
22+
23+
import upload_model_explain_image_managed_container_sample
24+
25+
PROJECT_ID = os.getenv("BUILD_SPECIFIC_GCLOUD_PROJECT")
26+
IMAGE_URI = "gcr.io/cloud-aiplatform/prediction/tf2-cpu.2-1:latest"
27+
ARTIFACT_URI = "gs://ucaip-samples-us-central1/model/cifar"
28+
DISPLAY_NAME = f"temp_upload_model_explain_image_managed_container_sample_{uuid4()}"
29+
30+
INPUT_TENSOR_NAME = "bytes_inputs"
31+
OUTPUT_TENSOR_NAME = "output_0"
32+
33+
34+
@pytest.fixture(scope="function", autouse=True)
35+
def teardown(teardown_model):
36+
yield
37+
38+
39+
def test_ucaip_generated_upload_model_explain_image_managed_container_sample(capsys, shared_state):
40+
41+
upload_model_explain_image_managed_container_sample.upload_model_explain_image_managed_container_sample(
42+
display_name=DISPLAY_NAME,
43+
artifact_uri=ARTIFACT_URI,
44+
container_spec_image_uri=IMAGE_URI,
45+
project=PROJECT_ID,
46+
input_tensor_name=INPUT_TENSOR_NAME,
47+
output_tensor_name=OUTPUT_TENSOR_NAME
48+
)
49+
50+
out, _ = capsys.readouterr()
51+
52+
shared_state["model_name"] = helpers.get_name(out, key="model")
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# Copyright 2020 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
# [START aiplatform_upload_model_explain_tabular_managed_container_sample]
16+
from google.cloud import aiplatform
17+
18+
19+
def upload_model_explain_tabular_managed_container_sample(
20+
project: str,
21+
display_name: str,
22+
container_spec_image_uri: str,
23+
artifact_uri: str,
24+
input_tensor_name: str,
25+
output_tensor_name: str,
26+
feature_names: list,
27+
location: str = "us-central1",
28+
api_endpoint: str = "us-central1-aiplatform.googleapis.com",
29+
timeout: int = 300,
30+
):
31+
client_options = {"api_endpoint": api_endpoint}
32+
# Initialize client that will be used to create and send requests.
33+
# This client only needs to be created once, and can be reused for multiple requests.
34+
client = aiplatform.gapic.ModelServiceClient(client_options=client_options)
35+
36+
# Container specification for deploying the model
37+
container_spec = {"image_uri": container_spec_image_uri, "command": [], "args": []}
38+
39+
# The explainabilty method and corresponding parameters
40+
parameters = aiplatform.gapic.ExplanationParameters(
41+
{"xrai_attribution": {"step_count": 1}}
42+
)
43+
44+
# The input tensor for feature attribution to the output
45+
# For single input model, y = f(x), this will be the serving input layer.
46+
input_metadata = aiplatform.gapic.ExplanationMetadata.InputMetadata(
47+
{
48+
"input_tensor_name": input_tensor_name,
49+
# Input is tabular data
50+
"modality": "numeric",
51+
# Assign feature names to the inputs for explanation
52+
"encoding": "BAG_OF_FEATURES",
53+
"index_feature_mapping": feature_names,
54+
}
55+
)
56+
57+
# The output tensor to explain
58+
# For single output model, y = f(x), this will be the serving output layer.
59+
output_metadata = aiplatform.gapic.ExplanationMetadata.OutputMetadata(
60+
{"output_tensor_name": output_tensor_name}
61+
)
62+
63+
# Assemble the explanation metadata
64+
metadata = aiplatform.gapic.ExplanationMetadata(
65+
inputs={"features": input_metadata}, outputs={"prediction": output_metadata}
66+
)
67+
68+
# Assemble the explanation specification
69+
explanation_spec = aiplatform.gapic.ExplanationSpec(
70+
parameters=parameters, metadata=metadata
71+
)
72+
73+
model = aiplatform.gapic.Model(
74+
display_name=display_name,
75+
# The Cloud Storage location of the custom model
76+
artifact_uri=artifact_uri,
77+
explanation_spec=explanation_spec,
78+
container_spec=container_spec,
79+
)
80+
parent = f"projects/{project}/locations/{location}"
81+
response = client.upload_model(parent=parent, model=model)
82+
print("Long running operation:", response.operation.name)
83+
upload_model_response = response.result(timeout=timeout)
84+
print("upload_model_response:", upload_model_response)
85+
86+
87+
# [END aiplatform_upload_model_explain_tabular_managed_container_sample]
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# Copyright 2020 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import os
16+
17+
from uuid import uuid4
18+
19+
import pytest
20+
21+
import helpers
22+
23+
import upload_model_explain_tabular_managed_container_sample
24+
25+
PROJECT_ID = os.getenv("BUILD_SPECIFIC_GCLOUD_PROJECT")
26+
IMAGE_URI = "gcr.io/cloud-aiplatform/prediction/tf2-cpu.2-1:latest"
27+
ARTIFACT_URI = "gs://ucaip-samples-us-central1/model/boston_housing/"
28+
DISPLAY_NAME = f"temp_upload_model_test_{uuid4()}"
29+
30+
INPUT_TENSOR_NAME = "dense_input"
31+
OUTPUT_TENSOR_NAME = "dense_2"
32+
33+
34+
@pytest.fixture(scope="function", autouse=True)
35+
def teardown(teardown_model):
36+
yield
37+
38+
39+
def test_ucaip_generated_upload_model_explain_tabular_managed_constainer_sample(capsys, shared_state):
40+
41+
upload_model_explain_tabular_managed_container_sample.upload_model_explain_tabular_managed_container_sample(
42+
display_name=DISPLAY_NAME,
43+
artifact_uri=ARTIFACT_URI,
44+
container_spec_image_uri=IMAGE_URI,
45+
project=PROJECT_ID,
46+
input_tensor_name=INPUT_TENSOR_NAME,
47+
output_tensor_name=OUTPUT_TENSOR_NAME,
48+
feature_names=["crim", "zn", "indus", "chas", "nox", "rm", "age",
49+
"dis", "rad", "tax", "ptratio", "b", "lstat"]
50+
)
51+
52+
out, _ = capsys.readouterr()
53+
54+
shared_state["model_name"] = helpers.get_name(out, key="model")

0 commit comments

Comments
 (0)