<jupyter_start><jupyter_text>Class H1stTune<jupyter_code>import json
import os    

from filelock import FileLock 

from examples.RayTune.tensorflow_mlp_classifier import TensorflowMLPClassifier

# class H1stTune(tune.Trainable):

#     h1st_ml_model = None
#     parameters = {}
    
#     def setup(self, config):
#         from filelock import FileLock 
#         self.config = config
#         self.timestep = 0

model_class = TensorflowMLPClassifier

class TrainH1stModel(tune.Trainable):    
    def setup(self, config):
        self.timestep = 0
#         self.config = config
#         self.timestep = 0
        self.kwargs = {}
        self.hyperparameter = getattr(model_class, 'hyperparameter', {})['tuning_param']
        for k, v in self.hyperparameter.items():
            self.kwargs[k] = v(config[k])
#         kwargs = {
#             'units': int(config['units']),
#             'epochs': int(config['epochs']), 
#             'lr': config['lr'], 
#             'n_layer': int(config['n_layer'])
#         }

        self.h1_ml_model = model_class(**self.kwargs)
#         self.h1_ml_model = model_class(
#             units=int(config['units']), 
#             epochs=int(config['epochs']), 
#             lr=config['lr'], 
#             n_layer=int(config['n_layer']))

#     TensorflowMLPClassifier(
#             units=int(config['units']), 
#             epochs=int(config['epochs']), 
#             lr=config['lr'], 
#             n_layer=int(config['n_layer']))
        
        DATA_ROOT = './data/credit_card'
        lock_file = f'{DATA_ROOT}/data.lock'
        if not os.path.exists(DATA_ROOT):
            os.makedirs(DATA_ROOT)
        with FileLock(os.path.expanduser(lock_file)):
            data = self.h1_ml_model.load_data()
        self.prepared_data = self.h1_ml_model.prep(data)  
        
    def step(self):
        self.timestep += 1
        self.h1_ml_model.train(self.prepared_data)
        self.h1_ml_model.evaluate(self.prepared_data)
        acc = self.h1_ml_model.metrics['accuracy']
        self.h1_ml_model.persist(str(self.timestep) + str())
        return {"mean_accuracy": acc}

    def save_checkpoint(self, checkpoint_dir):
        path = os.path.join(checkpoint_dir, "checkpoint")
        with open(path, "w") as f:
            f.write(json.dumps({"timestep": self.timestep}))
        return path

    def load_checkpoint(self, checkpoint_path):
        with open(checkpoint_path) as f:
            self.timestep = json.loads(f.read())["timestep"]



hyperparameter = {
    'tuning_param': {
        'lr': float, # 0.01 ~ 0.1
        'units': int # 4 ~ 16
    },
    'target_metrics': {
        'accuracy': 'minimize'
    }
}

            
class TrainH1stModel2(tune.Trainable):
#     def __init__(self, h1st_model):
#         self.h1_tf_mlp = h1st_model
    def setup(self, config):
        self.timestep = 0
        self.config = config
        self.h1_tf_mlp = TensorflowMLPClassifier(
            units=int(config['units']), 
            epochs=int(config['epochs']), 
            lr=config['lr'], 
            n_layer=int(config['n_layer']))
        
        DATA_ROOT = './data/credit_card'
        lock_file = f'{DATA_ROOT}/data.lock'
        if not os.path.exists(DATA_ROOT):
            os.makedirs(DATA_ROOT)
        with FileLock(os.path.expanduser(lock_file)):
            data = self.h1_tf_mlp.load_data()
        self.prepared_data = self.h1_tf_mlp.prep(data)  
        
    def step(self):
        self.timestep += 1
        self.h1_tf_mlp.train(self.prepared_data)
        self.h1_tf_mlp.evaluate(self.prepared_data)
        acc = self.h1_tf_mlp.metrics['accuracy']
        self.h1_tf_mlp.persist(str(self.timestep) + str())
        return {"accuracy": acc}

    def save_checkpoint(self, checkpoint_dir):
        path = os.path.join(checkpoint_dir, "checkpoint")
        with open(path, "w") as f:
            f.write(json.dumps({"timestep": self.timestep}))
        return path

    def load_checkpoint(self, checkpoint_path):
        with open(checkpoint_path) as f:
            self.timestep = json.loads(f.read())["timestep"]
            
            
