Camelback example

The camelback example is a two-dimension optimization problem that optimizes the six-hump camelback function.

This function has global minima.
f(x) = -1.0316 at x = (0.0898, -0.7126) and (-0.0898, 0.7126)

Command-line input to run camelback_example.py

usage: python camelback_example.py [-h] [--hostname BOA_SERVER]
                            [--protocol {http, https}] [--port PORT]
                            [--epochs EPOCHS] [--ca-cert-path CA_CERT_PATH]

optional arguments:
  -h, --help            show this help message and exit
  --hostname BOA_SERVER, -ho BOA_SERVER
                        Hostname or IP address of BOA server to connect to.
                        (default: localhost)
  --protocol {http, https}, -pr {http, https}
                        Protocol to use to connect to BOA server. (default:
                        http)
  --port PORT, -p PORT  Port to connect to on BOA server. (default: 80)
  --epochs EPOCHS, -e EPOCHS
                        Number of epochs to perform. (default: 40)
  --ca-cert-path CA_CERT_PATH, -c CA_CERT_PATH
                        Path to the CA certificate file to use for https
                        protocol. (default: None)

Sample Camelback example python file

A sample camelback example is shown below:
"""
Licensed Materials - Property of IBM
“Restricted Materials of IBM”

5765-R17

© Copyright IBM Corp. 2020  All Rights Reserved.
US Government Users Restricted Rights - Use, duplication or
disclosure restricted by GSA ADP Schedule Contract with IBM Corp
"""

import pandas as pd
import numpy as np
from sklearn.preprocessing import StandardScaler
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_squared_error
import os, sys
from common.boa_examples_utils import BoaExamplesUtils
from boaas_sdk import BOaaSClient
import signal

example_description="""
        This example demonstrates basic BOA usage for a simple optimization problem.

        The BOA SDK has been designed to be simple to use, but flexible in the range of
        configurations available for tailoring the optimization. This is achieved using
        the BOaaSClient object, which facilitates all communication with the BOA server.
        The optimization configuration is handled via a Python dictionary (or
        equivalently a JSON file).
PTF1-Fix Pack 1

        The camelback example is a two dimensional optimization problem that optimizes
        the six humped camelback function. This function has global minima
        f(x) = -1.0316 at x = (0.0898, -0.7126) and (-0.0898, 0.7126))
        """

"""
Perform parsing of common commandline arguments shared by all BOA examples.
"""
args = BoaExamplesUtils.parse_commandline_args(example_description,default_epochs=40)
hostname = BoaExamplesUtils.get_connection_url(args)
print("Connecting to host: {}".format(hostname))
boaas = BOaaSClient(host=hostname,ca_cert_path=args.ca_cert_path)

def camelback6(x):
    # Six-hump camelback function
    x1 = x[0]
    x2 = x[1]
    f = (4 - 2.1 * (x1 * x1) + (x1 * x1 * x1 * x1) / 3.0) * (x1 * x1) + x1 * x2 + (-4 + 4 * (x2 * x2)) * (x2 * x2)
    return f


experiment_config = {
    "name": "Reg camelback function",
    "domain": [
        {
            "name": "x1",
            "min": -2,
            "max": 2,
            "step": 0.01
        }, {
            "name": "x2",
            "min": -1,
            "max": 1,
            "step": 0.01
        }
    ],
    "model": {"gaussian_process": {
        "kernel_func": "Matern52",
        "scale_y": True,
        "scale_x": False,
        "noise_kernel": True,
        "use_scikit": True
    }},
    "optimization_type": "min",
    "initialization": {
        "type": "random",
        "random": {
            "no_samples": 3,
            "seed": None
        }
    },
    "sampling_function": {
        "type": "expected_improvement",
        "epsilon": 0.03,
        "optimize_acq": False,
        "outlier": False,
        "bounds": None
    }

}

user = {"_id": "boa_test@test.com", "password": "password"}
user_login = boaas.login(user)

if user_login == None:
    user = {"_id": "boa_test@test.com", "name": "BOA Test",
            "password": "password", "confirm_password": "password"}
    boaas.register(user)
    user_login = boaas.login(user)

