To use example-based explanations, you must configure explanations by specifying
an
explanationSpec
when you import or upload the Model
resource into the Model Registry.
Then, when you request online explanations, you can override some of those
configuration values by specifying an
ExplanationSpecOverride
in the request. You cannot request batch explanations; they are not supported.
This page describes how to configure and update these options.
Configure explanations when importing or uploading the model
Before you begin, make sure that you have following:
A Cloud Storage location that contains your model artifacts. Your model either needs to be a deep neural network (DNN) model where you provide the name of a layer, or signature, whose output can be used as the latent space, or you can provide a model that directly outputs embeddings (latent space representation). This latent space captures the example representations that are used for generating explanations.
A Cloud Storage location that contains the instances to be indexed for approximate nearest neighbor search. For more information, see input data requirements.
Console
Follow the guide to importing a model using the Google Cloud console.
In the Explainability tab, select Example-based explanation and fill in the fields.
For information about each field, see the tips in Google Cloud Console
(shown below) as well as the reference documentation for Example
and ExplanationMetadata
.
gcloud CLI
- Write the following
ExplanationMetadata
to a JSON file in your local environment. The filename does not matter, but for this example, call the fileexplanation-metadata.json
:
{
"inputs": {
"my_input": {
"inputTensorName": "INPUT_TENSOR_NAME",
"encoding": "IDENTITY",
},
"id": {
"inputTensorName": "id",
"encoding": "IDENTITY"
}
},
"outputs": {
"embedding": {
"outputTensorName": "OUTPUT_TENSOR_NAME"
}
}
}
- (Optional) If you are specifying the full
NearestNeighborSearchConfig
, write the following to a JSON file in your local environment. The filename does not matter, but for this example, call the filesearch_config.json
:
{
"contentsDeltaUri": "",
"config": {
"dimensions": 50,
"approximateNeighborsCount": 10,
"distanceMeasureType": "SQUARED_L2_DISTANCE",
"featureNormType": "NONE",
"algorithmConfig": {
"treeAhConfig": {
"leafNodeEmbeddingCount": 1000,
"fractionLeafNodesToSearch": 1.0
}
}
}
}
- Run the following command to upload your
Model
.
If you are using a Preset
search configuration, remove the
--explanation-nearest-neighbor-search-config-file
flag. If you are
specifying NearestNeighborSearchConfig
,
remove the --explanation-modality
and --explanation-query
flags.
The flags most pertinent to example-based explanations are bolded.
gcloud ai models upload \
--region=LOCATION \
--display-name=MODEL_NAME \
--container-image-uri=IMAGE_URI \
--artifact-uri=MODEL_ARTIFACT_URI \
--explanation-method=examples \
--uris=[URI, ...] \
--explanation-neighbor-count=NEIGHBOR_COUNT \
--explanation-metadata-file=explanation-metadata.json \
--explanation-modality=IMAGE|TEXT|TABULAR \
--explanation-query=PRECISE|FAST \
--explanation-nearest-neighbor-search-config-file=search_config.json
See gcloud ai models upload for more information.
-
The upload action returns an
OPERATION_ID
that can be used to check when the operation is finished. You can poll for the status of the operation until the response includes"done": true
. Use the gcloud ai operations describe command to poll the status, for example:gcloud ai operations describe <operation-id>
You will not be able to request explanations until the operation is done. Depending on the size of the dataset and model architecture, this step can take several hours to build the index used to query for examples.
REST
Before using any of the request data, make the following replacements:
- PROJECT
- LOCATION
To learn about the other placeholders, see Model
, explanationSpec
, and Examples
.
To learn more about uploading models, see the upload
method and Importing models.
The JSON request body below specifies a Preset
search configuration. Alternatively, you can specify the fullNearestNeighborSearchConfig
.
HTTP method and URL:
POST https://LOCATION-aiplatform.googleapis.com/v1/projects/PROJECT/locations/LOCATION/models:upload
Request JSON body:
{ "model": { "displayName": "my-model", "artifactUri": "gs://your-model-artifact-folder", "containerSpec": { "imageUri": "us-docker.pkg.dev/vertex-ai/prediction/tf2-cpu.2-11:latest", }, "explanationSpec": { "parameters": { "examples": { "gcsSource": { "uris": ["gs://your-examples-folder"] }, "neighborCount": 10, "presets": { "modality": "image" } } }, "metadata": { "outputs": { "embedding": { "output_tensor_name": "embedding" } }, "inputs": { "my_fancy_input": { "input_tensor_name": "input_tensor_name", "encoding": "identity", "modality": "image" }, "id": { "input_tensor_name": "id", "encoding": "identity" } } } } } }
To send your request, expand one of these options:
You should receive a JSON response similar to the following:
{ "name": "projects/PROJECT_NUMBER/locations/LOCATION/models/MODEL_ID/operations/OPERATION_ID", "metadata": { "@type": "type.googleapis.com/google.cloud.aiplatform.v1.UploadModelOperationMetadata", "genericMetadata": { "createTime": "2022-01-08T01:21:10.147035Z", "updateTime": "2022-01-08T01:21:10.147035Z" } } }
The upload action returns an OPERATION_ID
that can be used to check when the
operation is finished. You can poll for the status of the operation until
the response includes "done": true
. Use the gcloud ai operations describe command to poll the status, for example:
gcloud ai operations describe <operation-id>
You will not be able to request explanations until the operation is done. Depending on the size of the dataset and model architecture, this step can take several hours to build the index used to query for examples.
Python
See the section Upload the model in the image classification example-based explanations notebook.
NearestNeighborSearchConfig
The following JSON request body demonstrates how to specify the full
NearestNeighborSearchConfig
(instead of
presets) in an
upload
request.
{
"model": {
"displayName": displayname,
"artifactUri": model_path_to_deploy,
"containerSpec": {
"imageUri": DEPLOY_IMAGE,
},
"explanationSpec": {
"parameters": {
"examples": {
"gcsSource": {
"uris": [DATASET_PATH]
},
"neighborCount": 5,
"nearest_neighbor_search_config": {
"contentsDeltaUri": "",
"config": {
"dimensions": dimensions,
"approximateNeighborsCount": 10,
"distanceMeasureType": "SQUARED_L2_DISTANCE",
"featureNormType": "NONE",
"algorithmConfig": {
"treeAhConfig": {
"leafNodeEmbeddingCount": 1000,
"fractionLeafNodesToSearch": 1.0
}
}
}
}
}
},
"metadata": { ... }
}
}
}
The tables below lists the fields for NearestNeighborSearchConfig
.
Fields | |
---|---|
dimensions |
Required. The number of dimensions of the input vectors. Used for dense embeddings only. |
approximateNeighborsCount |
Required if tree-AH algorithm is used. The default number of neighbors to find through approximate search before exact reordering is performed. Exact reordering is a procedure where results returned by an approximate search algorithm are reordered using a more expensive distance computation. |
ShardSize |
ShardSize
The size of each shard. When an index is large, it is sharded based on the specified shard size. During serving, each shard is served on a separate node and scales independently. |
distanceMeasureType |
The distance measure used in nearest neighbor search. |
featureNormType |
Type of normalization to be carried out on each vector. |
algorithmConfig |
oneOf:
The configuration for the algorithms that Vector Search uses for efficient search. Used for dense embeddings only.
|
DistanceMeasureType
Enums | |
---|---|
SQUARED_L2_DISTANCE |
Euclidean (L2) Distance |
L1_DISTANCE |
Manhattan (L1) Distance |
DOT_PRODUCT_DISTANCE |
Default value. Defined as a negative of the dot product. |
COSINE_DISTANCE |
Cosine Distance. We strongly suggest using DOT_PRODUCT_DISTANCE + UNIT_L2_NORM instead of the COSINE distance. Our algorithms have been more optimized for the DOT_PRODUCT distance, and when combined with UNIT_L2_NORM, it offers the same ranking and mathematical equivalence as the COSINE distance. |
FeatureNormType
Enums | |
---|---|
UNIT_L2_NORM |
Unit L2 normalization type. |
NONE |
Default value. No normalization type is specified. |
TreeAhConfig
These are the fields to select for the tree-AH algorithm (Shallow tree + Asymmetric Hashing).
Fields | |
---|---|
fractionLeafNodesToSearch |
double |
The default fraction of leaf nodes that any query may be searched. Must be in range 0.0 - 1.0, exclusive. The default value is 0.05 if not set. | |
leafNodeEmbeddingCount |
int32 |
Number of embeddings on each leaf node. The default value is 1000 if not set. | |
leafNodesToSearchPercent |
int32 |
Deprecated, use fractionLeafNodesToSearch .The default percentage of leaf nodes that any query may be searched. Must be in range 1-100, inclusive. The default value is 10 (means 10%) if not set. |
BruteForceConfig
This option implements the standard linear search in the database for each
query. There are no fields to configure for a brute force search. To select this
algorithm, pass an empty object for BruteForceConfig
to algorithmConfig
.
Input data requirements
Upload your dataset to a Cloud Storage location. Make sure the files in the JSON Lines format.
The files must be in JSON Lines format. The following sample is from the image classification example-based explanations notebook:
{"id": "0", "bytes_inputs": {"b64": "..."}}
{"id": "1", "bytes_inputs": {"b64": "..."}}
{"id": "2", "bytes_inputs": {"b64": "..."}}
Update the index or configuration
Vertex AI lets you update a model's nearest neighbor index or
Example
configuration. This is
useful if you'd like to update your model without re-indexing its dataset. For
example, if your model's index contains 1,000 instances, and you'd like to add
500 more instances, you can call UpdateExplanationDataset
to add to the
index without re-processing the original 1,000 instances.
To update the explanation dataset:
Python
def update_explanation_dataset(model_id, new_examples):
response = clients["model"].update_explanation_dataset(model=model_id, examples=new_examples)
update_dataset_response = response.result()
return update_dataset_response
PRESET_CONFIG = {
"modality": "TEXT",
"query": "FAST"
}
NEW_DATASET_FILE_PATH = "new_dataset_path"
NUM_NEIGHBORS_TO_RETURN = 10
EXAMPLES = aiplatform.Examples(presets=PRESET_CONFIG,
gcs_source=aiplatform.types.io.GcsSource(uris=[NEW_DATASET_FILE_PATH]),
neighbor_count=NUM_NEIGHBORS_TO_RETURN)
MODEL_ID = 'model_id'
update_dataset_response = update_explanation_dataset(MODEL_ID, EXAMPLES)
Usage notes:
The
model_id
remains unchanged after theUpdateExplanationDataset
operation.The
UpdateExplanationDataset
operation affects only theModel
resource; it does not update any associatedDeployedModel
s. This means that adeployedModel
's index contains the dataset at the time it was deployed. To update adeployedModel
's index, you must re-deploy the updated model to an endpoint.
Override the configuration when getting online explanations
When you request an explanation, you can override some of the parameters on the
fly by specifying the
ExplanationSpecOverride
field.
Depending on the application, some constraints might be desirable on the kind of explanations that are returned. For example, to ensure diversity of explanations, a user can specify a crowding parameter which dictates that no single type of examples are over-represented in the explanations. Concretely, if a user is trying to understand why a bird was labeled as a plane by their model, they might not be interested in seeing too many bird examples as explanations to better investigate the root cause.
The following table summarizes the parameters that can be overridden for an example-based explanation request:
Property Name | Property Value | Description |
---|---|---|
neighborCount | int32 |
The number of examples to return as explanation |
crowdingCount | int32 |
Maximum number of examples to return with the same crowding tag |
allow | String Array |
The tags that are allowed for explanations to have |
deny | String Array |
The tags that are not allowed for explanations to have |
The Vector Search Filtering describes these parameters in more details.
Here's an example of a JSON request body with overrides:
{
"instances":[
{
"id": data[0]["id"],
"bytes_inputs": {"b64": bytes},
"restricts": "",
"crowding_tag": ""
}
],
"explanation_spec_override": {
"examples_override": {
"neighbor_count": 5,
"crowding_count": 2,
"restrictions": [
{
"namespace_name": "label",
"allow": ["Papilloma", "Rift_Valley", "TBE", "Influenza", "Ebol"]
}
]
}
}
}
What's next
Here's an example of the response from an example-based explain
request:
[
{
"neighbors":[
{
"neighborId":"311",
"neighborDistance":383.8
},
{
"neighborId":"286",
"neighborDistance":431.4
}
],
"input":"0"
},
{
"neighbors":[
{
"neighborId":"223",
"neighborDistance":471.6
},
{
"neighborId":"55",
"neighborDistance":392.7
}
],
"input":"1"
}
]
Pricing
See the section on example-based explanations in the pricing page.