class MyTrainableClass(tune.Trainable):
    """Example agent whose learning curve is a random sigmoid.

    The dummy hyperparameters "width" and "height" determine the slope and
    maximum reward value reached.
    """

    def setup(self, config):
        self.timestep = 0

    def step(self):
        self.timestep += 1
        v = np.tanh(float(self.timestep) / self.config.get("width", 1))
        v *= self.config.get("height", 1)

        # Here we use `episode_reward_mean`, but you can also report other
        # objectives such as loss or accuracy.
        return {"episode_reward_mean": v}

    def save_checkpoint(self, checkpoint_dir):
        path = os.path.join(checkpoint_dir, "checkpoint")
        with open(path, "w") as f:
            f.write(json.dumps({"timestep": self.timestep}))
        return path

    def load_checkpoint(self, checkpoint_path):
        with open(checkpoint_path) as f:
            self.timestep = json.loads(f.read())["timestep"]            
tmp_model = TensorflowMLPClassifier(
            units=32, 
            epochs=5, 
            lr=0.01, 
            n_layer=5)
tmp_model.hyperparameter<jupyter_output><empty_output><jupyter_text>Population Base Training<jupyter_code># config = {
#     "lr": tune.grid_search([0.005]),
#     "units": tune.grid_search([16, 32, 64, 128]),
#     "n_layer": tune.grid_search([3, 5, 10])
# #     "n_layer": tune.uniform(1, 10)
# }

# analysis = tune.run(
#     TrainH1stModel, 
#     config=config, 
#     verbose=2,
#     stop={"training_iteration": 3}
# )
from ray.tune.schedulers import PopulationBasedTraining

# experiment_metrics = dict(metric="accuracy", mode="max")

pbt_scheduler = PopulationBasedTraining(
        time_attr='training_iteration',
        perturbation_interval=2,  # Every N time_attr units, "perturb" the parameters.
        hyperparam_mutations={           
#             "lr": [0.005],
            "lr": lambda: random.uniform(0.001, 0.01),
            "epochs": [2, 10, 30, 100],
            "units": [4, 8, 16, 32, 64],
            "n_layer": [2, 4, 6]            
        })

# Note: This appears to be needed to avoid a "key error", but in fact these values won't change
# in the analysis.dataframe() object, even though they will be tuned by the PBT scheduler.
# So when you look at the analysis.dataframe(), look at the `experiment_tag` to see the actual values!
config = {
    "lr": 0.005,            # Use the lowest values from the previous definition
    "units": 16,
    "n_layer": 4,
    "epochs": 2
}
# analysis = tune.run(TrainH1stModel, 
#     scheduler=pbt_scheduler, 
#     config=config,
#     stop={"training_iteration": 4},
# #     stop={"mean_accuracy": 0.82, "training_iteration": 200},                    
#     num_samples=40,
#     verbose=1,
#     metric="mean_accuracy",
#     mode="max"
# )b

analysis= tune.run(
    TrainH1stModel2,
    config=config,
    metric="accuracy",
    mode="max",
    scheduler=pbt_scheduler,
    stop={"training_iteration": 6},
    verbose=2,
    num_samples=20
)
analysis.dataframe()[['accuracy', 'config/epochs', 'config/lr', 'config/n_layer', 'config/units']].sort_values('accuracy', ascending=False).head(20)
analysis.dataframe()[['mean_accuracy', 'config/epochs', 'config/lr', 'config/n_layer', 'config/units']].sort_values('mean_accuracy', ascending=False).head(20).mean_accuracy.mean()
stats = analysis.stats()
secs = stats["timestamp"] - stats["start_time"]
print(f'{secs:7.2f} seconds, {secs/60.0:7.2f} minutes')<jupyter_output><empty_output><jupyter_text>BO Hyperband (BOHB)<jupyter_code># import json
# import os

