Skip to content

Commit 201cf10

Browse files
Merge pull request #40 from CodeCutTech/add-gpr-optimization
Add gpr optimization
2 parents a266ec4 + 26ece2b commit 201cf10

File tree

3 files changed

+317
-0
lines changed

3 files changed

+317
-0
lines changed

machine-learning/gpr_optimization.py

Lines changed: 231 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,231 @@
1+
# /// script
2+
# requires-python = ">=3.12"
3+
# dependencies = [
4+
# "marimo",
5+
# "matplotlib==3.10.3",
6+
# "numpy==2.2.6",
7+
# "scikit-learn==1.6.1",
8+
# "scipy==1.15.3",
9+
# ]
10+
# ///
11+
12+
import marimo
13+
14+
__generated_with = "0.13.7"
15+
app = marimo.App(width="medium")
16+
17+
18+
@app.cell
19+
def _():
20+
import random
21+
import time
22+
23+
def train_model(epochs, batch_size):
24+
# Simulate training by producing a score based on epochs and batch size
25+
time.sleep(0.5) # 0.5 second delay to mimic compute time
26+
random.seed(epochs + batch_size)
27+
return {"score": random.uniform(0.7, 0.95)}
28+
29+
def evaluate_model(model):
30+
return model["score"]
31+
32+
best_score = float("-inf")
33+
best_params = None
34+
35+
for epochs in [10, 50, 100]:
36+
for batch_size in [16, 32, 64]:
37+
print(f"Training model with epochs={epochs}, batch_size={batch_size}...")
38+
model = train_model(epochs=epochs, batch_size=batch_size)
39+
score = evaluate_model(model)
40+
print(f"--> Score: {score:.4f}")
41+
if score > best_score:
42+
best_score = score
43+
best_params = {"epochs": epochs, "batch_size": batch_size}
44+
print(f"--> New best score! Updated best_params: {best_params}")
45+
46+
print("Best score:", best_score)
47+
print("Best params:", best_params)
48+
return (time,)
49+
50+
51+
@app.cell
52+
def _():
53+
import matplotlib.pyplot as plt
54+
import numpy as np
55+
from sklearn.gaussian_process import GaussianProcessRegressor
56+
from sklearn.gaussian_process.kernels import ConstantKernel as C
57+
from sklearn.gaussian_process.kernels import Matern, WhiteKernel
58+
return C, GaussianProcessRegressor, Matern, WhiteKernel, np, plt
59+
60+
61+
@app.cell
62+
def _(np):
63+
def black_box_function(x):
64+
return - (np.sin(3*x) + 0.5 * x)
65+
return (black_box_function,)
66+
67+
68+
@app.cell
69+
def _(black_box_function, np, plt):
70+
X = np.linspace(0, 5.5, 1000).reshape(-1, 1)
71+
y = black_box_function(X)
72+
plt.plot(X, y)
73+
plt.title("Black-box function")
74+
plt.xlabel("x")
75+
plt.ylabel("f(x)")
76+
plt.show()
77+
return X, y
78+
79+
80+
@app.cell
81+
def _(black_box_function, np):
82+
X_grid = np.linspace(0, 2, 100).reshape(-1, 1)
83+
y_grid = black_box_function(X_grid)
84+
x_best = X_grid[np.argmax(y_grid)]
85+
return
86+
87+
88+
@app.cell
89+
def _(black_box_function, np, time):
90+
def train(epochs):
91+
time.sleep(0.1) # Simulate a slow training step
92+
return black_box_function(epochs)
93+
94+
search_space = np.linspace(0, 5, 1000)
95+
results = []
96+
97+
start = time.time()
98+
for x in search_space:
99+
loss = train(x)
100+
results.append((x, loss))
101+
end = time.time()
102+
103+
print("Best x:", search_space[np.argmin([r[1] for r in results])])
104+
print("Time taken:", round(end - start, 2), "seconds")
105+
return
106+
107+
108+
@app.cell
109+
def _(black_box_function, np):
110+
# Initial sample points (simulate prior evaluations)
111+
X_sample = np.array([[1.0], [3.0], [5.5]])
112+
y_sample = black_box_function(X_sample)
113+
return X_sample, y_sample
114+
115+
116+
@app.cell
117+
def _(C, GaussianProcessRegressor, Matern, WhiteKernel, X_sample, y_sample):
118+
# Define the kernel
119+
kernel = C(1.0) * Matern(length_scale=1.0, nu=2.5) + WhiteKernel(noise_level=1e-5, noise_level_bounds=(1e-10, 1e1))
120+
121+
# Create and fit the Gaussian Process model
122+
gpr = GaussianProcessRegressor(kernel=kernel, alpha=0.0)
123+
gpr.fit(X_sample, y_sample)
124+
return (gpr,)
125+
126+
127+
@app.cell
128+
def _(X, X_sample, gpr, plt, y, y_sample):
129+
# Predict across the domain
130+
mu, std = gpr.predict(X, return_std=True)
131+
132+
# Plot the result
133+
plt.figure(figsize=(10, 5))
134+
plt.plot(X, y, "k--", label="True function")
135+
plt.plot(X, mu, "b-", label="GPR mean")
136+
plt.fill_between(X.ravel(), mu - std, mu + std, alpha=0.3, label="Uncertainty")
137+
plt.scatter(X_sample, y_sample, c="red", label="Samples")
138+
plt.legend()
139+
plt.title("Gaussian Process Fit")
140+
plt.xlabel("x")
141+
plt.ylabel("f(x)")
142+
plt.show()
143+
return
144+
145+
146+
@app.cell
147+
def _(np):
148+
from scipy.stats import norm
149+
150+
def expected_improvement(X, X_sample, y_sample, model, xi=0.01):
151+
mu, std = model.predict(X, return_std=True)
152+
mu_sample_opt = np.min(y_sample)
153+
154+
with np.errstate(divide="warn"):
155+
imp = mu_sample_opt - mu - xi # because we are minimizing
156+
Z = imp / std
157+
ei = imp * norm.cdf(Z) + std * norm.pdf(Z)
158+
ei[std == 0.0] = 0.0
159+
160+
return ei
161+
162+
return (expected_improvement,)
163+
164+
165+
@app.cell
166+
def _(X, X_sample, expected_improvement, gpr, np, plt, y_sample):
167+
ei = expected_improvement(X, X_sample, y_sample, gpr)
168+
169+
plt.figure(figsize=(10, 4))
170+
plt.plot(X, ei, label="Expected Improvement")
171+
plt.axvline(X[np.argmax(ei)], color="r", linestyle="--", label="Next sample point")
172+
plt.title("Acquisition Function (Expected Improvement)")
173+
plt.xlabel("x")
174+
plt.ylabel("EI(x)")
175+
plt.legend()
176+
plt.show()
177+
178+
return
179+
180+
181+
@app.cell
182+
def _(X, black_box_function, expected_improvement, gpr, np):
183+
def bayesian_optimization(n_iter=10):
184+
# Initial data
185+
X_sample = np.array([[1.0], [2.5], [4.0]])
186+
y_sample = black_box_function(X_sample)
187+
188+
for _ in range(n_iter):
189+
gpr.fit(X_sample, y_sample)
190+
ei = expected_improvement(X, X_sample, y_sample, gpr)
191+
x_next = X[np.argmax(ei)].reshape(-1, 1)
192+
193+
# Evaluate the function at the new point
194+
y_next = black_box_function(x_next)
195+
196+
# Add the new sample to our dataset
197+
X_sample = np.vstack((X_sample, x_next))
198+
y_sample = np.append(y_sample, y_next)
199+
return X_sample, y_sample
200+
201+
return (bayesian_optimization,)
202+
203+
204+
@app.cell
205+
def _(bayesian_optimization):
206+
X_opt, y_opt = bayesian_optimization(n_iter=10)
207+
208+
return X_opt, y_opt
209+
210+
211+
@app.cell
212+
def _(X, X_opt, black_box_function, plt, y_opt):
213+
# Plot final sampled points
214+
plt.plot(X, black_box_function(X), "k--", label="True function")
215+
plt.scatter(X_opt, y_opt, c="red", label="Sampled Points")
216+
plt.title("Bayesian Optimization with Gaussian Process")
217+
plt.xlabel("x")
218+
plt.ylabel("f(x)")
219+
plt.legend()
220+
plt.show()
221+
222+
return
223+
224+
225+
@app.cell
226+
def _():
227+
return
228+
229+
230+
if __name__ == "__main__":
231+
app.run()

public/index.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,10 @@ <h2 class="notebook-title">lchain ollama</h2>
101101
<h2 class="notebook-title">pydantic ai examples</h2>
102102
<a href="llm/pydantic_ai_examples.html" class="notebook-link">View the notebook</a>
103103
</li>
104+
<li class="notebook-item">
105+
<h2 class="notebook-title">gpr optimization</h2>
106+
<a href="machine-learning/gpr_optimization.html" class="notebook-link">View the notebook</a>
107+
</li>
104108
</ul>
105109
</body>
106110
</html>

public/machine-learning/gpr_optimization.html

Lines changed: 82 additions & 0 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)