refactor, chore, fix(egen): replace K80 with T4, template fixes (#3137)

* fix,refractor,chore(egen): refracted code according to template guidelines, performed linter testfixed and refactored notebook according to template

* refactor(egen): replaced the project_id with [you-project-id] according to template guidelines

* chore: template guideline fixes

* chore: corrects/rewords some sentences

* chore: minor markdown fixes

* chore(Egen):Done changes according to @kittyabs review and performed linter test.

* performed linter test

---------

Co-authored-by: sriramya2610 <sriramya.peddapally@egen.ai>
Co-authored-by: krishr2d2 <krishna.movva@egen.ai>
This commit is contained in:
Sri Ramya - SpringML
2024-06-26 21:39:13 +00:00
committed by GitHub
co-authored by sriramya2610 krishr2d2
parent a1bbe56d90
commit 3cff78caf0
@@ -32,21 +32,24 @@
"# Vertex SDK: Custom training tabular regression model for batch prediction with explainabilty\n",
"\n",
"<table align=\"left\">\n",
" <td>\n",
" <td style=\"text-align: center\">\n",
" <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/official/explainable_ai/sdk_custom_tabular_regression_batch_explain.ipynb\">\n",
" <img src=\"https://cloud.google.com/ml-engine/images/colab-logo-32px.png\" alt=\"Colab logo\"> Run in Colab\n",
" <img src=\"https://cloud.google.com/ml-engine/images/colab-logo-32px.png\" alt=\"Colab logo\"><br> Open in Colab\n",
" </a>\n",
" </td>\n",
" <td>\n",
" <td style=\"text-align: center\">\n",
" <a href=\"https://console.cloud.google.com/vertex-ai/colab/import/https:%2F%2Fraw.githubusercontent.com%2FGoogleCloudPlatform%2Fvertex-ai-samples%2Fmain%2Fnotebooks%2Fofficial%2Fexplainable_ai%2Fsdk_custom_tabular_regression_batch_explain.ipynb\">\n",
" <img width=\"32px\" src=\"https://cloud.google.com/ml-engine/images/colab-enterprise-logo-32px.png\" alt=\"Google Cloud Colab Enterprise logo\"><br> Open in Colab Enterprise\n",
" </a>\n",
" </td> \n",
" <td style=\"text-align: center\">\n",
" <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://raw.githubusercontent.com/GoogleCloudPlatform/vertex-ai-samples/main/notebooks/official/explainable_ai/sdk_custom_tabular_regression_batch_explain.ipynb\">\n",
" <img src=\"https://lh3.googleusercontent.com/UiNooY4LUgW_oTvpsNhPpQzsstV5W8F7rYgxgGBD85cWJoLmrOzhVs_ksK_vgx40SHs7jCqkTkCk=e14-rj-sc0xffffff-h130-w32\" alt=\"Vertex AI logo\"><br> Open in Workbench\n",
" </a>\n",
" </td>\n",
" <td style=\"text-align: center\">\n",
" <a href=\"https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/official/explainable_ai/sdk_custom_tabular_regression_batch_explain.ipynb\">\n",
" <img src=\"https://cloud.google.com/ml-engine/images/github-logo-32px.png\" alt=\"GitHub logo\">\n",
" View on GitHub\n",
" </a>\n",
" </td>\n",
" <td>\n",
" <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://raw.githubusercontent.com/GoogleCloudPlatform/vertex-ai-samples/main/notebooks/official/explainable_ai/sdk_custom_tabular_regression_batch_explain.ipynb\">\n",
" <img src=\"https://lh3.googleusercontent.com/UiNooY4LUgW_oTvpsNhPpQzsstV5W8F7rYgxgGBD85cWJoLmrOzhVs_ksK_vgx40SHs7jCqkTkCk=e14-rj-sc0xffffff-h130-w32\" alt=\"Vertex AI logo\">\n",
" Open in Vertex AI Workbench\n",
" <img src=\"https://cloud.google.com/ml-engine/images/github-logo-32px.png\" alt=\"GitHub logo\"><br> View on GitHub\n",
" </a>\n",
" </td>\n",
"</table>\n",
@@ -61,8 +64,7 @@
"source": [
"## Overview\n",
"\n",
"\n",
"This tutorial demonstrates how to use the Vertex AI SDK to train and deploy a custom tabular regression model for batch prediction with explanation.\n",
"This tutorial demonstrates how to use the Vertex AI SDK for Python to train and deploy a custom tabular regression model for batch prediction with explanations.\n",
"\n",
"Learn more about [Vertex Explainable AI](https://cloud.google.com/vertex-ai/docs/explainable-ai/overview) and [Vertex AI Batch Prediction](https://cloud.google.com/vertex-ai/docs/tabular-data/classification-regression/get-batch-predictions)."
]
@@ -70,45 +72,45 @@
{
"cell_type": "markdown",
"metadata": {
"id": "objective:custom,training,batch_prediction,xai"
"id": "82a273206a67"
},
"source": [
"### Objective\n",
"\n",
"In this tutorial, you learn how to use `Vertex AI Training and Explainable AI` to create a custom image classification model with explanations, and then you learn to use `Vertex AI Batch Prediction` to make a batch prediction request with explanations. You can alternatively create custom models using `gcloud` command-line tool or online using Cloud Console.\n",
"In this tutorial, you learn how to use Vertex AI training and Explainable AI to create a custom image classification model with explanations. Then, you learn how to use the Vertex AI batch prediction service to make a batch prediction request with explanations. Alternatively, you can create custom models using `gcloud` command-line tool or online using Cloud Console.\n",
"\n",
"This tutorial uses the following Google Cloud ML services:\n",
"This tutorial uses the following Vertex AI services:\n",
"\n",
"- `Vertex AI Training`\n",
"- `Vertex AI Batch Prediction`\n",
"- `Vertex Explainable AI`\n",
"- `Vertex AI Model` resource\n",
"- Vertex AI Training\n",
"- Vertex AI batch prediction\n",
"- Vertex Explainable AI\n",
"- Vertex AI model resource\n",
"\n",
"\n",
"The steps performed include:\n",
"\n",
"- Create a `Vertex AI` custom job for training a TensorFlow model.\n",
"- Create a Vertex AI custom job for training a TensorFlow model.\n",
"- View the model evaluation for the trained model.\n",
"- Set explanation parameters for when the model is deployed.\n",
"- Upload the trained model artifacts and explanations as a `Model` resource.\n",
"- Set explanation parameters for the model.\n",
"- Upload the trained model artifacts as a model resource.\n",
"- Make a batch prediction with explanations."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "dataset:custom,boston,lrg"
"id": "543b0e9b3b33"
},
"source": [
"### Dataset\n",
"\n",
"The dataset used for this tutorial is the [Boston Housing Prices dataset](https://www.cs.toronto.edu/~delve/data/boston/bostonDetail.html). The version of the dataset you will use in this tutorial is built into TensorFlow. The trained model predicts the median price of a house in units of 1K USD."
"The dataset used for this tutorial is the [Boston Housing Prices dataset](https://www.cs.toronto.edu/~delve/data/boston/bostonDetail.html). The version of the dataset you use in this tutorial is the one that's available from TensorFlow SDK. The trained model predicts the median price of a house in units of 1K USD."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "costs"
"id": "181d4dfbf917"
},
"source": [
"### Costs\n",
@@ -128,12 +130,19 @@
{
"cell_type": "markdown",
"metadata": {
"id": "install_aip:mbsdk"
"id": "f0316df526f8"
},
"source": [
"## Installation\n",
"\n",
"Install the packages required for executing this notebook."
"## Get started"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "deda65b8cc6e"
},
"source": [
"### Install Vertex AI SDK for Python and other required packages"
]
},
{
@@ -144,49 +153,88 @@
},
"outputs": [],
"source": [
"! pip3 install --upgrade --quiet google-cloud-aiplatform==1.36.0 \\\n",
"! pip3 install --upgrade --quiet google-cloud-aiplatform \\\n",
" google-cloud-storage \\\n",
" tensorflow==2.11"
" tensorflow==2.15.1"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "restart"
"id": "install_aip:mbsdk"
},
"source": [
"### Colab only: Uncomment the following cell to restart the kernel"
"### Restart runtime (Colab only)\n",
"\n",
"To use the newly installed packages, you must restart the runtime on Google Colab."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "D-ZBOjErv5mM"
"id": "f09b4dff629a"
},
"outputs": [],
"source": [
"# Automatically restart kernel after installs so that your environment can access the new packages\n",
"# import IPython\n",
"import sys\n",
"\n",
"# app = IPython.Application.instance()\n",
"# app.kernel.do_shutdown(True)"
"if \"google.colab\" in sys.modules:\n",
"\n",
" import IPython\n",
"\n",
" app = IPython.Application.instance()\n",
" app.kernel.do_shutdown(True)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "yfEglUHQk9S3"
"id": "4a2b7b59bbf7"
},
"source": [
"## Before you begin\n",
"<div class=\"alert alert-block alert-warning\">\n",
"<b>⚠️ The kernel is going to restart. Wait until it's finished before continuing to the next step. ⚠️</b>\n",
"</div>"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "f82e28c631cc"
},
"source": [
"### Authenticate your notebook environment (Colab only)\n",
"\n",
"### Set your project ID\n",
"Authenticate your environment on Google Colab."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "46604f70e831"
},
"outputs": [],
"source": [
"import sys\n",
"\n",
"**If you don't know your project ID**, try the following:\n",
"* Run `gcloud config list`.\n",
"* Run `gcloud projects list`.\n",
"* See the support page: [Locate the project ID](https://support.google.com/googleapi/answer/7014113)"
"if \"google.colab\" in sys.modules:\n",
"\n",
" from google.colab import auth\n",
"\n",
" auth.authenticate_user()"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "c708f022953d"
},
"source": [
"### Set Google Cloud project information \n",
"\n",
"Learn more about [setting up a project and a development environment](https://cloud.google.com/vertex-ai/docs/start/cloud-environment)."
]
},
{
@@ -198,89 +246,7 @@
"outputs": [],
"source": [
"PROJECT_ID = \"[your-project-id]\" # @param {type:\"string\"}\n",
"\n",
"# Set the project id\n",
"! gcloud config set project {PROJECT_ID}"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "region"
},
"source": [
"#### Region\n",
"\n",
"You can also change the `REGION` variable used by Vertex AI. Learn more about [Vertex AI regions](https://cloud.google.com/vertex-ai/docs/general/locations)."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "region"
},
"outputs": [],
"source": [
"REGION = \"us-central1\" # @param {type: \"string\"}"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "gcp_authenticate"
},
"source": [
"### Authenticate your Google Cloud account\n",
"\n",
"Depending on your Jupyter environment, you may have to manually authenticate. Follow the relevant instructions below.\n",
"\n",
"**1. Vertex AI Workbench**\n",
"* Do nothing as you are already authenticated.\n",
"\n",
"**2. Local JupyterLab instance, uncomment and run:**"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "ce6043da7b33"
},
"outputs": [],
"source": [
"# ! gcloud auth login"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "0367eac06a10"
},
"source": [
"**3. Colab, uncomment and run:**"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "21ad4dbb4a61"
},
"outputs": [],
"source": [
"# from google.colab import auth\n",
"# auth.authenticate_user()"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "c13224697bfb"
},
"source": [
"**4. Service account or other**\n",
"* See how to grant Cloud Storage permissions to your service account at https://cloud.google.com/storage/docs/gsutil/commands/iam#ch-examples."
"LOCATION = \"us-central1\" # @param {type: \"string\"}"
]
},
{
@@ -311,7 +277,7 @@
"id": "create_bucket"
},
"source": [
"**Only if your bucket doesn't already exist**: Run the following cell to create your Cloud Storage bucket."
"**If your bucket doesn't already exist**: Run the following cell to create your Cloud Storage bucket."
]
},
{
@@ -322,7 +288,7 @@
},
"outputs": [],
"source": [
"! gsutil mb -l {REGION} {BUCKET_URI}"
"! gsutil mb -l {LOCATION} -p {PROJECT_ID} {BUCKET_URI}"
]
},
{
@@ -331,10 +297,7 @@
"id": "setup_vars"
},
"source": [
"### Set up variables\n",
"\n",
"Next, set up some variables used throughout the tutorial.\n",
"### Import libraries and define constants"
"### Import libraries"
]
},
{
@@ -347,7 +310,8 @@
"source": [
"import os\n",
"\n",
"import google.cloud.aiplatform as aip"
"import tensorflow as tf\n",
"from google.cloud import aiplatform"
]
},
{
@@ -358,7 +322,7 @@
"source": [
"### Initialize Vertex AI SDK for Python\n",
"\n",
"Initialize the Vertex AI SDK for Python for your project and corresponding bucket."
"To get started using Vertex AI, you must [enable the Vertex AI API](https://console.cloud.google.com/flows/enableapi?apiid=aiplatform.googleapis.com). "
]
},
{
@@ -369,7 +333,7 @@
},
"outputs": [],
"source": [
"aip.init(project=PROJECT_ID, staging_bucket=BUCKET_URI)"
"aiplatform.init(project=PROJECT_ID, location=LOCATION, staging_bucket=BUCKET_URI)"
]
},
{
@@ -382,16 +346,16 @@
"\n",
"You can set hardware accelerators for training and prediction.\n",
"\n",
"Set the variables `TRAIN_GPU/TRAIN_NGPU` and `DEPLOY_GPU/DEPLOY_NGPU` to use a container image supporting a GPU and the number of GPUs allocated to the virtual machine (VM) instance. For example, to use a GPU container image with 4 Nvidia Telsa K80 GPUs allocated to each VM, you would specify:\n",
"Set the variables `TRAIN_GPU/TRAIN_NGPU` and `DEPLOY_GPU/DEPLOY_NGPU` to use a container image supporting a GPU and the number of GPUs allocated to the virtual machine (VM) instance. For example, to use a GPU container image with 4 Nvidia Telsa T4 GPUs allocated to each VM, you specify:\n",
"\n",
" (aip.gapic.AcceleratorType.NVIDIA_TESLA_K80, 4)\n",
" (aiplatform.gapic.AcceleratorType.NVIDIA_TESLA_T4, 4)\n",
"\n",
"\n",
"Otherwise specify `(None, None)` to use a container image to run on a CPU.\n",
"\n",
"Learn more [here](https://cloud.google.com/vertex-ai/docs/general/locations#accelerators) hardware accelerator support for your region\n",
"Learn more about [hardware accelerator support for regions](https://cloud.google.com/vertex-ai/docs/general/locations#accelerators).\n",
"\n",
"*Note*: TF releases before 2.3 for GPU support will fail to load the custom model in this tutorial. It is a known issue and fixed in TF 2.3 -- which is caused by static graph ops that are generated in the serving function. If you encounter this issue on your own custom models, use a container image for TF 2.3 with GPU support."
"**Note**: TF releases before 2.3 for GPU support fail to load the custom model in this tutorial. It's a known issue and fixed in TF 2.3 -- which is caused by static graph ops that are generated in the serving function. If you encounter this issue on your own custom models, use a container image for TF 2.3 with GPU support."
]
},
{
@@ -404,7 +368,7 @@
"source": [
"if os.getenv(\"IS_TESTING_TRAIN_GPU\"):\n",
" TRAIN_GPU, TRAIN_NGPU = (\n",
" aip.gapic.AcceleratorType.NVIDIA_TESLA_K80,\n",
" aiplatform.gapic.AcceleratorType.NVIDIA_TESLA_T4,\n",
" int(os.getenv(\"IS_TESTING_TRAIN_GPU\")),\n",
" )\n",
"else:\n",
@@ -412,7 +376,7 @@
"\n",
"if os.getenv(\"IS_TESTING_DEPLOY_GPU\"):\n",
" DEPLOY_GPU, DEPLOY_NGPU = (\n",
" aip.gapic.AcceleratorType.NVIDIA_TESLA_K80,\n",
" aiplatform.gapic.AcceleratorType.NVIDIA_TESLA_T4,\n",
" int(os.getenv(\"IS_TESTING_DEPLOY_GPU\")),\n",
" )\n",
"else:\n",
@@ -465,10 +429,10 @@
" DEPLOY_VERSION = \"tf-cpu.{}\".format(TF)\n",
"\n",
"TRAIN_IMAGE = \"{}-docker.pkg.dev/vertex-ai/training/{}:latest\".format(\n",
" REGION.split(\"-\")[0], TRAIN_VERSION\n",
" LOCATION.split(\"-\")[0], TRAIN_VERSION\n",
")\n",
"DEPLOY_IMAGE = \"{}-docker.pkg.dev/vertex-ai/prediction/{}:latest\".format(\n",
" REGION.split(\"-\")[0], DEPLOY_VERSION\n",
" LOCATION.split(\"-\")[0], DEPLOY_VERSION\n",
")\n",
"\n",
"print(\"Training:\", TRAIN_IMAGE, TRAIN_GPU, TRAIN_NGPU)\n",
@@ -485,19 +449,19 @@
"\n",
"Next, set the machine type to use for training and prediction.\n",
"\n",
"- Set the variables `TRAIN_COMPUTE` and `DEPLOY_COMPUTE` to configure the compute resources for the VMs you will use for for training and prediction.\n",
"- Set the variables `TRAIN_COMPUTE` and `DEPLOY_COMPUTE` to configure the compute resources for the VMs used for training and prediction.\n",
" - `machine type`\n",
" - `n1-standard`: 3.75GB of memory per vCPU.\n",
" - `n1-highmem`: 6.5GB of memory per vCPU\n",
" - `n1-highcpu`: 0.9 GB of memory per vCPU\n",
" - `vCPUs`: number of \\[2, 4, 8, 16, 32, 64, 96 \\]\n",
"\n",
"*Note: The following is not supported for training:*\n",
"**Note**: The following isn't supported for training:\n",
"\n",
" - `standard`: 2 vCPUs\n",
" - `highcpu`: 2, 4 and 8 vCPUs\n",
"\n",
"*Note: You may also use n2 and e2 machine types for training and deployment, but they do not support GPUs*."
"**Note**: You may also use n2 and e2 machine types for training and deployment, but they don't support GPUs."
]
},
{
@@ -527,17 +491,6 @@
"print(\"Deploy machine type\", DEPLOY_COMPUTE)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "tutorial_start:custom"
},
"source": [
"# Tutorial\n",
"\n",
"Now you are ready to start creating your own custom model and training for Boston Housing."
]
},
{
"cell_type": "markdown",
"metadata": {
@@ -548,7 +501,7 @@
"\n",
"#### Package layout\n",
"\n",
"Before you start the training, you will look at how a Python package is assembled for a custom training job. When unarchived, the package contains the following directory/file layout.\n",
"Before you start training, look at how a Python package is assembled for a custom training job. When unarchived, the package contains the following directory/file layout.\n",
"\n",
"- PKG-INFO\n",
"- README.md\n",
@@ -560,11 +513,13 @@
"\n",
"The files `setup.cfg` and `setup.py` are the instructions for installing the package into the operating environment of the Docker image.\n",
"\n",
"The file `trainer/task.py` is the Python script for executing the custom training job. *Note*, when we referred to it in the worker pool specification, we replace the directory slash with a dot (`trainer.task`) and dropped the file suffix (`.py`).\n",
"The file `trainer/task.py` is the Python script for executing the custom training job. \n",
"\n",
"**Note**: When referring to the worker pool specification, the directory slash is replaced with a dot (`trainer.task`) and file suffix (`.py`) is dropped.\n",
"\n",
"#### Package Assembly\n",
"\n",
"In the following cells, you will assemble the training package."
"In the following cells, you assemble the training package."
]
},
{
@@ -604,10 +559,12 @@
"source": [
"#### Task.py contents\n",
"\n",
"In the next cell, you write the contents of the training script task.py. I won't go into detail, it's just there for you to browse. In summary:\n",
"In the next cell, you write the contents of the training script task.py. \n",
"\n",
"In summary, *task.py* script does the following:\n",
"\n",
"- Get the directory where to save the model artifacts from the command line (`--model_dir`), and if not specified, then from the environment variable `AIP_MODEL_DIR`.\n",
"- Loads Boston Housing dataset from TF.Keras builtin datasets\n",
"- Loads Boston Housing dataset from TF.Keras builtin datasets.\n",
"- Builds a simple deep neural network model using TF.Keras model API.\n",
"- Compiles the model (`compile()`).\n",
"- Sets a training distribution strategy according to the argument `args.distribute`.\n",
@@ -736,7 +693,7 @@
"source": [
"#### Store training script on your Cloud Storage bucket\n",
"\n",
"Next, you package the training folder into a compressed tar ball, and then store it in your Cloud Storage bucket."
"Next, package the training folder into a compressed tar ball, and then store it in your Cloud Storage bucket."
]
},
{
@@ -782,7 +739,7 @@
},
"outputs": [],
"source": [
"job = aip.CustomTrainingJob(\n",
"job = aiplatform.CustomTrainingJob(\n",
" display_name=\"boston\",\n",
" script_path=\"custom/trainer/task.py\",\n",
" container_uri=TRAIN_IMAGE,\n",
@@ -798,16 +755,16 @@
"id": "prepare_custom_cmdargs"
},
"source": [
"### Prepare your command-line arguments\n",
"### Prepare your training parameters\n",
"\n",
"Now define the command-line arguments for your custom training container:\n",
"\n",
"- `args`: The command-line arguments to pass to the executable that is set as the entry point into the container.\n",
" - `--model-dir` : For our demonstrations, we use this command-line argument to specify where to store the model artifacts.\n",
" - direct: You pass the Cloud Storage location as a command line argument to your training script (set variable `DIRECT = True`), or\n",
" - indirect: The service passes the Cloud Storage location as the environment variable `AIP_MODEL_DIR` to your training script (set variable `DIRECT = False`). In this case, you tell the service the model artifact location in the job specification.\n",
" - `\"--epochs=\" + EPOCHS`: The number of epochs for training.\n",
" - `\"--steps=\" + STEPS`: The number of steps per epoch."
"- `args`: The command-line arguments to pass to the executable that's set as the entry point into the container.\n",
" - `--model-dir`: Command-line argument to specify where to store the model artifacts. You can use either of the following methods to specify the storage location for artifacts.\n",
" - **method-1**(set `DIRECT` to `True`): You pass the Cloud Storage location as a command line argument to your training script.\n",
" - **method-2**(set `DIRECT` to `False`): The service passes the Cloud Storage location as the environment variable `AIP_MODEL_DIR` to your training script. In this case, you tell the service the model artifact location in the job specification.\n",
" - `--epochs`: The number of epochs for training.\n",
" - `--steps`: The number of steps per epoch."
]
},
{
@@ -823,7 +780,7 @@
"EPOCHS = 20\n",
"STEPS = 100\n",
"\n",
"DIRECT = True\n",
"DIRECT = True # Set False to use AIP_MODEL_DIR\n",
"if DIRECT:\n",
" CMDARGS = [\n",
" \"--model-dir=\" + MODEL_DIR,\n",
@@ -845,15 +802,15 @@
"source": [
"#### Run the custom training job\n",
"\n",
"Next, you run the custom job to start the training job by invoking the method `run`, with the following parameters:\n",
"Next, you run the custom job to start the training job by invoking the `run()` method, with the following parameters:\n",
"\n",
"- `args`: The command-line arguments to pass to the training script.\n",
"- `replica_count`: The number of compute instances for training (replica_count = 1 is single node training).\n",
"- `machine_type`: The machine type for the compute instances.\n",
"- `accelerator_type`: The hardware accelerator type.\n",
"- `accelerator_count`: The number of accelerators to attach to a worker replica.\n",
"- `base_output_dir`: The Cloud Storage location to write the model artifacts to.\n",
"- `sync`: Whether to block until completion of the job."
"- `base_output_dir`: The Cloud Storage location to store the model artifacts.\n",
"- `sync`: Set **True** to wait until the completion of the job."
]
},
{
@@ -894,9 +851,9 @@
"source": [
"## Load the saved model\n",
"\n",
"Your model is stored in a TensorFlow SavedModel format in a Cloud Storage bucket. Now load it from the Cloud Storage bucket, and then you can do some things, like evaluate the model, and do a prediction.\n",
"Your model is stored in a TensorFlow SavedModel format in a Cloud Storage bucket. Now, load it from the Cloud Storage bucket, and then you can run model evaluation and prepare it for batch prediction requests.\n",
"\n",
"To load, you use the TF.Keras `model.load_model()` method passing it the Cloud Storage path where the model is saved -- specified by `MODEL_DIR`."
"To load, use the TF.Keras `model.load_model()` method passing it the Cloud Storage path where the model is saved -- specified by `MODEL_DIR`."
]
},
{
@@ -907,8 +864,6 @@
},
"outputs": [],
"source": [
"import tensorflow as tf\n",
"\n",
"local_model = tf.keras.models.load_model(MODEL_DIR)"
]
},
@@ -920,18 +875,15 @@
"source": [
"## Evaluate the model\n",
"\n",
"Now let's find out how good the model is.\n",
"Now, find out how good the model performs. Prepare some test data for evaluation and run the `evaluate()` method.\n",
"\n",
"### Load evaluation data\n",
"\n",
"You will load the Boston Housing test (holdout) data from `tf.keras.datasets`, using the method `load_data()`. This returns the dataset as a tuple of two elements. The first element is the training data and the second is the test data. Each element is also a tuple of two elements: the feature data, and the corresponding labels (median value of owner-occupied home).\n",
"Load the Boston Housing test (holdout) data from `tf.keras.datasets`, using the `load_data()` method. This returns the dataset as a tuple of two elements. The first element is the training data and the second one is the test data. Each element is again a tuple of two elements: the feature data, and the corresponding labels (median value of owner-occupied home).\n",
"\n",
"You don't need the training data, and hence why we loaded it as `(_, _)`.\n",
"For this step, you don't need the training data. Hence, you skip it by loading as `(_, _)`.\n",
"\n",
"Before you can run the data through evaluation, you need to preprocess it:\n",
"\n",
"`x_test`:\n",
"1. Normalize (rescale) the data in each column by dividing each value by the maximum value of that column. This replaces each single value with a 32-bit floating point number between 0 and 1."
"Before you can use the data for evaluation, you need to preprocess it. Normalize (rescale) the data in each column by dividing each value by the maximum value of that column. This replaces each single value with a 32-bit floating point number between 0 and 1."
]
},
{
@@ -976,7 +928,7 @@
"source": [
"### Perform the model evaluation\n",
"\n",
"Now evaluate how well the model in the custom job did."
"Use the model's `evaluate()` method to perform the evaluation."
]
},
{
@@ -1000,7 +952,7 @@
"\n",
"You can get the signatures of your model's input and output layers by reloading the model into memory, and querying it for the signatures corresponding to each layer.\n",
"\n",
"When making a prediction request, you need to route the request to the serving function instead of the model, so you need to know the input layer name of the serving function -- which you will use later when you make a prediction request.\n",
"When making a prediction request, you need to route the request to the serving function instead of the model. Therefore, you need to know the input layer name of the serving function -- which you use later when you make a prediction request.\n",
"\n",
"You also need to know the name of the serving function's input and output layer for constructing the explanation metadata -- which is discussed subsequently."
]
@@ -1034,38 +986,38 @@
"id": "explanation_spec"
},
"source": [
"### Explanation Specification\n",
"### Explanation specification\n",
"\n",
"To get explanations when doing a prediction, you must enable the explanation capability and set corresponding settings when you upload your custom model to an Vertex `Model` resource. These settings are referred to as the explanation metadata, which consists of:\n",
"To get explanations when doing a prediction, you must enable the explanation capability and set corresponding settings when you upload your custom model to a Vertex AI model resource. These settings are referred to as the explanation metadata, which consists of:\n",
"\n",
"- `parameters`: This is the specification for the explainability algorithm to use for explanations on your model. You can choose between:\n",
" - Shapley - *Note*, not recommended for image data -- can be very long running\n",
" - Shapley(**Note**: Not recommended for image data since it can be very long running)\n",
" - XRAI\n",
" - Integrated Gradients\n",
"- `metadata`: This is the specification for how the algoithm is applied on your custom model.\n",
"\n",
"#### Explanation Parameters\n",
"#### Explanation parameters\n",
"\n",
"Let's first dive deeper into the settings for the explainability algorithm.\n",
"Take a look at a detailed overview of the settings for the explainability algorithm.\n",
"\n",
"#### Shapley\n",
"\n",
"Assigns credit for the outcome to each feature, and considers different permutations of the features. This method provides a sampling approximation of exact Shapley values.\n",
"\n",
"Use Cases:\n",
"Use cases:\n",
" - Classification and regression on tabular data.\n",
"\n",
"Parameters:\n",
"\n",
"- `path_count`: This is the number of paths over the features that will be processed by the algorithm. An exact approximation of the Shapley values requires M! paths, where M is the number of features. For the CIFAR10 dataset, this would be 784 (28*28).\n",
"- `path_count`: This is the number of paths over the features processed by the algorithm. An exact approximation of the Shapley values requires M! paths, where M is the number of features. For the CIFAR10 dataset, this would be 784 (28*28).\n",
"\n",
"For any non-trival number of features, this is too compute expensive. You can reduce the number of paths over the features to M * `path_count`.\n",
"For any non-trival number of features, this is very compute expensive. You can reduce the number of paths over the features to M * `path_count`.\n",
"\n",
"#### Integrated Gradients\n",
"\n",
"A gradients-based method to efficiently compute feature attributions with the same axiomatic properties as the Shapley value.\n",
"\n",
"Use Cases:\n",
"Use cases:\n",
" - Classification and regression on tabular data.\n",
" - Classification on image data.\n",
"\n",
@@ -1077,7 +1029,7 @@
"\n",
"Based on the integrated gradients method, XRAI assesses overlapping regions of the image to create a saliency map, which highlights relevant regions of the image rather than pixels.\n",
"\n",
"Use Cases:\n",
"Use cases:\n",
"\n",
" - Classification on image data.\n",
"\n",
@@ -1085,7 +1037,7 @@
"\n",
"- `step_count`: This is the number of steps to approximate the remaining sum. The more steps, the more accurate the integral approximation. The general rule of thumb is 50 steps, but as you increase so does the compute time.\n",
"\n",
"In the next code cell, set the variable `XAI` to which explainabilty algorithm you will use on your custom model."
"In the next code cell, set the variable `XAI` to the explainabilty algorithm you use on your custom model."
]
},
{
@@ -1105,7 +1057,7 @@
"elif XAI == \"xrai\":\n",
" PARAMETERS = {\"xrai_attribution\": {\"step_count\": 50}}\n",
"\n",
"parameters = aip.explain.ExplanationParameters(PARAMETERS)"
"parameters = aiplatform.explain.ExplanationParameters(PARAMETERS)"
]
},
{
@@ -1114,15 +1066,15 @@
"id": "explanation_metadata:tabular"
},
"source": [
"#### Explanation Metadata\n",
"#### Explanation metadata\n",
"\n",
"Let's first dive deeper into the explanation metadata, which consists of:\n",
"Now, let's dive deeper into the explanation metadata which consists of:\n",
"\n",
"- `outputs`: A scalar value in the output to attribute -- what to explain. For example, in a probability output \\[0.1, 0.2, 0.7\\] for classification, one wants an explanation for 0.7. Consider the following formulae, where the output is `y` and that is what we want to explain.\n",
"- `outputs`: A scalar value in the output to attribute -- what to explain. For example, in a probability output \\[0.1, 0.2, 0.7\\] for classification, one wants an explanation for 0.7. Consider the following formula, where the output is `y` and that's what you want to explain.\n",
"\n",
" y = f(x)\n",
"\n",
"Consider the following formulae, where the outputs are `y` and `z`. Since we can only do attribution for one scalar value, we have to pick whether we want to explain the output `y` or `z`. Assume in this example the model is object detection and y and z are the bounding box and the object classification. You would want to pick which of the two outputs to explain.\n",
"Consider the following formulae, where the outputs are `y` and `z`. Since you can only do attribution for one scalar value, you have to pick whether you want to explain the output `y` or `z`. Assume in this example the model is object detection and y and z are the bounding box and the object classification. You'd want to pick which of the two outputs to explain.\n",
"\n",
" y, z = f(x)\n",
"\n",
@@ -1136,10 +1088,10 @@
"<blockquote>\n",
" - [your_display_name]: A human readable name you assign to the output to explain. A common example is \"probability\".<br/>\n",
" - \"output_tensor_name\": The key/value field to identify the output layer to explain. <br/>\n",
" - [layer]: The output layer to explain. In a single task model, like a tabular regressor, it is the last (topmost) layer in the model.\n",
" - [layer]: The output layer to explain. In a single task model, like a tabular regressor, it's the last (topmost) layer in the model.\n",
"</blockquote>\n",
"\n",
"- `inputs`: The features for attribution -- how they contributed to the output. Consider the following formulae, where `a` and `b` are the features. We have to pick which features to explain how the contributed. Assume that this model is deployed for A/B testing, where `a` are the data_items for the prediction and `b` identifies whether the model instance is A or B. You would want to pick `a` (or some subset of) for the features, and not `b` since it does not contribute to the prediction.\n",
"- `inputs`: The features for attribution -- how they contributed to the output. Consider the following formulae, where `a` and `b` are the features. You have to pick which features to explain how the contributed. Assume that this model is deployed for A/B testing, where `a` are the data_items for the prediction and `b` identifies whether the model instance is A or B. You'd want to pick `a` (or some subset of) for the features, and not `b` since it doesn't contribute to the prediction.\n",
"\n",
" y = f(a,b)\n",
"\n",
@@ -1153,7 +1105,7 @@
"<blockquote>\n",
" - [your_display_name]: A human readable name you assign to the input to explain. A common example is \"features\".<br/>\n",
" - \"input_tensor_name\": The key/value field to identify the input layer for the feature attribution. <br/>\n",
" - [layer]: The input layer for feature attribution. In a single input tensor model, it is the first (bottom-most) layer in the model.\n",
" - [layer]: The input layer for feature attribution. In a single input tensor model, it's the first (bottom-most) layer in the model.\n",
"</blockquote>\n",
"\n",
"Since the inputs to the model are tabular, you can specify the following two additional fields as reporting/visualization aids:\n",
@@ -1166,7 +1118,7 @@
"\n",
"<blockquote>\n",
" - \"encoding\": \"BAG_OF_FEATURES\" : Indicates that the inputs are set of tabular features.<br/>\n",
" - \"index_feature_mapping\": [ feature-names ] : A list of human readable names for each feature. For this example, we use the feature names specified in the dataset.<br/>\n",
" - \"index_feature_mapping\": [ feature-names ] : A list of human readable names for each feature. For this example, you use the feature names specified in the dataset.<br/>\n",
" - \"modality\": \"numeric\": Indicates the field values are numeric.\n",
"</blockquote>"
]
@@ -1202,10 +1154,10 @@
"\n",
"OUTPUT_METADATA = {\"output_tensor_name\": serving_output}\n",
"\n",
"input_metadata = aip.explain.ExplanationMetadata.InputMetadata(INPUT_METADATA)\n",
"output_metadata = aip.explain.ExplanationMetadata.OutputMetadata(OUTPUT_METADATA)\n",
"input_metadata = aiplatform.explain.ExplanationMetadata.InputMetadata(INPUT_METADATA)\n",
"output_metadata = aiplatform.explain.ExplanationMetadata.OutputMetadata(OUTPUT_METADATA)\n",
"\n",
"metadata = aip.explain.ExplanationMetadata(\n",
"metadata = aiplatform.explain.ExplanationMetadata(\n",
" inputs={\"features\": input_metadata}, outputs={\"medv\": output_metadata}\n",
")"
]
@@ -1218,14 +1170,14 @@
"source": [
"## Upload the model\n",
"\n",
"Next, upload your model to a `Model` resource using `Model.upload()` method, with the following parameters:\n",
"Next, upload your model to Vertex AI Model Registry using `Model.upload()` method, with the following parameters:\n",
"\n",
"- `display_name`: The human readable name for the `Model` resource.\n",
"- `display_name`: The human readable name for the model resource.\n",
"- `artifact`: The Cloud Storage location of the trained model artifacts.\n",
"- `serving_container_image_uri`: The serving container image.\n",
"- `sync`: Whether to execute the upload asynchronously or synchronously.\n",
"- `explanation_parameters`: Parameters to configure explaining for `Model`'s predictions.\n",
"- `explanation_metadata`: Metadata describing the `Model`'s input and output for explanation.\n",
"- `explanation_parameters`: Parameters to configure explaining for model's predictions.\n",
"- `explanation_metadata`: Metadata describing the model's input and output for explanation.\n",
"\n",
"If the `upload()` method is run asynchronously, you can subsequently block until completion with the `wait()` method."
]
@@ -1238,7 +1190,7 @@
},
"outputs": [],
"source": [
"model = aip.Model.upload(\n",
"model = aiplatform.Model.upload(\n",
" display_name=\"boston\",\n",
" artifact_uri=MODEL_DIR,\n",
" serving_container_image_uri=DEPLOY_IMAGE,\n",
@@ -1258,7 +1210,7 @@
"source": [
"## Send a batch prediction request\n",
"\n",
"Send a batch prediction to your deployed model."
"Create test items as your input to the batch prediction request. Then, send a batch prediction request to your deployed model. "
]
},
{
@@ -1280,7 +1232,7 @@
"source": [
"### Make the batch input file\n",
"\n",
"Now make a batch input file, which you will store in your local Cloud Storage bucket. Unlike image, video and text, the batch input file for tabular is only supported for CSV. For CSV file, you make:\n",
"Now make a batch input file which you store in your local Cloud Storage bucket. Unlike image, video and text, the batch input file for tabular is only supported for CSV. For CSV file, you make:\n",
"\n",
"- The first line is the heading with the feature (fields) heading names.\n",
"- Each remaining line is a separate prediction request with the corresponding feature values.\n",
@@ -1303,7 +1255,7 @@
" f.write(\"crim, zn, indus, chas, nox, rm, age, dis, rad, tax, ptratio, b, lstat\\n\")\n",
" f.write(str(x_test[0].tolist()).replace(\"[\", \"\").replace(\"]\", \"\"))\n",
" f.write(\"\\n\")\n",
" f.write(str(x_test[1].tolist()))\n",
" f.write(str(x_test[1].tolist()).replace(\"[\", \"\").replace(\"]\", \"\"))\n",
" f.write(\"\\n\")\n",
"\n",
"gcs_input_uri = BUCKET_URI + \"/test.csv\"\n",
@@ -1319,15 +1271,15 @@
"source": [
"### Make the batch explanation request\n",
"\n",
"Now that your Model resource is trained, you can make a batch prediction by invoking the batch_predict() method, with the following parameters:\n",
"Now that your model resource is trained, you can make a batch prediction by invoking the `batch_predict()` method, with the following parameters:\n",
"\n",
"- `job_display_name`: The human readable name for the batch prediction job.\n",
"- `gcs_source`: A list of one or more batch request input files.\n",
"- `gcs_destination_prefix`: The Cloud Storage location for storing the batch prediction resuls.\n",
"- `gcs_destination_prefix`: The Cloud Storage location for storing the batch prediction results.\n",
"- `instances_format`: The format for the input instances, either 'csv' or 'jsonl'. Defaults to 'jsonl'.\n",
"- `predictions_format`: The format for the output predictions, either 'csv' or 'jsonl'. Defaults to 'jsonl'.\n",
"- `generate_explanations`: Set to `True` to generate explanations.\n",
"- `sync`: If set to True, the call will block while waiting for the asynchronous batch job to complete."
"- `sync`: If set to `True`, the call blocks while waiting for the asynchronous batch job to complete."
]
},
{
@@ -1363,9 +1315,9 @@
"id": "batch_request_wait:mbsdk,testing"
},
"source": [
"### Wait for completion of batch prediction job\n",
"### Wait for the completion of batch prediction job\n",
"\n",
"Next, wait for the batch job to complete. Alternatively, one can set the parameter `sync` to `True` in the `batch_predict()` method to block until the batch prediction job is completed."
"Next, wait for the batch job to complete. Alternatively, you can set the `sync` parameter to `True` in the `batch_predict()` method to wait until the batch prediction job is completed."
]
},
{
@@ -1389,10 +1341,7 @@
"\n",
"Next, get the explanation results from the completed batch prediction job.\n",
"\n",
"The results are written to the Cloud Storage output bucket you specified in the batch prediction request. You call the method iter_outputs() to get a list of each Cloud Storage file generated with the results. Each file contains one or more explanation requests in a CSV format:\n",
"\n",
"- CSV header + predicted_label\n",
"- CSV row + explanation, per prediction request"
"The results are written to the Cloud Storage output bucket you specified in the batch prediction request. You call the `iter_outputs()` method to get a list of each Cloud Storage file generated with the results."
]
},
{
@@ -1440,17 +1389,18 @@
},
"outputs": [],
"source": [
"delete_bucket = False\n",
"\n",
"# Delete the model\n",
"model.delete()\n",
"try:\n",
" batch_predict_job.delete()\n",
"except Exception as e:\n",
" print(e)\n",
"\n",
"if delete_bucket or os.getenv(\"IS_TESTING\"):\n",
"# Delete the batch prediction job\n",
"batch_predict_job.delete()\n",
"\n",
"# Delete the Cloud Storage bucket\n",
"delete_bucket = False # Set True for deletion\n",
"if delete_bucket:\n",
" ! gsutil rm -r $BUCKET_URI\n",
"\n",
"# Remove the locally generated files\n",
"! rm -rf batch.csv custom.tar.gz custom"
]
}