print(user_login)
user_token = user_login["logged_in"]["token"]
print("user token")
print(user_token)
create_exp_user_object = {"_id": user["_id"], "token": user_token}
experiment_res = boaas.create_experiment(create_exp_user_object, experiment_config)
print(experiment_res)
experiment_id = experiment_res["experiment"]["_id"]


def signal_handler(signal, frame):
    """
    Function to handle Ctrl+C signal
    """

    print("Aborting...")
    boaas.abort(experiment_id, user_token)
    sys.exit()


# Catch ctrl+c signal to invoke its signal handler
signal.signal(signal.SIGINT, signal_handler)

boaas.run(experiment_id=experiment_id, user_token=user_token, func=camelback6, no_epochs=args.epochs, explain=False)
best_observation = boaas.best_observation(experiment_id, user_token)
print("best observation:")
print(best_observation)
boaas.stop_experiment(experiment_id=experiment_id, user_token=user_token)

Authenticate a registered user

The login call maps to the REST API call /users/login user_login = boaas.login(user). A sample of the authenticate a registered user object is displayed in the following example.
if user_login == None:
    user = {"_id": "boa_test@test.com", "name": "BOA Test",
            "password": "password", "confirm_password": "password"}
			
    # Register a new user. The Register call maps to REST API call /users/register
    boaas.register(user)
	
    user_login = boaas.login(user)

print(user_login)
user_token = user_login["logged_in"]["token"]
print("user token")
print(user_token)
create_exp_user_object = {"_id": user["_id"], "token": user_token}

Authenticate a registered user

The login call maps to the REST API call /users/login user_login = boaas.login(user). A sample of the authenticate a registered user object is displayed in the following example.
if user_login == None:     user = {"_id": "boa_test@test.com", "name": "BOA Test",
            "password": "password", "confirm_password": "password"}
   
    # Register a new user. The Register call maps to REST API call /users/register
    boaas.register(user)
 
    user_login = boaas.login(user)
print(user_login)
user_token = user_login["logged_in"]["token"]
print("user token") print(user_token)
create_exp_user_object = {"_id": user["_id"], "token": user_token}

Create an experiment for a registered user with the specified configuration

The create_experiment call maps to REST API call /experiments/create. A sample of the create an experiment for a registered user with the specified configuration object is displayed in the following example.
experiment_res = boaas.create_experiment(create_exp_user_object, experiment_config)

print(experiment_res)
experiment_id = experiment_res["experiment"]["_id"]

Run BOA

Get the next parameter set to try, and evaluate y by using the specified evaluation function. Then, insert the new observation into BOA until the wanted number of iterations has been reached. A sample of the run BOA object is displayed in the following example.
boaas.run(experiment_id=experiment_id, user_token=user_token, func=camelback6, no_epochs=4, explain=False)

Print the best minimum or maximum observation of all the observations set

This API call maps to the REST API call /experiments/best_pbservation. A sample of the print the best minimum or maximum observation of all the observations set object is displayed in the following example.
best_observation = boaas.best_observation(experiment_id, user_token)
print("best observation:")
print(best_observation)

Stop an experiment for a registered user

