<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Using Vertex Vizier to Optimize Multiple Objectives
Overview
In this lab, you will use Vertex Vizier to perform multi-objective optimization. Multi-objective optimization is concerned with mathematical optimization problems involving more than one objective function to be optimized simultaneously
Objective
The goal is to minimize the objective metric
Step1:  Import libraries and define constants
Step2:  Tutorial
This section defines some parameters and util methods to call Vertex Vizier APIs. Please fill in the following information to get started.
Step3:  Create the study configuration
The following is a sample study configuration, built as a hierarchical python dictionary. It is already filled out. Run the cell to configure the study.
Step4:  Create the study
Next, create the study, which you will subsequently run to optimize the two objectives.
Step7:  Metric evaluation functions
Next, define some functions to evaluate the two objective metrics.
Step8:  Set configuration parameters for running trials
client_id
Step9:  Run Vertex Vizier trials
Run the trials.
Step10:  List the optimal solutions
list_optimal_trials returns the pareto-optimal Trials for multi-objective Study or the optimal Trials for single-objective Study. In the case, we define mutliple-objective in previeous steps, pareto-optimal trials will be returned.
Step11:  Cleaning up
To clean up all Google Cloud resources used in this project, you can delete the Google Cloud
project you used for the tutorial. You can also manually delete resources that you created by running the following code.
<ASSISTANT_TASK:>
Python Code:
# Setup your dependencies
import os
# The Google Cloud Notebook product has specific requirements
IS_GOOGLE_CLOUD_NOTEBOOK = os.path.exists("/opt/deeplearning/metadata/env_version")
# Google Cloud Notebook requires dependencies to be installed with '--user'
USER_FLAG = ""
if IS_GOOGLE_CLOUD_NOTEBOOK:
    USER_FLAG = "--user"
# Upgrade the specified package to the newest available version
! pip install {USER_FLAG} --upgrade google-cloud-aiplatform
import os
if not os.getenv("IS_TESTING"):
    # Restart the kernel after pip installs
    import IPython
    app = IPython.Application.instance()
    app.kernel.do_shutdown(True)
Explanation: Using Vertex Vizier to Optimize Multiple Objectives
Overview
In this lab, you will use Vertex Vizier to perform multi-objective optimization. Multi-objective optimization is concerned with mathematical optimization problems involving more than one objective function to be optimized simultaneously
Objective
The goal is to minimize the objective metric:
   y1 = r*sin(theta)
and simultaneously maximize the objective metric:
   y2 = r*cos(theta)
that you will evaluate over the parameter space:
r in [0,1],
theta in [0, pi/2]
Introduction
In this notebook, you will use Vertex Vizier multi-objective optimization. Multi-objective optimization is concerned with mathematical optimization problems involving more than one objective function to be optimized simultaneously.
Each learning objective will correspond to a #TODO in this student lab notebook -- try to complete this notebook first and then review the solution notebook.  
Make sure to enable the Vertex AI API
Install Vertex AI library
Download and install Vertex AI library.
End of explanation
# Import necessary libraries
import datetime
import json
from google.cloud import aiplatform_v1beta1
Explanation: Import libraries and define constants
End of explanation
# Fill in your project ID and region
REGION = "us-central1"  # @param {type:"string"}
PROJECT_ID = "qwiklabs-gcp-00-866bdf7714fe"  # @param {type:"string"}
# These will be automatically filled in.
STUDY_DISPLAY_NAME = "{}_study_{}".format(
    PROJECT_ID.replace("-", ""), datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
)  # @param {type: 'string'}
ENDPOINT = REGION + "-aiplatform.googleapis.com"
PARENT = "projects/{}/locations/{}".format(PROJECT_ID, REGION)
print("ENDPOINT: {}".format(ENDPOINT))
print("REGION: {}".format(REGION))
print("PARENT: {}".format(PARENT))
# If you don't know your project ID, you might be able to get your project ID
# using gcloud command by executing the second cell below.
if PROJECT_ID == "" or PROJECT_ID is None or PROJECT_ID == "qwiklabs-gcp-00-866bdf7714fe":
    # 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)
