09_deploying/09b_rest.ipynb (606 lines of code) (raw):
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 72
},
"id": "hiQ6zAoYhyaA",
"outputId": "0acee878-1207-42c3-9bee-a594acd44365"
},
"outputs": [
{
"data": {
"text/markdown": [
"\n",
"<table class=\"tfo-notebook-buttons\" align=\"left\">\n",
" <td>\n",
" <a target=\"_blank\" href=\"https://console.cloud.google.com/ai-platform/notebooks/deploy-notebook?name=Predictions using a REST endpoint&url=https%3A%2F%2Fgithub.com%2FGoogleCloudPlatform%2Fpractical-ml-vision-book%2Fblob%2Fmaster%2F09_deploying%2F09b_rest.ipynb&download_url=https%3A%2F%2Fgithub.com%2FGoogleCloudPlatform%2Fpractical-ml-vision-book%2Fraw%2Fmaster%2F09_deploying%2F09b_rest.ipynb\">\n",
" <img src=\"https://raw.githubusercontent.com/GoogleCloudPlatform/practical-ml-vision-book/master/logo-cloud.png\"/> Run in AI Platform Notebook</a>\n",
" </td>\n",
" </td>\n",
" <td>\n",
" <a target=\"_blank\" href=\"https://colab.research.google.com/github/GoogleCloudPlatform/practical-ml-vision-book/blob/master/09_deploying/09b_rest.ipynb\">\n",
" <img src=\"https://www.tensorflow.org/images/colab_logo_32px.png\" />Run in Google Colab</a>\n",
" </td>\n",
" <td>\n",
" <a target=\"_blank\" href=\"https://github.com/GoogleCloudPlatform/practical-ml-vision-book/blob/master/09_deploying/09b_rest.ipynb\">\n",
" <img src=\"https://www.tensorflow.org/images/GitHub-Mark-32px.png\" />View source on GitHub</a>\n",
" </td>\n",
" <td>\n",
" <a href=\"https://raw.githubusercontent.com/GoogleCloudPlatform/practical-ml-vision-book/master/09_deploying/09b_rest.ipynb\">\n",
" <img src=\"https://www.tensorflow.org/images/download_logo_32px.png\" />Download notebook</a>\n",
" </td>\n",
"</table>\n"
],
"text/plain": [
"<IPython.core.display.Markdown object>"
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from IPython.display import Markdown as md\n",
"\n",
"### change to reflect your notebook\n",
"_nb_loc = \"09_deploying/09b_rest.ipynb\"\n",
"_nb_title = \"Predictions using a REST endpoint\"\n",
"\n",
"### no need to change any of this\n",
"_nb_safeloc = _nb_loc.replace(\"/\", \"%2F\")\n",
"md(\"\"\"\n",
"<table class=\"tfo-notebook-buttons\" align=\"left\">\n",
" <td>\n",
" <a target=\"_blank\" href=\"https://console.cloud.google.com/ai-platform/notebooks/deploy-notebook?name={1}&url=https%3A%2F%2Fgithub.com%2FGoogleCloudPlatform%2Fpractical-ml-vision-book%2Fblob%2Fmaster%2F{2}&download_url=https%3A%2F%2Fgithub.com%2FGoogleCloudPlatform%2Fpractical-ml-vision-book%2Fraw%2Fmaster%2F{2}\">\n",
" <img src=\"https://raw.githubusercontent.com/GoogleCloudPlatform/practical-ml-vision-book/master/logo-cloud.png\"/> Run in AI Platform Notebook</a>\n",
" </td>\n",
" </td>\n",
" <td>\n",
" <a target=\"_blank\" href=\"https://colab.research.google.com/github/GoogleCloudPlatform/practical-ml-vision-book/blob/master/{0}\">\n",
" <img src=\"https://www.tensorflow.org/images/colab_logo_32px.png\" />Run in Google Colab</a>\n",
" </td>\n",
" <td>\n",
" <a target=\"_blank\" href=\"https://github.com/GoogleCloudPlatform/practical-ml-vision-book/blob/master/{0}\">\n",
" <img src=\"https://www.tensorflow.org/images/GitHub-Mark-32px.png\" />View source on GitHub</a>\n",
" </td>\n",
" <td>\n",
" <a href=\"https://raw.githubusercontent.com/GoogleCloudPlatform/practical-ml-vision-book/master/{0}\">\n",
" <img src=\"https://www.tensorflow.org/images/download_logo_32px.png\" />Download notebook</a>\n",
" </td>\n",
"</table>\n",
"\"\"\".format(_nb_loc, _nb_title, _nb_safeloc))"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "a8HQYsAtC0Fv"
},
"source": [
"# Predictions using a REST endpoint\n",
"\n",
"In this notebook, we start from an already trained and saved model (as in Chapter 7).\n",
"For convenience, we have put this model in a public bucket in gs://practical-ml-vision-book-data/flowers_5_trained\n",
"\n",
"We deploy this model to a REST endpoint, and then show how to invoke the model using POST operations."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## REST endpoint"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"#!/bin/bash\n",
"\n",
"REGION=\"us-central1\" # make sure you have GPU/TPU quota in this region\n",
"ENDPOINT_NAME=\"flowers_endpoint\"\n",
"MODEL_NAME=\"flowers\"\n",
"MODEL_LOCATION=\"gs://practical-ml-vision-book-data/flowers_5_trained\"\n",
"IMAGE_URI=\"us-docker.pkg.dev/vertex-ai/prediction/tf2-cpu.2-1:latest\"\n",
"\n",
"for i in \"$@\"\n",
"do\n",
"case $i in\n",
" -r=*|--region=*) REGION=\"${i#*=}\"; shift ;;\n",
" -e=*|--endpoint_name=*) ENDPOINT_NAME=\"${i#*=}\"; shift ;;\n",
" -m=*|--model_name=*) MODEL_NAME=\"${i#*=}\"; shift ;;\n",
" -l=*|--model_location=*) MODEL_LOCATION=\"${i#*=}\"; shift ;;\n",
" -i=*|--image_uri=*) IMAGE_URI=\"${i#*=}\"; shift ;;\n",
" *) echo \"Unknown parameter passed: $1\"; exit 1 ;;\n",
"esac\n",
"done\n",
"\n",
"echo \"Deploying model $MODEL_NAME\"\n",
"\n",
"if [[ $(gcloud ai endpoints list --region=$REGION --format=\"value(display_name)\" | grep $ENDPOINT_NAME) ]]; then\n",
" echo \"The endpoint named $ENDPOINT_NAME already exists.\"\n",
"else\n",
" # Create endpoint.\n",
" echo \"Creating $ENDPOINT_NAME endpoint now.\"\n",
" gcloud ai endpoints create \\\n",
" --region=$REGION \\\n",
" --display-name=$ENDPOINT_NAME\n",
"fi\n",
"\n",
"ENDPOINT_ID=$(gcloud ai endpoints list --region=$REGION --format=\"value(name)\" --filter=\"displayName=$ENDPOINT_NAME\")\n",
"echo \"The endpoint_id is $ENDPOINT_ID\"\n",
"\n",
"if [[ $(gcloud ai models list --region=$REGION --format=\"value(display_name)\" | grep $MODEL_NAME) ]]; then\n",
" echo \"The model named $MODEL_NAME already exists.\"\n",
"else\n",
" # Upload model.\n",
" echo \"Uploading $MODEL_NAME model now.\"\n",
" gcloud ai models upload \\\n",
" --region=$REGION \\\n",
" --display-name=$MODEL_NAME \\\n",
" --container-image-uri=$IMAGE_URI \\\n",
" --artifact-uri=$MODEL_LOCATION\n",
"fi\n",
"\n",
"MODEL_ID=$(gcloud ai models list --region=$REGION --format=\"value(name)\" --filter=\"displayName=$MODEL_NAME\")\n",
"echo \"The model_id is $MODEL_ID\"\n",
"\n",
"echo \"Deploying model now\"\n",
"gcloud ai endpoints deploy-model $ENDPOINT_ID\\\n",
" --region=$REGION \\\n",
" --model=$MODEL_ID \\\n",
" --display-name=$MODEL_NAME \\\n",
" --traffic-split=0=100\n"
]
}
],
"source": [
"!cat ./vertex_deploy.sh"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Deploying model flowers\n",
"Using endpoint [https://us-central1-aiplatform.googleapis.com/]\n",
"The endpoint named flowers_endpoint already exists.\n",
"Using endpoint [https://us-central1-aiplatform.googleapis.com/]\n",
"The endpoint_id is 4327589805996113920\n",
"Using endpoint [https://us-central1-aiplatform.googleapis.com/]\n",
"Uploading flowers model now.\n",
"Using endpoint [https://us-central1-aiplatform.googleapis.com/]\n",
"Waiting for operation [8618855115064868864]...done. \n",
"Using endpoint [https://us-central1-aiplatform.googleapis.com/]\n",
"The model_id is 4626538221495386112\n",
"Deploying model now\n",
"Using endpoint [https://us-central1-aiplatform.googleapis.com/]\n",
"Waiting for operation [3921600703717441536]...done. \n",
"Deployed a model to the endpoint 4327589805996113920. Id of the deployed model: 1963683786742824960.\n"
]
}
],
"source": [
"!./vertex_deploy.sh"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## IMPORTANT: CHANGE THIS CELL"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Note the endpoint ID and deployed model ID above. Set it in the cell below."
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [],
"source": [
"# CHANGE THESE TO REFLECT WHERE YOU DEPLOYED THE MODEL\n",
"import os\n",
"os.environ['ENDPOINT_ID'] = '4327589805996113920' # CHANGE\n",
"os.environ['MODEL_ID'] = '1963683786742824960' # CHANGE\n",
"os.environ['PROJECT'] = 'ai-analytics-solutions' # CHANGE\n",
"os.environ['BUCKET'] = 'ai-analytics-solutions-mlvisionbook' # CHANGE\n",
"os.environ['REGION'] = 'us-central1' # CHANGE"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## JSON request"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Writing request.json\n"
]
}
],
"source": [
"%%writefile request.json\n",
"{\n",
" \"instances\": [\n",
" {\n",
" \"filenames\": \"gs://practical-ml-vision-book-data/flowers_5_jpeg/flower_photos/dandelion/9818247_e2eac18894.jpg\"\n",
" },\n",
" {\n",
" \"filenames\": \"gs://practical-ml-vision-book-data/flowers_5_jpeg/flower_photos/dandelion/9853885425_4a82356f1d_m.jpg\"\n",
" },\n",
" {\n",
" \"filenames\": \"gs://practical-ml-vision-book-data/flowers_5_jpeg/flower_photos/daisy/9299302012_958c70564c_n.jpg\"\n",
" },\n",
" {\n",
" \"filenames\": \"gs://practical-ml-vision-book-data/flowers_5_jpeg/flower_photos/tulips/8733586143_3139db6e9e_n.jpg\"\n",
" },\n",
" {\n",
" \"filenames\": \"gs://practical-ml-vision-book-data/flowers_5_jpeg/flower_photos/tulips/8713397358_0505cc0176_n.jpg\"\n",
" }\n",
" ]\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{\n",
" \"deployedModelId\": \"1963683786742824960\",\n",
" \"model\": \"projects/379218021631/locations/us-central1/models/4626538221495386112\",\n",
" \"modelDisplayName\": \"flowers\",\n",
" \"predictions\": [\n",
" {\n",
" \"flower_type_int\": 1,\n",
" \"flower_type_str\": \"dandelion\",\n",
" \"probability\": 0.619152546\n",
" },\n",
" {\n",
" \"flower_type_int\": 1,\n",
" \"flower_type_str\": \"dandelion\",\n",
" \"probability\": 0.999984384\n",
" },\n",
" {\n",
" \"flower_type_int\": 0,\n",
" \"flower_type_str\": \"daisy\",\n",
" \"probability\": 0.995082855\n",
" },\n",
" {\n",
" \"flower_type_int\": 4,\n",
" \"flower_type_str\": \"tulips\",\n",
" \"probability\": 0.975185812\n",
" },\n",
" {\n",
" \"flower_type_int\": 4,\n",
" \"flower_type_str\": \"tulips\",\n",
" \"probability\": 0.954917\n",
" }\n",
" ]\n",
"}\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"Using endpoint [https://us-central1-prediction-aiplatform.googleapis.com/]\n"
]
}
],
"source": [
"%%bash\n",
"gcloud ai endpoints predict ${ENDPOINT_ID} \\\n",
"--region=${REGION} \\\n",
"--json-request=request.json \\\n",
"--format=json"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Sending over HTTP Post"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"b'{\\n \"predictions\": [\\n {\\n \"flower_type_int\": 1,\\n \"probability\": 0.619152546,\\n \"flower_type_str\": \"dandelion\"\\n },\\n {\\n \"flower_type_str\": \"dandelion\",\\n \"probability\": 0.999984384,\\n \"flower_type_int\": 1\\n },\\n {\\n \"probability\": 0.995082855,\\n \"flower_type_str\": \"daisy\",\\n \"flower_type_int\": 0\\n },\\n {\\n \"probability\": 0.975185812,\\n \"flower_type_str\": \"tulips\",\\n \"flower_type_int\": 4\\n },\\n {\\n \"flower_type_int\": 4,\\n \"flower_type_str\": \"tulips\",\\n \"probability\": 0.954917\\n }\\n ],\\n \"deployedModelId\": \"1963683786742824960\",\\n \"model\": \"projects/379218021631/locations/us-central1/models/4626538221495386112\",\\n \"modelDisplayName\": \"flowers\"\\n}\\n'\n"
]
}
],
"source": [
"# Invoke from Python.\n",
"import json\n",
"from oauth2client.client import GoogleCredentials\n",
"import requests\n",
"\n",
"PROJECT = os.environ['PROJECT']\n",
"REGION = os.environ['REGION']\n",
"ENDPOINT_ID = os.environ['ENDPOINT_ID']\n",
"\n",
"token = GoogleCredentials.get_application_default().get_access_token().access_token\n",
"api = \"https://{}-aiplatform.googleapis.com/v1/projects/{}/locations/{}/endpoints/{}:predict\".format(\n",
" REGION, PROJECT, REGION, ENDPOINT_ID)\n",
"headers = {\"Authorization\": \"Bearer \" + token }\n",
"data = {\n",
" \"instances\": [\n",
" {\n",
" \"filenames\": \"gs://practical-ml-vision-book-data/flowers_5_jpeg/flower_photos/dandelion/9818247_e2eac18894.jpg\"\n",
" },\n",
" {\n",
" \"filenames\": \"gs://practical-ml-vision-book-data/flowers_5_jpeg/flower_photos/dandelion/9853885425_4a82356f1d_m.jpg\"\n",
" },\n",
" {\n",
" \"filenames\": \"gs://practical-ml-vision-book-data/flowers_5_jpeg/flower_photos/daisy/9299302012_958c70564c_n.jpg\"\n",
" },\n",
" {\n",
" \"filenames\": \"gs://practical-ml-vision-book-data/flowers_5_jpeg/flower_photos/tulips/8733586143_3139db6e9e_n.jpg\"\n",
" },\n",
" {\n",
" \"filenames\": \"gs://practical-ml-vision-book-data/flowers_5_jpeg/flower_photos/tulips/8713397358_0505cc0176_n.jpg\"\n",
" }\n",
" ]\n",
"}\n",
"response = requests.post(api, json=data, headers=headers)\n",
"print(response.content)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## [Optional] CAIP Batch prediction"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"%%writefile batchinputs.jsonl\n",
"{\"filenames\": \"gs://practical-ml-vision-book-data/flowers_5_jpeg/flower_photos/dandelion/9818247_e2eac18894.jpg\"}\n",
"{\"filenames\": \"gs://practical-ml-vision-book-data/flowers_5_jpeg/flower_photos/dandelion/9853885425_4a82356f1d_m.jpg\"}\n",
"{\"filenames\": \"gs://practical-ml-vision-book-data/flowers_5_jpeg/flower_photos/daisy/9299302012_958c70564c_n.jpg\"}\n",
"{\"filenames\": \"gs://practical-ml-vision-book-data/flowers_5_jpeg/flower_photos/tulips/8733586143_3139db6e9e_n.jpg\"}\n",
"{\"filenames\": \"gs://practical-ml-vision-book-data/flowers_5_jpeg/flower_photos/tulips/8713397358_0505cc0176_n.jpg\"}"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"%%bash\n",
"gsutil cp batchinputs.jsonl gs://BUCKET"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Invoke from Python.\n",
"import json\n",
"from oauth2client.client import GoogleCredentials\n",
"import requests\n",
"\n",
"PROJECT = os.environ['PROJECT']\n",
"REGION = os.environ['REGION']\n",
"ENDPOINT_ID = os.environ['ENDPOINT_ID']\n",
"MODEL_ID = os.environ['MODEL_ID']\n",
"BUCKET = os.environ['BUCKET'] # used for staging\n",
"\n",
"BATCH_JOB_NAME = \"batch_pred_job\"\n",
"INPUT_FORMAT = \"jsonl\"\n",
"INPUT_URI = \"gs://{}/batchinputs.jsonl\".format(BUCKET)\n",
"OUTPUT_DIRECTORY = \"gs://{}/batch_predictions\".format(BUCKET)\n",
"MACHINE_TYPE = \"n1-standard-2\"\n",
"STARTING_REPLICA_COUNT = 1\n",
"BATCH_SIZE = 64\n",
"\n",
"token = GoogleCredentials.get_application_default().get_access_token().access_token\n",
"api = \"https://{}-aiplatform.googleapis.com/v1/projects/{}/locations/{}/batchPredictionJobs\".format(\n",
" REGION, PROJECT, REGION\n",
")\n",
"headers = {\"Authorization\": \"Bearer \" + token}\n",
"data = {\n",
" \"displayName\": BATCH_JOB_NAME,\n",
" \"model\": \"projects/{}/locations/{}/models/{}\".format(\n",
" PROJECT, REGION, MODEL_ID\n",
" ),\n",
" \"inputConfig\": {\n",
" \"instancesFormat\": INPUT_FORMAT,\n",
" \"gcsSource\": {\n",
" \"uris\": [INPUT_URI],\n",
" },\n",
" },\n",
" \"outputConfig\": {\n",
" \"predictionsFormat\": \"jsonl\",\n",
" \"gcsDestination\": {\n",
" \"outputUriPrefix\": OUTPUT_DIRECTORY,\n",
" },\n",
" },\n",
" \"dedicatedResources\" : {\n",
" \"machineSpec\" : {\n",
" \"machineType\": MACHINE_TYPE\n",
" },\n",
" \"startingReplicaCount\": STARTING_REPLICA_COUNT\n",
" },\n",
" \"manualBatchTuningParameters\": {\n",
" \"batch_size\": BATCH_SIZE,\n",
" }\n",
"}\n",
"response = requests.post(api, json=data, headers=headers)\n",
"print(response.content)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## [Optional] Invoking online predictions from Apache Beam"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import apache_beam as beam\n",
"import json\n",
"from oauth2client.client import GoogleCredentials\n",
"import requests\n",
"\n",
"class ModelPredict:\n",
" def __init__(self, project, region, endpoint_id):\n",
" self._api = \"https://{}-aiplatform.googleapis.com/v1/projects/{}/locations/{}/endpoints/{}:predict\".format(\n",
" region, project, region, endpoint_id) \n",
" \n",
" def __call__(self, filenames): \n",
" token = GoogleCredentials.get_application_default().get_access_token().access_token\n",
" if isinstance(filenames, str):\n",
" # Only one element, put it into a batch of 1.\n",
" data = {\n",
" \"instances\": [\n",
" {\"filenames\": filenames}\n",
" ]\n",
" }\n",
" else:\n",
" data = {\n",
" \"instances\": []\n",
" }\n",
" for f in filenames:\n",
" data[\"instances\"].append({\n",
" \"filenames\" : f\n",
" })\n",
" # print(data)\n",
" headers = {\"Authorization\": \"Bearer \" + token }\n",
" response = requests.post(self._api, json=data, headers=headers)\n",
" response = json.loads(response.content.decode(\"utf-8\"))\n",
" # print(response)\n",
" if isinstance(filenames, str):\n",
" result = response[\"predictions\"][0]\n",
" result[\"filename\"] = filenames\n",
" yield result\n",
" else:\n",
" for (a,b) in zip(filenames, response[\"predictions\"]):\n",
" result = b\n",
" result[\"filename\"] = a\n",
" yield result\n",
"\n",
"\n",
"PROJECT = os.environ['PROJECT']\n",
"REGION = os.environ['REGION']\n",
"ENDPOINT_ID = os.environ['ENDPOINT_ID']\n",
"\n",
"with beam.Pipeline() as p: \n",
" (p \n",
" | \"input\" >> beam.Create([\n",
" \"gs://practical-ml-vision-book-data/flowers_5_jpeg/flower_photos/dandelion/9818247_e2eac18894.jpg\",\n",
" \"gs://practical-ml-vision-book-data/flowers_5_jpeg/flower_photos/dandelion/9853885425_4a82356f1d_m.jpg\",\n",
" \"gs://practical-ml-vision-book-data/flowers_5_jpeg/flower_photos/daisy/9299302012_958c70564c_n.jpg\",\n",
" \"gs://practical-ml-vision-book-data/flowers_5_jpeg/flower_photos/tulips/8733586143_3139db6e9e_n.jpg\",\n",
" \"gs://practical-ml-vision-book-data/flowers_5_jpeg/flower_photos/tulips/8713397358_0505cc0176_n.jpg\"\n",
" ]) \n",
" | \"batch\" >> beam.BatchElements(min_batch_size=2, max_batch_size=3)\n",
" | \"addpred\" >> beam.FlatMap(ModelPredict(PROJECT, REGION, ENDPOINT_ID))\n",
" | \"write\" >> beam.Map(print)\n",
" )"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "Duu8mX3iXANE"
},
"source": [
"## License\n",
"Copyright 2020 Google Inc. 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."
]
}
],
"metadata": {
"accelerator": "GPU",
"colab": {
"collapsed_sections": [
"5UOm2etrwYCs"
],
"name": "03a_transfer_learning.ipynb",
"provenance": [],
"toc_visible": true
},
"environment": {
"kernel": "python3",
"name": "tf2-gpu.2-6.m87",
"type": "gcloud",
"uri": "gcr.io/deeplearning-platform-release/tf2-gpu.2-6:m87"
},
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.12"
}
},
"nbformat": 4,
"nbformat_minor": 4
}