# import numpy as np

# import ray
# from ray import tune
# from ray.tune import Trainable
# from ray.tune.schedulers.hb_bohb import HyperBandForBOHB
# from ray.tune.suggest.bohb import TuneBOHB


# class MyTrainableClass(Trainable):
#     """Example agent whose learning curve is a random sigmoid.

#     The dummy hyperparameters "width" and "height" determine the slope and
#     maximum reward value reached.
#     """

#     def setup(self, config):
#         self.timestep = 0

#     def step(self):
#         self.timestep += 1
#         v = np.tanh(float(self.timestep) / self.config.get("width", 1))
#         v *= self.config.get("height", 1)

#         # Here we use `episode_reward_mean`, but you can also report other
#         # objectives such as loss or accuracy.
#         return {"episode_reward_mean": v}

#     def save_checkpoint(self, checkpoint_dir):
#         path = os.path.join(checkpoint_dir, "checkpoint")
#         with open(path, "w") as f:
#             f.write(json.dumps({"timestep": self.timestep}))
#         return path

#     def load_checkpoint(self, checkpoint_path):
#         with open(checkpoint_path) as f:
#             self.timestep = json.loads(f.read())["timestep"]


# if __name__ == "__main__":
#     import ConfigSpace as CS  # noqa: F401
#     ray.init(num_cpus=8)

#     config = {
#         "iterations": 100,
#         "width": tune.uniform(0, 20),
#         "height": tune.uniform(-100, 100),
#         "activation": tune.choice(["relu", "tanh"])
#     }

#     # Optional: Pass the parameter space yourself
#     # config_space = CS.ConfigurationSpace()
#     # config_space.add_hyperparameter(
#     #     CS.UniformFloatHyperparameter("width", lower=0, upper=20))
#     # config_space.add_hyperparameter(
#     #     CS.UniformFloatHyperparameter("height", lower=-100, upper=100))
#     # config_space.add_hyperparameter(
#     #     CS.CategoricalHyperparameter(
#     #         "activation", choices=["relu", "tanh"]))

#     experiment_metrics = dict(metric="episode_reward_mean", mode="max")

#     bohb_hyperband = HyperBandForBOHB(
#         time_attr="training_iteration",
#         max_t=100,
#         reduction_factor=4,
#         **experiment_metrics)

#     bohb_search = TuneBOHB(
#         # space=config_space,  # If you want to set the space manually
#         max_concurrent=4,
#         **experiment_metrics)

#     tune.run(
#         MyTrainableClass,
#         name="bohb_test",
#         config=config,
#         scheduler=bohb_hyperband,
#         search_alg=bohb_search,
#         num_samples=10,
#         stop={"training_iteration": 100})
import ConfigSpace as CS
from ray.tune.schedulers.hb_bohb import HyperBandForBOHB
from ray.tune.suggest.bohb import TuneBOHB
config_space = CS.ConfigurationSpace()

# There are also UniformIntegerHyperparameter and UniformFloatHyperparameter
# objects for defining integer and float ranges, respectively. For example:
# config_space.add_hyperparameter(
#     CS.UniformIntegerHyperparameter('foo', lower=0, upper=100))

config_space.add_hyperparameter(
    CS.UniformFloatHyperparameter('lr', lower=0.005, upper=0.05))
config_space.add_hyperparameter(
    CS.UniformIntegerHyperparameter('units', lower=1, upper=64))
config_space.add_hyperparameter(
    CS.UniformIntegerHyperparameter('n_layer', lower=1, upper=8))
config_space.add_hyperparameter(
    CS.UniformIntegerHyperparameter('epochs', lower=4, upper=50))