! gcloud config set project $PROJECT_ID
Explanation: Tutorial
This section defines some parameters and util methods to call Vertex Vizier APIs. Please fill in the following information to get started.
End of explanation
# Parameter Configuration
param_r = {"parameter_id": "r", "double_value_spec": {"min_value": 0, "max_value": 1}}
param_theta = {
    "parameter_id": "theta",
    "double_value_spec": {"min_value": 0, "max_value": 1.57},
}
# TODO
# Objective Metrics
metric_y1 = {"metric_id": "y1", "goal": "MINIMIZE"}
# TODO
# Objective Metrics
metric_y2 = {"metric_id": "y2", "goal": "MAXIMIZE"}
# Put it all together in a study configuration
study = {
    "display_name": STUDY_DISPLAY_NAME,
    "study_spec": {
        "algorithm": "RANDOM_SEARCH",
        "parameters": [
            param_r,
            param_theta,
        ],
        "metrics": [metric_y1, metric_y2],
    },
}
print(json.dumps(study, indent=2, sort_keys=True))
Explanation: Create the study configuration
The following is a sample study configuration, built as a hierarchical python dictionary. It is already filled out. Run the cell to configure the study.
End of explanation
# TODO
# Create the study using study configuration and send request through VizierServiceClient
vizier_client = aiplatform_v1beta1.VizierServiceClient(
    client_options=dict(api_endpoint=ENDPOINT)
)
study = vizier_client.create_study(parent=PARENT, study=study)
STUDY_ID = study.name
print("STUDY_ID: {}".format(STUDY_ID))
Explanation: Create the study
Next, create the study, which you will subsequently run to optimize the two objectives.
End of explanation
import math
# r * sin(theta)
def Metric1Evaluation(r, theta):
    Evaluate the first metric on the trial.
    return r * math.sin(theta)
# r * cos(theta)
def Metric2Evaluation(r, theta):
    Evaluate the second metric on the trial.
    return r * math.cos(theta)
def CreateMetrics(trial_id, r, theta):
    print(("=========== Start Trial: [{}] =============").format(trial_id))
    # TODO
    # Evaluate both objective metrics for this trial
    y1 = Metric1Evaluation(r, theta)
    y2 = Metric2Evaluation(r, theta)
    print(
        "[r = {}, theta = {}] => y1 = r*sin(theta) = {}, y2 = r*cos(theta) = {}".format(
            r, theta, y1, y2
        )
    )
    metric1 = {"metric_id": "y1", "value": y1}
    metric2 = {"metric_id": "y2", "value": y2}
    # Return the results for this trial
    return [metric1, metric2]
Explanation: Metric evaluation functions
Next, define some functions to evaluate the two objective metrics.
End of explanation
client_id = "client1"  # @param {type: 'string'}
suggestion_count_per_request = 5  # @param {type: 'integer'}
max_trial_id_to_stop = 4  # @param {type: 'integer'}
print("client_id: {}".format(client_id))
print("suggestion_count_per_request: {}".format(suggestion_count_per_request))
print("max_trial_id_to_stop: {}".format(max_trial_id_to_stop))
Explanation: Set configuration parameters for running trials
client_id: The identifier of the client that is requesting the suggestion. If multiple SuggestTrialsRequests have the same client_id, the service will return the identical suggested trial if the trial is PENDING, and provide a new trial if the last suggested trial was completed.
suggestion_count_per_request: The number of suggestions (trials) requested in a single request.
max_trial_id_to_stop: The number of trials to explore before stopping. It is set to 4 to shorten the time to run the code, so don't expect convergence. For convergence, it would likely need to be about 20 (a good rule of thumb is to multiply the total dimensionality by 10).
End of explanation
trial_id = 0
while int(trial_id) < max_trial_id_to_stop:
    suggest_response = vizier_client.suggest_trials(
        {
            "parent": STUDY_ID,
            "suggestion_count": suggestion_count_per_request,
            "client_id": client_id,
        }
    )
    for suggested_trial in suggest_response.result().trials:
        trial_id = suggested_trial.name.split("/")[-1]
        trial = vizier_client.get_trial({"name": suggested_trial.name})
        if trial.state in ["COMPLETED", "INFEASIBLE"]:
            continue
        for param in trial.parameters:
            if param.parameter_id == "r":
                r = param.value
            elif param.parameter_id == "theta":
                theta = param.value
        print("Trial : r is {}, theta is {}.".format(r, theta))
        # TODO
        # Store your measurement and send the request
        vizier_client.add_trial_measurement(
            {
                "trial_name": suggested_trial.name,
                "measurement": {
                    # TODO
                    "metrics": CreateMetrics(suggested_trial.name, r, theta)
                },
            }
        )
        response = vizier_client.complete_trial(
            {"name": suggested_trial.name, "trial_infeasible": False}
        )
Explanation: Run Vertex Vizier trials
Run the trials.
End of explanation
# TODO
# List all the pareto-optimal trails
optimal_trials = vizier_client.list_optimal_trials({"parent": STUDY_ID})
print("optimal_trials: {}".format(optimal_trials))
Explanation: List the optimal solutions
list_optimal_trials returns the pareto-optimal Trials for multi-objective Study or the optimal Trials for single-objective Study. In the case, we define mutliple-objective in previeous steps, pareto-optimal trials will be returned.
End of explanation
vizier_client.delete_study({"name": STUDY_ID})
Explanation: Cleaning up
To clean up all Google Cloud resources used in this project, you can delete the Google Cloud
project you used for the tutorial. You can also manually delete resources that you created by running the following code.
End of explanation
<END_TASK>