diff --git a/optunapi/config/optunapi-test.yaml b/optunapi/config/optunapi-test.yaml deleted file mode 100644 index e415ecc..0000000 --- a/optunapi/config/optunapi-test.yaml +++ /dev/null @@ -1,17 +0,0 @@ -x : - name : x - type : float - choices : - low : -10 - high : 10 - step : - log : False - -y : - name : y - type : float - choices : - low : -10 - high : 10 - step : - log : False diff --git a/optunapi/server.py b/optunapi/server.py deleted file mode 100644 index 66af904..0000000 --- a/optunapi/server.py +++ /dev/null @@ -1,187 +0,0 @@ -import os -PATH = os.path.abspath (os.path.dirname (__file__)) - -from fastapi import FastAPI -optunapi = FastAPI() - -import optuna -from optuna.trial._state import TrialState - -from typing import Optional -from utils import suggest_from_config, create_log_file - - -@optunapi.get ('/optunapi/ping') -async def ping_server(): - """ - Ping Server - =========== - - Returns the message "The Optuna-server is alive!" if the server is running. - - Parameters - ---------- - None - - Returns - ------- - msg : str - A message witnessing that the server is running. - """ - msg = 'The Optuna-server is alive!' - return msg - - -@optunapi.get ('/optunapi/hparams/{model_name}') -async def read_hparams (model_name: str): - """ - Read Hyperparameters - ==================== - - When a machine submits a GET request with path `/optunapi/hparams/{model_name}`, - an Optuna study is created (if it's the first request) or loaded (for any other - requests) and an ask instance is called. The resulting trial is equipped with a - set of hyperparameters and encoded to the HTTP response together with the name - of the optimization session, the trial identifier, the number of running trials - and the number of completed trials. - - Parameters - ---------- - model_name : str (path parameter) - Name of the optimization session for which one asks for hyperparameters. - - Returns - ------- - response : dict (HTTP response) - Dictionary with the following items: - - `model_name` > Name of the optimization session - - `trial_id` > Number identifying the created trial - - `params` > Current set of values for the hyperparameters - - `running_trials` > Number of running trials - - `completed_trials` > Number of completed trials - """ - storage_dir = os.path.join (PATH, 'db') - storage_name = 'sqlite:///{}/{}.db' . format (storage_dir, model_name) - study = optuna.create_study ( - study_name = model_name , - storage = storage_name , - load_if_exists = True , - ) - - trial = study.ask() - - config_file = '{}/config/{}.yaml' . format (PATH, model_name) - suggest_from_config (trial, configuration = config_file) - - log_file = '{}/log/{}.log' . format (PATH, model_name) - create_log_file (study, log_file = log_file) - - running_trials = study.get_trials ( - deepcopy = False, - states = (TrialState.RUNNING,) - ) - completed_trials = study.get_trials ( - deepcopy = False, - states = (TrialState.COMPLETE,) - ) - - trial_id = study.trials[-1].number - params = study.trials[-1].params - num_running_trials = len (running_trials) - num_completed_trials = len (completed_trials) - - response = { - 'model_name' : model_name , - 'trial_id' : trial_id , - 'params' : params , - 'running_trials' : num_running_trials , - 'completed_trials' : num_completed_trials , - } - - return response - - -@optunapi.get ('/optunapi/score/{model_name}') -async def send_score ( - model_name : str , - trial_id : int , - score : float , - ): - """ - Send Score - ========== - - When a machine submits a GET request with path `/optunapi/score/{model_name}?trial_id=TRIAL_ID&score=SCORE`, - an Optuna study is loaded and its trial `TRIAL_ID` is finished with score `SCORE` calling a tell instance. - The corresponding HTTP response encodes the name of the optimization session, `TRIAL_ID`, the tested set of - hyperparameters, `SCORE`, the number identifying the best trial, the best set of hyperparameters, the best - score, the number of running trials and the number of completed trials. - - Parameters - ---------- - model_name : str (path parameter) - Name of the optimization session for which one asks for hyperparameters. - - trial_id : int (query parameter) - Number identifying the tested trial. - - score : float (query parameter) - Score obtained with the set of hyperparameters tested. - - Returns - ------- - response : dict (HTTP response) - Dictionary with the following items: - - `model_name` > Name of the optimization session - - `trial_id` > Number identifying the tested trial - - `params` > Tested set of values for the hyperparameters - - `score` > Score obtained with the tested set of hyperparameters - - `best_trial_id` > Number identifying the best trial - - `best_params` > Best set of values for the hyperparameters - - `best_score` > Score obtained with the best set of hyperparameters - - `running_trials` > Number of running trials - - `completed_trials` > Number of completed trials - """ - storage_dir = os.path.join (PATH, 'db') - storage_name = 'sqlite:///{}/{}.db' . format (storage_dir, model_name) - study = optuna.create_study ( - study_name = model_name , - storage = storage_name , - load_if_exists = True , - ) - - study.tell (trial_id, score) - - log_file = '{}/log/{}.log' . format (PATH, model_name) - create_log_file (study, log_file = log_file) - - running_trials = study.get_trials ( - deepcopy = False, - states = (TrialState.RUNNING,) - ) - completed_trials = study.get_trials ( - deepcopy = False, - states = (TrialState.COMPLETE,) - ) - - params = study.trials[trial_id].params - best_trial = study.best_trial.number - best_params = study.best_params - best_score = study.best_value - num_running_trials = len (running_trials) - num_completed_trials = len (completed_trials) - - response = { - 'model_name' : model_name , - 'trial_id' : trial_id , - 'params' : params , - 'score' : score , - 'best_trial' : best_trial , - 'best_params' : best_params , - 'best_score' : best_score , - 'running_trials' : num_running_trials , - 'completed_trials' : num_completed_trials , - } - - return response - \ No newline at end of file diff --git a/optunapi/db/.gitkeep b/optunapi/study/.gitkeep similarity index 100% rename from optunapi/db/.gitkeep rename to optunapi/study/.gitkeep diff --git a/optunapi/log/.gitkeep b/optunapi/trial/.gitkeep similarity index 100% rename from optunapi/log/.gitkeep rename to optunapi/trial/.gitkeep diff --git a/optunapi/utils/__init__.py b/optunapi/utils/__init__.py deleted file mode 100644 index ca7f3ff..0000000 --- a/optunapi/utils/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -from .suggest_from_config import suggest_from_config -from .create_log_file import create_log_file diff --git a/optunapi/utils/create_log_file.py b/optunapi/utils/create_log_file.py deleted file mode 100644 index 51b96a9..0000000 --- a/optunapi/utils/create_log_file.py +++ /dev/null @@ -1,25 +0,0 @@ -from optuna.study import Study - - -def create_log_file (study: Study, log_file: str): - """ - Create Log File - =============== - - Allows to create a log file containing a pandas `DataFrame` of trials in the `Study`. - - Parameters - ---------- - study : optuna.study.Study - Set of `Trial` objects deriving from an Ask-and-Tell interface. - - log_file : str - Name of file reporting the study results. - - Returns - ------- - None - """ - df = study.trials_dataframe ( attrs = ('number', 'params', 'value', 'state') ) - with open (log_file, 'w') as file: - print (df.to_string(), file = file) diff --git a/optunapi/utils/suggest_from_config.py b/optunapi/utils/suggest_from_config.py deleted file mode 100644 index 2b2b3e3..0000000 --- a/optunapi/utils/suggest_from_config.py +++ /dev/null @@ -1,51 +0,0 @@ -import yaml -from optuna.trial import Trial - - -def suggest_from_config (trial: Trial, configuration: str): - """ - Suggest From Config - =================== - - Allows to generalize the `suggest_*` functions taking - information from a YAML configuration file. - - Parameters - ---------- - trial : optuna.trial.Trial - `Trial` object deriving from an Ask-and-Tell interface. - - configuration : str - YAML file containing hyperparameters configuration. - - Returns - ------- - None - """ - with open (configuration) as file: - params = yaml.full_load (file) - - for par in params.values(): - if par['type'] == 'categorical': - trial.suggest_categorical ( - name = str ( par [ 'name' ] ) , - choices = list ( par [ 'choices' ] ) , - ) - elif par['type'] == 'float': - trial.suggest_float ( - name = str ( par [ 'name' ] ) , - low = float ( par [ 'low' ] ) , - high = float ( par [ 'high' ] ) , - step = float ( par [ 'step' ] ) if par [ 'step' ] else None , - log = bool ( par [ 'log' ] ) if par [ 'log' ] else False , - ) - elif par['type'] == 'int': - trial.suggest_int ( - name = str ( par [ 'name' ] ) , - low = float ( par [ 'low' ] ) , - high = float ( par [ 'high' ] ) , - step = float ( par [ 'step' ] ) if par [ 'step' ] else 1 , - log = bool ( par [ 'log' ] ) if par [ 'log' ] else False , - ) - else: - raise ValueError ('Trial suggestion not implemented.') diff --git a/optunapi/version.py b/optunapi/version.py new file mode 100644 index 0000000..49f34f4 --- /dev/null +++ b/optunapi/version.py @@ -0,0 +1 @@ +__version__ = "0.2.0" \ No newline at end of file diff --git a/tests/.gitkeep b/tests/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/tests/secured_client.py b/tests/secured_client.py deleted file mode 100644 index 8daa172..0000000 --- a/tests/secured_client.py +++ /dev/null @@ -1,14 +0,0 @@ -import sshtunnel -import requests - - -with sshtunnel.open_tunnel ( - (REMOTE_SERVER_IP, 22), - ssh_username = 'mbarbetti', - ssh_pkey = '/home/mbarbetti/.ssh/id_rsa', - remote_bind_address = (PRIVATE_SERVER_IP, PRIVATE_SERVER_PORT), - local_bind_address = ('127.0.0.1', 10022) -) as tunnel: - ping_server = requests.get ('http://localhost:10022/optunapi/ping') - ping_msg = ping_server.json() - print (ping_msg) \ No newline at end of file diff --git a/tests/simple_client.py b/tests/simple_client.py deleted file mode 100644 index 55385d4..0000000 --- a/tests/simple_client.py +++ /dev/null @@ -1,45 +0,0 @@ -import requests - - -HOST = 'http://127.0.0.1:8000' -model_name = 'optunapi-test' - -num_trials = 10 -for _ in range (num_trials): - read_hparams = requests.get (HOST + '/optunapi/hparams/{}' . format (model_name)) - hp_req = read_hparams.json() - - trial_id = hp_req [ 'trial_id' ] - params = hp_req [ 'params' ] - running_trials = hp_req [ 'running_trials' ] - - print ( - 'Trial {} started with parameters: {}. Total number of running trials: {}.' \ - . format ( trial_id, params, running_trials ) - ) - - x = params['x'] - y = params['y'] - func = (x - 2) ** 2 + (y - 3) ** 2 - - send_score = requests.get (HOST + '/optunapi/score/{}?trial_id={}&score={}' . format (model_name, trial_id, func)) - score_req = send_score.json() - - trial_id = score_req [ 'trial_id' ] - score = score_req [ 'score' ] - best_trial = score_req [ 'best_trial' ] - best_score = score_req [ 'best_score' ] - best_params = score_req [ 'best_params' ] - completed_trials = score_req [ 'completed_trials' ] - - print ( - 'Trial {} finished with value: {}. Best is trial {} with value: {} and parameters: {}. Total number of completed trials: {}.\n' \ - . format ( trial_id, score, best_trial, best_score, best_params, completed_trials ) - ) - -print ( '\nRESULT AFTER {} TRIALS' . format (completed_trials) ) -print ( '+--------------------------------+' ) -print ( '| x : {:.4f} |' . format (best_params['x']) ) -print ( '| y : {:.4f} |' . format (best_params['y']) ) -print ( '| (x - 2)^2 + (y - 3)^2 : {:.4f} |' . format (best_score) ) -print ( '+--------------------------------+\n' )