# config_space.add_hyperparameter(
#     CS.CategoricalHyperparameter('lr', choices=[0.005]))
# config_space.add_hyperparameter(
#     CS.CategoricalHyperparameter('units', choices=[4, 8, 16, 32]))
# config_space.add_hyperparameter(
#     CS.CategoricalHyperparameter('n_layer', choices=[2, 4, 6, 8]))
# config_space.add_hyperparameter(
#     CS.CategoricalHyperparameter('epochs', choices=[2, 10, 30, 100]))
# tune.run(
#     MyTrainableClass,
#     name="bohb_test",
#     config=config,
#     scheduler=bohb_hyperband,
#     search_alg=bohb_search,
#     num_samples=10,
#     stop={"training_iteration": 100})
config = {
    "lr": tune.uniform(0.002, 0.01),
    "units": tune.uniform(4, 32),
    "n_layer": tune.uniform(1, 8),    
    "epochs": tune.choice([10, 5])
}
experiment_metrics = dict(metric="accuracy", mode="max")
algo = TuneBOHB(
#     config_space, 
    max_concurrent=10, 
    **experiment_metrics
)
# algo = TuneBOHB(config_space, max_concurrent=10)
# search_algorithm = TuneBOHB(config_space, max_concurrent=4)

scheduler = HyperBandForBOHB(
    time_attr="training_iteration",
    max_t=100,
    reduction_factor=4,
    **experiment_metrics
)
analysis= tune.run(
    TrainH1stModel2,
    config=config,
#     metric="mean_accuracy",
#     mode="max",     
    search_alg=algo,
    scheduler=scheduler,
    stop={"training_iteration": 5},
    verbose=2,
    num_samples=20
)

# analysis = tune.run(
#     TrainH1stModel,
#     config=config,
#     scheduler=bohb_hyperband,
#     search_alg=bohb_search,
#     num_samples=10,
#     stop={"training_iteration": 100})

# analysis = tune.run(
#     TrainH1stModel, 
#     scheduler=scheduler, 
#     search_alg=search_algorithm, 
#     metric="mean_accuracy",
#     mode="max",         
#     num_samples=40,                           # Force it try all 12 combinations
#     stop={"training_iteration": 4},
#     verbose=1
# )
analysis.dataframe()[['accuracy', 'config/epochs','config/lr', 'config/n_layer', 'config/units']].sort_values('mean_accuracy', ascending=False)
analysis.dataframe()[['mean_accuracy', 'config/epochs', 'config/lr', 'config/n_layer', 'config/units']].sort_values('mean_accuracy', ascending=False).head(20).mean_accuracy.mean()
stats = analysis.stats()
secs = stats["timestamp"] - stats["start_time"]
print(f'{secs:7.2f} seconds, {secs/60.0:7.2f} minutes')<jupyter_output><empty_output><jupyter_text>Bayesian Optimization (BO)<jupyter_code>"""This test checks that BayesOpt is functional.

It also checks that it is usable with a separate scheduler.
"""
import time


import ray
from ray import tune
from ray.tune.schedulers import AsyncHyperBandScheduler
from ray.tune.suggest import ConcurrencyLimiter
from ray.tune.suggest.bayesopt import BayesOptSearch


# def evaluation_fn(step, width, height):
#     return (0.1 + width * step / 100)**(-1) + height * 0.1


# def easy_objective(config):
#     # Hyperparameters
#     width, height = config["width"], config["height"]

#     for step in range(config["steps"]):
#         # Iterative training function - can be any arbitrary training procedure
#         intermediate_score = evaluation_fn(step, width, height)
#         # Feed the score back back to Tune.
#         tune.report(iterations=step, mean_loss=intermediate_score)
#         time.sleep(0.1)

space = {
    "lr": tune.uniform(0.005, 0.05),
    "units": tune.uniform(1, 64),
    "epochs": tune.uniform(4, 50),    
#     "units": tune.randint(1, 64),
#     "n_layer": tune.randint(1, 8)
    "n_layer": tune.quniform(1, 8, 1.0),    
}

algo = BayesOptSearch(   
    utility_kwargs={
    "kind": "ucb",
    "kappa": 2.5,
    "xi": 0.0
}
)

algo = ConcurrencyLimiter(algo, max_concurrent=10)
scheduler = AsyncHyperBandScheduler()

analysis= tune.run(
    TrainH1stModel,
    config=space,
    metric="mean_accuracy",
    mode="max",     
#     name="my_exp",
    search_alg=algo,
#     scheduler=scheduler,
    stop={"training_iteration": 5},
    verbose=1,
    num_samples=200
)

analysis.dataframe()[['mean_accuracy', 'config/epochs', 'config/lr', 'config/n_layer', 'config/units']].sort_values('mean_accuracy', ascending=False).head(20)
analysis.dataframe()[['mean_accuracy', 'config/epochs', 'config/lr', 'config/n_layer', 'config/units']].sort_values('mean_accuracy', ascending=False).head(20).mean_accuracy.mean()
stats = analysis.stats()
secs = stats["timestamp"] - stats["start_time"]
print(f'{secs:7.2f} seconds, {secs/60.0:7.2f} minutes')<jupyter_output><empty_output><jupyter_text>with AsyncHyperBandScheduler<jupyter_code>analysis.dataframe()[['mean_accuracy', 'config/epochs', 'config/lr', 'config/n_layer', 'config/units']].sort_values('mean_accuracy', ascending=False).head(20)
analysis.dataframe()[['mean_accuracy', 'config/epochs', 'config/lr', 'config/n_layer', 'config/units']].sort_values('mean_accuracy', ascending=False).head(20).mean_accuracy.mean()
stats = analysis.stats()
secs = stats["timestamp"] - stats["start_time"]
print(f'{secs:7.2f} seconds, {secs/60.0:7.2f} minutes')<jupyter_output><empty_output><jupyter_text>OptunaSearch<jupyter_code>from ray.tune.suggest import ConcurrencyLimiter
from ray.tune.schedulers import AsyncHyperBandScheduler
from ray.tune.suggest.optuna import OptunaSearch
tune_kwargs = {
    "num_samples": 200,
    "config": {
        "lr": tune.uniform(0.005, 0.05),
        "units": tune.uniform(1, 64),
        "epochs": tune.uniform(4, 50),    
        "n_layer": tune.choice([2, 4, 6]),           
    }
}
algo = OptunaSearch()
algo = ConcurrencyLimiter(algo, max_concurrent=10)
scheduler = AsyncHyperBandScheduler()
analysis = tune.run(
    TrainH1stModel2,
    metric="mean_accuracy",
    mode="max",
    search_alg=algo,
    scheduler=scheduler,
    **tune_kwargs)
analysis.dataframe().head(10)
analysis.dataframe()[['mean_accuracy', 'config/epochs', 'config/lr', 'config/n_layer', 'config/units']].sort_values('mean_accuracy', ascending=False).head(20)
analysis.dataframe()[['mean_accuracy', 'config/epochs', 'config/lr', 'config/n_layer', 'config/units']].sort_values('mean_accuracy', ascending=False).head(20).mean_accuracy.mean()
stats = analysis.stats()
secs = stats["timestamp"] - stats["start_time"]
print(f'{secs:7.2f} seconds, {secs/60.0:7.2f} minutes')<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.14261928001377963, 'fraction_numerical': 0.02170293391514038, 'mean_word_length': 3.2901477832512316, 'pattern_counts': {'":': 56, '<': 25, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '6', 'dir': 'jupyter-structured-clean-dedup', 'id': '529996', 'license': 'Apache-2.0', 'n_tokens_mistral': 6210, 'n_tokens_neox': 5904, 'n_words': 1073, 'path': 'examples/RayTune/RayTune_with_H1st_Class.ipynb', 'repo_name': 'vophihungvn/h1st', 'size': '17417'}