-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbayesian_optimizer.py
More file actions
executable file
·131 lines (107 loc) · 4.45 KB
/
Copy pathbayesian_optimizer.py
File metadata and controls
executable file
·131 lines (107 loc) · 4.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
import optuna
import mlflow
import numpy as np
import pandas as pd
from pyspark.sql import SparkSession
import warnings
warnings.filterwarnings("ignore")
# MLflow config
TRACKING_URI = "sqlite:////home/hadoop/hpo_project/mlflow.db"
mlflow.set_tracking_uri(TRACKING_URI)
experiment = mlflow.get_experiment_by_name("HPO_Bayesian_Optimization")
experiment_id = experiment.experiment_id
# Load historical data from HDFS via PySpark
spark = SparkSession.builder \
.appName("HPO Bayesian Optimizer") \
.config("spark.hadoop.fs.defaultFS", "hdfs://localhost:9000") \
.getOrCreate()
spark.sparkContext.setLogLevel("ERROR")
print("✅ Loading historical HPO data from HDFS...")
df = spark.read.parquet(
"hdfs://localhost:9000/hpo/processed/hpo_runs_parquet"
).toPandas()
print(f"✅ Loaded {len(df):,} historical runs")
# Build surrogate model from historical data
from sklearn.ensemble import RandomForestRegressor
from sklearn.preprocessing import LabelEncoder
print("🔧 Training surrogate model on historical runs...")
le_opt = LabelEncoder()
le_space = LabelEncoder()
df["optimizer_enc"] = le_opt.fit_transform(df["optimizer"])
df["space_enc"] = le_space.fit_transform(df["search_space_id"].astype(str))
feature_cols = [
"learning_rate", "batch_size", "dropout",
"num_layers", "hidden_units", "weight_decay",
"epochs", "optimizer_enc", "space_enc"
]
X = df[feature_cols].values
y = df["val_accuracy"].values
surrogate = RandomForestRegressor(n_estimators=50, random_state=42, n_jobs=-1)
surrogate.fit(X, y)
print(f"✅ Surrogate model trained! R² score: {surrogate.score(X, y):.4f}")
spark.stop()
# Define Optuna objective using surrogate
def objective(trial):
params = {
"learning_rate": trial.suggest_float("learning_rate", 1e-5, 1e-1, log=True),
"batch_size": trial.suggest_categorical("batch_size", [16, 32, 64, 128, 256]),
"dropout": trial.suggest_float("dropout", 0.0, 0.5),
"num_layers": trial.suggest_int("num_layers", 1, 5),
"hidden_units": trial.suggest_categorical("hidden_units", [64, 128, 256, 512]),
"weight_decay": trial.suggest_float("weight_decay", 1e-6, 1e-2, log=True),
"epochs": trial.suggest_int("epochs", 10, 200),
"optimizer": trial.suggest_categorical("optimizer", ["adam", "sgd", "rmsprop", "adagrad"]),
"search_space_id": "5859"
}
# Encode for surrogate
try:
opt_enc = le_opt.transform([params["optimizer"]])[0]
space_enc = le_space.transform([params["search_space_id"]])[0]
except:
return 0.0
X_pred = np.array([[
params["learning_rate"], params["batch_size"],
params["dropout"], params["num_layers"],
params["hidden_units"], params["weight_decay"],
params["epochs"], opt_enc, space_enc
]])
predicted_accuracy = surrogate.predict(X_pred)[0]
return predicted_accuracy
# Run Bayesian optimization
print("\n🚀 Running Bayesian Optimization...")
print("=" * 50)
with mlflow.start_run(experiment_id=experiment_id, run_name="bayesian_optimization"):
# Baseline — random search
random_study = optuna.create_study(
direction="maximize",
sampler=optuna.samplers.RandomSampler(seed=42)
)
random_study.optimize(objective, n_trials=200, show_progress_bar=False)
random_best = random_study.best_value
print(f"✅ Random Search best: {random_best:.4f}")
# Bayesian optimization with TPE
tpe_study = optuna.create_study(
direction="maximize",
sampler=optuna.samplers.TPESampler(seed=42)
)
tpe_study.optimize(objective, n_trials=200, show_progress_bar=False)
tpe_best = tpe_study.best_value
print(f"✅ Bayesian (TPE) best: {tpe_best:.4f}")
# Improvement
improvement = ((tpe_best - random_best) / random_best) * 100
print(f"✅ Improvement over random: {improvement:.2f}%")
# Log to MLflow
mlflow.log_param("n_trials", 50)
mlflow.log_param("sampler", "TPE")
mlflow.log_param("target_search_space", "5859")
mlflow.log_metric("random_search_best", round(random_best, 4))
mlflow.log_metric("bayesian_best", round(tpe_best, 4))
mlflow.log_metric("improvement_pct", round(improvement, 2))
# Log best hyperparameters
best_params = tpe_study.best_params
for k, v in best_params.items():
mlflow.log_param(f"best_{k}", v)
print("\n🏆 Best Hyperparameters Found:")
for k, v in best_params.items():
print(f" {k}: {v}")
print("\n🎉 Day 7 Complete — Bayesian Optimizer working!")