The stop_experiment call maps to the REST API call /experiments/stop. A sample of the stop an experiment for a registered user object is displayed in the following example.
boaas.stop_experiment(experiment_id=experiment_id, user_token=user_token)
The following screen displays a sample output of running a BOA experiment: PTF1-Fix Pack 1
{'_id': 'boa_test@test.com', 'logged_in': {'status': True, 'token': '5c806a36-2b01-11eb-ab4c-a9d04ca0275f'}, 'user': {'_id': 'boa_test@test.com', 'logged_in': {'status': True, 'token': '5c806a36-2b01-11eb-ab4c-a9d04ca0275f'}, 'name': 'boa_test', 'role': 'expuser', 'whitelist': 'true'}}
user token
5c806a36-2b01-11eb-ab4c-a9d04ca0275f
{'experiment': {'_id': '92c7a0be-2b01-11eb-a3b0-f9d9ecbd5771', 'created_at': 1605857132245, 'domain_id': '92c7a3b6-2b01-11eb-a3b0-f9d9ecbd5771', 'initialization': {'random': {'no_samples': 3, 'seed': None}, 'type': 'random'}, 'model': {'gaussian_process': {'kernel_func': 'Matern52', 'noise_kernel': True, 'scale_x': False, 'scale_y': True, 'use_scikit': True}}, 'n_sample': 1, 'name': 'Reg camelback function', 'next_parameter_set': {'X': [[]]}, 'observations_id': '92c7a348-2b01-11eb-a3b0-f9d9ecbd5771', 'optimization_type': 'min', 'sampler_config': {'generating_prior': False, 'mqtt': {'error_notifications_topic': '92c7a1f4-2b01-11eb-a3b0-f9d9ecbd5771/error', 'host': '172.20.181.37', 'lsf_notifications_topic': '92c7a1f4-2b01-11eb-a3b0-f9d9ecbd5771/lsf', 'new_explanation_notifications_topic': '92c7a1f4-2b01-11eb-a3b0-f9d9ecbd5771/new_explanation', 'new_observation_notifications_topic': '92c7a1f4-2b01-11eb-a3b0-f9d9ecbd5771/new_observation', 'new_y_notifications_topic': '92c7a1f4-2b01-11eb-a3b0-f9d9ecbd5771/new_y', 'next_constraint_X_function_notifications_topic': '92c7a1f4-2b01-11eb-a3b0-f9d9ecbd5771/next_constraint_X_function', 'next_constraint_X_function_notifications_topic_ui': '92c7a1f4-2b01-11eb-a3b0-f9d9ecbd5771/next_constraint_X_function_ui', 'next_constraint_X_model_notifications_topic': '92c7a1f4-2b01-11eb-a3b0-f9d9ecbd5771/next_constraint_X_model', 'next_parameter_set_notifications_topic': '92c7a1f4-2b01-11eb-a3b0-f9d9ecbd5771/next_parameter_set', 'port': '80', 'sampler_status_notifications_topic': '92c7a1f4-2b01-11eb-a3b0-f9d9ecbd5771/sampler_status', 'subscription_topic_base': '92c7a1f4-2b01-11eb-a3b0-f9d9ecbd5771', 'url': 'mqtt://172:80', 'ws_https_url': 'wss://172:443/mqttws/', 'ws_port': '80', 'ws_url': 'ws://172:80/mqttws/'}, 'status': 'initializing'}, 'sampling_function': {'batch_sampling': {'use': False}, 'bounds': None, 'epsilon': 0.03, 'explain': None, 'optimize_acq': False, 'outlier': False, 'type': 'expected_improvement'}, 'type': 'default', 'user_id': 'boa_test@test.com', 'y_best': None}, 'status': 'Experiment created'}
Attempting to connect to message broker at URL ws://172:80/mqttws/...
Connected to message broker with result code 0
Calculating the next y value for suggested parameters...
--------------------
Calculating the next y value for suggested parameters...
--------------------
Calculating the next y value for suggested parameters...
--------------------
Calculating the next y value for suggested parameters...
--------------------
Calculating the next y value for suggested parameters...
--------------------
Calculating the next y value for suggested parameters...
--------------------
Calculating the next y value for suggested parameters...
--------------------
Calculating the next y value for suggested parameters...
--------------------
Calculating the next y value for suggested parameters...
--------------------
Calculating the next y value for suggested parameters...
--------------------
Calculating the next y value for suggested parameters...
--------------------
Calculating the next y value for suggested parameters...
--------------------
Calculating the next y value for suggested parameters...
--------------------
Calculating the next y value for suggested parameters...
--------------------
Completed 40 iterations of Bayesian Optimisation.
40 iterations of Bayesian Optimisation have been completed in total for this experiment.
best observation:
{'best': {'X': [-0.12999999999999834, 0.7100000000000015], 'y': -1.0252309320636674}}