Skip to content

Commit efb6d18

Browse files
authored
feat: add explanation metadata get_metadata_protobuf for reuse (#672)
* feat: add explanation metadata object for reuse * Fix test * address comments for renaming method name
1 parent 18e4be0 commit efb6d18

6 files changed

+87
-8
lines changed

README.rst

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ You can also create a batch prediction job asynchronously by including the `sync
304304
batch_prediction_job.state
305305
306306
# block until job is complete
307-
batch_prediction_job.wait()
307+
batch_prediction_job.wait()
308308
309309
310310
Endpoints
@@ -393,7 +393,7 @@ To create a Vertex Pipeline run:
393393
Explainable AI: Get Metadata
394394
----------------------------
395395

396-
To get metadata from TensorFlow 1 models:
396+
To get metadata in dictionary format from TensorFlow 1 models:
397397

398398
.. code-block:: Python
399399
@@ -404,7 +404,7 @@ To get metadata from TensorFlow 1 models:
404404
)
405405
generated_md = builder.get_metadata()
406406
407-
To get metadata from TensorFlow 2 models:
407+
To get metadata in dictionary format from TensorFlow 2 models:
408408

409409
.. code-block:: Python
410410
@@ -413,6 +413,20 @@ To get metadata from TensorFlow 2 models:
413413
builder = saved_model_metadata_builder.SavedModelMetadataBuilder('gs://python/to/my/model/dir')
414414
generated_md = builder.get_metadata()
415415
416+
To use Explanation Metadata in endpoint deployment and model upload:
417+
418+
.. code-block:: Python
419+
420+
explanation_metadata = builder.get_metadata_protobuf()
421+
422+
# To deploy a model to an endpoint with explanation
423+
model.deploy(..., explanation_metadata=explanation_metadata)
424+
425+
# To deploy a model to a created endpoint with explanation
426+
endpoint.deploy(..., explanation_metadata=explanation_metadata)
427+
428+
# To upload a model with explanation
429+
aiplatform.Model.upload(..., explanation_metadata=explanation_metadata)
416430
417431
418432
Next Steps

google/cloud/aiplatform/explain/metadata/metadata_builder.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,7 @@ class MetadataBuilder(_ABC):
2828
@abc.abstractmethod
2929
def get_metadata(self):
3030
"""Returns the current metadata as a dictionary."""
31+
32+
@abc.abstractmethod
33+
def get_metadata_protobuf(self):
34+
"""Returns the current metadata as ExplanationMetadata protobuf"""

google/cloud/aiplatform/explain/metadata/tf/v1/saved_model_metadata_builder.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,10 +113,17 @@ def get_metadata(self) -> Dict[str, Any]:
113113
Returns:
114114
Json format of the explanation metadata.
115115
"""
116-
current_md = explanation_metadata.ExplanationMetadata(
116+
return json_format.MessageToDict(self.get_metadata_protobuf()._pb)
117+
118+
def get_metadata_protobuf(self) -> explanation_metadata.ExplanationMetadata:
119+
"""Returns the current metadata as a Protobuf object.
120+
121+
Returns:
122+
ExplanationMetadata object format of the explanation metadata.
123+
"""
124+
return explanation_metadata.ExplanationMetadata(
117125
inputs=self._inputs, outputs=self._outputs,
118126
)
119-
return json_format.MessageToDict(current_md._pb)
120127

121128

122129
def _create_input_metadata_from_signature(

google/cloud/aiplatform/explain/metadata/tf/v2/saved_model_metadata_builder.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,14 @@ def get_metadata(self) -> Dict[str, Any]:
127127
Returns:
128128
Json format of the explanation metadata.
129129
"""
130-
current_md = explanation_metadata.ExplanationMetadata(
130+
return json_format.MessageToDict(self.get_metadata_protobuf()._pb)
131+
132+
def get_metadata_protobuf(self) -> explanation_metadata.ExplanationMetadata:
133+
"""Returns the current metadata as a Protobuf object.
134+
135+
Returns:
136+
ExplanationMetadata object format of the explanation metadata.
137+
"""
138+
return explanation_metadata.ExplanationMetadata(
131139
inputs=self._inputs, outputs=self._outputs,
132140
)
133-
return json_format.MessageToDict(current_md._pb)

tests/unit/aiplatform/test_explain_saved_model_metadata_builder_tf1_test.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
import tensorflow.compat.v1 as tf
1919

2020
from google.cloud.aiplatform.explain.metadata.tf.v1 import saved_model_metadata_builder
21+
from google.cloud.aiplatform.compat.types import (
22+
explanation_metadata_v1beta1 as explanation_metadata,
23+
)
2124

2225

2326
class SavedModelMetadataBuilderTF1Test(tf.test.TestCase):
@@ -68,6 +71,18 @@ def test_get_metadata_correct_inputs(self):
6871

6972
assert md_builder.get_metadata() == expected_md
7073

74+
def test_get_metadata_protobuf_correct_inputs(self):
75+
self._set_up()
76+
md_builder = saved_model_metadata_builder.SavedModelMetadataBuilder(
77+
self.model_path, tags=[tf.saved_model.tag_constants.SERVING]
78+
)
79+
expected_object = explanation_metadata.ExplanationMetadata(
80+
inputs={"x": {"input_tensor_name": "inp:0"}},
81+
outputs={"y": {"output_tensor_name": "Relu:0"}},
82+
)
83+
84+
assert md_builder.get_metadata_protobuf() == expected_object
85+
7186
def test_get_metadata_double_output(self):
7287
self._set_up()
7388
md_builder = saved_model_metadata_builder.SavedModelMetadataBuilder(
@@ -80,3 +95,16 @@ def test_get_metadata_double_output(self):
8095
}
8196

8297
assert md_builder.get_metadata() == expected_md
98+
99+
def test_get_metadata_protobuf_double_output(self):
100+
self._set_up()
101+
md_builder = saved_model_metadata_builder.SavedModelMetadataBuilder(
102+
self.model_path, signature_name="double", outputs_to_explain=["lin"]
103+
)
104+
105+
expected_object = explanation_metadata.ExplanationMetadata(
106+
inputs={"x": {"input_tensor_name": "inp:0"}},
107+
outputs={"lin": {"output_tensor_name": "Add:0"}},
108+
)
109+
110+
assert md_builder.get_metadata_protobuf() == expected_object

tests/unit/aiplatform/test_explain_saved_model_metadata_builder_tf2_test.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,13 @@
2020
import numpy as np
2121

2222
from google.cloud.aiplatform.explain.metadata.tf.v2 import saved_model_metadata_builder
23+
from google.cloud.aiplatform.compat.types import (
24+
explanation_metadata_v1beta1 as explanation_metadata,
25+
)
2326

2427

2528
class SavedModelMetadataBuilderTF2Test(tf.test.TestCase):
26-
def test_get_metadata_sequential(self):
29+
def _set_up_sequential(self):
2730
# Set up for the sequential.
2831
self.seq_model = tf.keras.models.Sequential()
2932
self.seq_model.add(tf.keras.layers.Dense(32, activation="relu", input_dim=10))
@@ -32,6 +35,9 @@ def test_get_metadata_sequential(self):
3235
self.saved_model_path = self.get_temp_dir()
3336
tf.saved_model.save(self.seq_model, self.saved_model_path)
3437

38+
def test_get_metadata_sequential(self):
39+
self._set_up_sequential()
40+
3541
builder = saved_model_metadata_builder.SavedModelMetadataBuilder(
3642
self.saved_model_path
3743
)
@@ -42,6 +48,19 @@ def test_get_metadata_sequential(self):
4248
}
4349
assert expected_md == generated_md
4450

51+
def test_get_metadata_protobuf_sequential(self):
52+
self._set_up_sequential()
53+
54+
builder = saved_model_metadata_builder.SavedModelMetadataBuilder(
55+
self.saved_model_path
56+
)
57+
generated_object = builder.get_metadata_protobuf()
58+
expected_object = explanation_metadata.ExplanationMetadata(
59+
inputs={"dense_input": {"input_tensor_name": "dense_input"}},
60+
outputs={"dense_2": {"output_tensor_name": "dense_2"}},
61+
)
62+
assert expected_object == generated_object
63+
4564
def test_get_metadata_functional(self):
4665
inputs1 = tf.keras.Input(shape=(10,), name="model_input1")
4766
inputs2 = tf.keras.Input(shape=(10,), name="model_input2")

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy