mirror of
https://github.com/GoogleCloudPlatform/vertex-ai-samples.git
synced 2026-09-26 14:42:04 +00:00
44 KiB
44 KiB
In [ ]:
# Copyright 2021 Google LLC
#
# 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
#
# https://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.In [ ]:
! pip3 install -U google-cloud-aiplatform --userIn [ ]:
! pip3 install google-cloud-storageIn [ ]:
import os
if not os.getenv("AUTORUN"):
# Automatically restart kernel after installs
import IPython
app = IPython.Application.instance()
app.kernel.do_shutdown(True)In [ ]:
PROJECT_ID = "[your-project-id]" # @param {type:"string"}In [ ]:
if PROJECT_ID == "" or PROJECT_ID is None or PROJECT_ID == "[your-project-id]":
# Get your GCP project id from gcloud
shell_output = !gcloud config list --format 'value(core.project)' 2>/dev/null
PROJECT_ID = shell_output[0]
print("Project ID:", PROJECT_ID)In [ ]:
! gcloud config set project $PROJECT_IDIn [ ]:
REGION = "us-central1" # @param {type: "string"}In [ ]:
from datetime import datetime
TIMESTAMP = datetime.now().strftime("%Y%m%d%H%M%S")In [ ]:
import os
import sys
# If you are running this notebook in Colab, run this cell and follow the
# instructions to authenticate your Google Cloud account. This provides access
# to your Cloud Storage bucket and lets you submit training jobs and prediction
# requests.
# If on Vertex, then don't execute this code
if not os.path.exists("/opt/deeplearning/metadata/env_version"):
if "google.colab" in sys.modules:
from google.colab import auth as google_auth
google_auth.authenticate_user()
# If you are running this tutorial in a notebook locally, replace the string
# below with the path to your service account key and run this cell to
# authenticate your Google Cloud account.
else:
%env GOOGLE_APPLICATION_CREDENTIALS your_path_to_credentials.json
# Log in to your account on Google Cloud
! gcloud auth loginIn [ ]:
BUCKET_NAME = "[your-bucket-name]" # @param {type:"string"}In [ ]:
if BUCKET_NAME == "" or BUCKET_NAME is None or BUCKET_NAME == "[your-bucket-name]":
BUCKET_NAME = PROJECT_ID + "aip-" + TIMESTAMPIn [ ]:
! gsutil mb -l $REGION gs://$BUCKET_NAMEIn [ ]:
! gsutil ls -al gs://$BUCKET_NAMEIn [ ]:
import os
import sys
import time
from google.cloud.aiplatform import gapic as aip
from google.protobuf import json_format
from google.protobuf.json_format import MessageToJson, ParseDict
from google.protobuf.struct_pb2 import Struct, ValueIn [ ]:
# API Endpoint
API_ENDPOINT = "{}-aiplatform.googleapis.com".format(REGION)
# Vertex AI location root path for your dataset, model and endpoint resources
PARENT = "projects/" + PROJECT_ID + "/locations/" + REGIONIn [ ]:
# client options same for all services
client_options = {"api_endpoint": API_ENDPOINT}
def create_model_client():
client = aip.ModelServiceClient(client_options=client_options)
return client
def create_endpoint_client():
client = aip.EndpointServiceClient(client_options=client_options)
return client
def create_prediction_client():
client = aip.PredictionServiceClient(client_options=client_options)
return client
def create_job_client():
client = aip.JobServiceClient(client_options=client_options)
return client
clients = {}
clients["model"] = create_model_client()
clients["endpoint"] = create_endpoint_client()
clients["prediction"] = create_prediction_client()
clients["job"] = create_job_client()
for client in clients.items():
print(client)In [ ]:
# Make folder for python training script
! rm -rf custom
! mkdir custom
# Add package information
! touch custom/README.md
setup_cfg = "[egg_info]\n\
tag_build =\n\
tag_date = 0"
! echo "$setup_cfg" > custom/setup.cfg
setup_py = "import setuptools\n\
# Requires TensorFlow Datasets\n\
setuptools.setup(\n\
install_requires=[\n\
'tensorflow_datasets==1.3.0',\n\
],\n\
packages=setuptools.find_packages())"
! echo "$setup_py" > custom/setup.py
pkg_info = "Metadata-Version: 1.0\n\
Name: Hyperparameter Tuning - Boston Housing\n\
Version: 0.0.0\n\
Summary: Demonstration hyperparameter tuning script\n\
Home-page: www.google.com\n\
Author: Google\n\
Author-email: aferlitsch@gmail.com\n\
License: Public\n\
Description: Demo\n\
Platform: Vertex AI"
! echo "$pkg_info" > custom/PKG-INFO
# Make the training subfolder
! mkdir custom/trainer
! touch custom/trainer/__init__.pyIn [ ]:
%%writefile custom/trainer/task.py
# hyperparameter tuningfor Boston Housing
import tensorflow_datasets as tfds
import tensorflow as tf
from tensorflow.python.client import device_lib
from hypertune import HyperTune
import numpy as np
import argparse
import os
import sys
tfds.disable_progress_bar()
parser = argparse.ArgumentParser()
parser.add_argument('--model-dir', dest='model_dir',
default='/tmp/saved_model', type=str, help='Model dir.')
parser.add_argument('--lr', dest='lr',
default=0.001, type=float,
help='Learning rate.')
parser.add_argument('--units', dest='units',
default=64, type=int,
help='Number of units.')
parser.add_argument('--epochs', dest='epochs',
default=20, type=int,
help='Number of epochs.')
parser.add_argument('--param-file', dest='param_file',
default='/tmp/param.txt', type=str,
help='Output file for parameters')
args = parser.parse_args()
print('Python Version = {}'.format(sys.version))
print('TensorFlow Version = {}'.format(tf.__version__))
print('TF_CONFIG = {}'.format(os.environ.get('TF_CONFIG', 'Not found')))
def make_dataset():
# Scaling Boston Housing data features
def scale(feature):
max = np.max(feature)
feature = (feature / max).astype(np.float)
return feature, max
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.boston_housing.load_data(
path="boston_housing.npz", test_split=0.2, seed=113
)
params = []
for _ in range(13):
x_train[_], max = scale(x_train[_])
x_test[_], _ = scale(x_test[_])
params.append(max)
# store the normalization (max) value for each feature
with tf.io.gfile.GFile(args.param_file, 'w') as f:
f.write(str(params))
return (x_train, y_train), (x_test, y_test)
# Build the Keras model
def build_and_compile_dnn_model():
model = tf.keras.Sequential([
tf.keras.layers.Dense(args.units, activation='relu', input_shape=(13,)),
tf.keras.layers.Dense(args.units, activation='relu'),
tf.keras.layers.Dense(1, activation='linear')
])
model.compile(
loss='mse',
optimizer=tf.keras.optimizers.RMSprop(learning_rate=args.lr))
return model
model = build_and_compile_dnn_model()
# Instantiate the HyperTune reporting object
hpt = HyperTune()
# Reporting callback
class HPTCallback(tf.keras.callbacks.Callback):
def on_epoch_end(self, epoch, logs=None):
global hpt
hpt.report_hyperparameter_tuning_metric(
hyperparameter_metric_tag='val_loss',
metric_value=logs['val_loss'],
global_step=epoch)
# Train the model
BATCH_SIZE = 16
(x_train, y_train), (x_test, y_test) = make_dataset()
model.fit(x_train, y_train, epochs=args.epochs, batch_size=BATCH_SIZE, validation_split=0.1, callbacks=[HPTCallback()])
model.save(args.model_dir)
In [ ]:
! rm -f custom.tar custom.tar.gz
! tar cvf custom.tar custom
! gzip custom.tar
! gsutil cp custom.tar.gz gs://$BUCKET_NAME/hpt_boston_housing.tar.gzIn [ ]:
JOB_NAME = "hyperparameter_tuning_" + TIMESTAMP
WORKER_POOL_SPEC = [
{
"replica_count": 1,
"machine_spec": {"machine_type": "n1-standard-4", "accelerator_count": 0},
"python_package_spec": {
"executor_image_uri": "gcr.io/cloud-aiplatform/training/tf-cpu.2-1:latest",
"package_uris": ["gs://" + BUCKET_NAME + "/hpt_boston_housing.tar.gz"],
"python_module": "trainer.task",
"args": ["--model-dir=" + "gs://{}/{}".format(BUCKET_NAME, JOB_NAME)],
},
}
]
STUDY_SPEC = {
"metrics": [
{"metric_id": "val_loss", "goal": aip.StudySpec.MetricSpec.GoalType.MINIMIZE}
],
"parameters": [
{
"parameter_id": "lr",
"discrete_value_spec": {"values": [0.001, 0.01, 0.1]},
"scale_type": aip.StudySpec.ParameterSpec.ScaleType.UNIT_LINEAR_SCALE,
},
{
"parameter_id": "units",
"integer_value_spec": {"min_value": 32, "max_value": 256},
"scale_type": aip.StudySpec.ParameterSpec.ScaleType.UNIT_LINEAR_SCALE,
},
],
"algorithm": aip.StudySpec.Algorithm.RANDOM_SEARCH,
}
hyperparameter_tuning_job = aip.HyperparameterTuningJob(
display_name=JOB_NAME,
trial_job_spec={"worker_pool_specs": WORKER_POOL_SPEC},
study_spec=STUDY_SPEC,
max_trial_count=6,
parallel_trial_count=1,
)
print(
MessageToJson(
aip.CreateHyperparameterTuningJobRequest(
parent=PARENT, hyperparameter_tuning_job=hyperparameter_tuning_job
).__dict__["_pb"]
)
)In [ ]:
request = clients["job"].create_hyperparameter_tuning_job(
parent=PARENT, hyperparameter_tuning_job=hyperparameter_tuning_job
)In [ ]:
print(MessageToJson(request.__dict__["_pb"]))In [ ]:
# The full unique ID for the hyperparameter tuningjob
hyperparameter_tuning_id = request.name
# The short numeric ID for the hyperparameter tuningjob
hyperparameter_tuning_short_id = hyperparameter_tuning_id.split("/")[-1]
print(hyperparameter_tuning_id)In [ ]:
request = clients["job"].get_hyperparameter_tuning_job(name=hyperparameter_tuning_id)In [ ]:
print(MessageToJson(request.__dict__["_pb"]))In [ ]:
while True:
response = clients["job"].get_hyperparameter_tuning_job(
name=hyperparameter_tuning_id
)
if response.state != aip.PipelineState.PIPELINE_STATE_SUCCEEDED:
print("Study trials have not completed:", response.state)
if response.state == aip.PipelineState.PIPELINE_STATE_FAILED:
break
else:
print("Study trials have completed:", response.end_time - response.start_time)
break
time.sleep(20)In [ ]:
best = (None, None, None, 0.0)
response = clients["job"].get_hyperparameter_tuning_job(name=hyperparameter_tuning_id)
for trial in response.trials:
print(MessageToJson(trial.__dict__["_pb"]))
# Keep track of the best outcome
try:
if float(trial.final_measurement.metrics[0].value) > best[3]:
best = (
trial.id,
float(trial.parameters[0].value),
float(trial.parameters[1].value),
float(trial.final_measurement.metrics[0].value),
)
except:
pass
print()
print("ID", best[0])
print("Decay", best[1])
print("Learning Rate", best[2])
print("Validation Accuracy", best[3])In [ ]:
delete_hpt_job = True
delete_bucket = True
# Delete the hyperparameter tuningusing the Vertex AI fully qualified identifier for the custome training
try:
if delete_hpt_job:
clients["job"].delete_hyperparameter_tuning_job(name=hyperparameter_tuning_id)
except Exception as e:
print(e)
if delete_bucket and "BUCKET_NAME" in globals():
! gsutil rm -r gs://$BUCKET_NAME