From 6ba193222ebc07dfac5b8826e4a8a68e4326a14e Mon Sep 17 00:00:00 2001 From: ianran Date: Mon, 8 Jan 2024 15:13:57 -0800 Subject: [PATCH] Added gif generator for examples to show training with preferences --- examples/.gitignore | 1 + .../active_learners/pref_gp_ucb_learner.py | 74 +++++++++++++------ src/lop/models/PreferenceGP.py | 13 +++- tests/kernels/test_gp_kernel.py | 4 +- 4 files changed, 69 insertions(+), 23 deletions(-) create mode 100644 examples/.gitignore diff --git a/examples/.gitignore b/examples/.gitignore new file mode 100644 index 0000000..e3d998b --- /dev/null +++ b/examples/.gitignore @@ -0,0 +1 @@ +**.gif diff --git a/examples/active_learners/pref_gp_ucb_learner.py b/examples/active_learners/pref_gp_ucb_learner.py index aa8aa53..1337e56 100644 --- a/examples/active_learners/pref_gp_ucb_learner.py +++ b/examples/active_learners/pref_gp_ucb_learner.py @@ -26,6 +26,8 @@ import numpy as np import matplotlib.pyplot as plt +from matplotlib.animation import FFMpegWriter + import lop @@ -33,42 +35,72 @@ def f_sin(x, data=None): return 2 * np.cos(np.pi * (x-2)) * np.exp(-(0.9*x)) -def main(): - al = lop.GV_UCBLearner() - model = lop.PreferenceGP(lop.RBF_kern(0.5,0.7), active_learner=al, normalize_gp=True) - - - # Generate active learning point and add it to the model - for i in range(10): - # generate random test set to select test point from - x_canidiates = np.random.random(20)*10 - - test_pt_idxs = model.select(x_canidiates, 2) - - - x_train = x_canidiates[test_pt_idxs] - y_train = f_sin(x_train) - y_pairs = lop.gen_pairs_from_idx(np.argmax(y_train), list(range(len(y_train)))) - - model.add(x_train, y_pairs) +def plot_data(model, new_selections=None): # Create test output of model x_test = np.arange(0,10,0.005) y_test = f_sin(x_test) y_pred,y_sigma = model.predict(x_test) std = np.sqrt(y_sigma) - print(std) - # Plot output of model with uncertianty sigma_to_plot = 1.96 + + plt.clf() plt.plot(x_test, y_test, zorder=5) plt.plot(x_test, y_pred, zorder=5) - plt.scatter(model.X_train, model.F, zorder=10) + + if hasattr(model, "F"): + plt.scatter(model.X_train, model.F, zorder=10) + plt.gca().fill_between(x_test, y_pred-(sigma_to_plot*std), y_pred+(sigma_to_plot*std), color='#dddddd', zorder=1) + if new_selections is not None: + print('Show scatter?') + print(new_selections) + print(model.F[-len(new_selections):]) + plt.scatter(new_selections, model.F[-len(new_selections):], color='orange', zorder=20) plt.xlabel('input values') plt.ylabel('GP output') plt.legend(['Real function', 'Predicted function', 'Active learning points', '95% condidence region']) + + +def main(): + al = lop.GV_UCBLearner() + #al = lop.RandomLearner() + model = lop.PreferenceGP(lop.RBF_kern(0.5,0.7), active_learner=al, normalize_gp=False) + model.probits[0].set_sigma(0.5) + + fig = plt.figure() + writer = FFMpegWriter(fps=2) + + with writer.saving(fig, "write_test.gif", 100): + + plot_data(model) + writer.grab_frame() + + # Generate active learning point and add it to the model + for i in range(10): + # generate random test set to select test point from + x_canidiates = np.random.random(20)*10 + + test_pt_idxs = model.select(x_canidiates, 2) + + + x_train = x_canidiates[test_pt_idxs] + y_train = f_sin(x_train) + y_pairs = lop.gen_pairs_from_idx(np.argmax(y_train), list(range(len(y_train)))) + # y_pairs = lop.generate_fake_pairs(x_train, f_sin, 0) + \ + # lop.generate_fake_pairs(x_train, f_sin, 1) + \ + # lop.generate_fake_pairs(x_train, f_sin, 2) + + model.add(x_train, y_pairs) + + plot_data(model, x_train) + writer.grab_frame() + + # plot_data(model) + # writer.grab_frame() + plt.show() if __name__ == '__main__': diff --git a/src/lop/models/PreferenceGP.py b/src/lop/models/PreferenceGP.py index b1a9a50..0fee9fc 100644 --- a/src/lop/models/PreferenceGP.py +++ b/src/lop/models/PreferenceGP.py @@ -275,7 +275,18 @@ def loss_func(self, F): log_py_f = self.log_likelyhood_training(F) K_inv = self.invert_function(K) term1 = 0.5*(np.transpose(F) @ K_inv @ F) - term2 = np.log(np.linalg.det(K)) + det_K = np.linalg.det(K) + while det_K <= 0: + #K = K + np.eye(K.shape[0])*0.01 + rand_arr = np.random.normal(0, 0.1, size=K.shape[0]) + K = K + np.diag(np.where(rand_arr<0, 0, rand_arr)) + print('Adding noise to covariance matrix to avoid being singular') + det_K = np.linalg.det(K) + term2 = np.log(det_K) + term3 = 0.5*len(F) * np.log(2 * np.pi) + + #log_py_f = 0 + log_prior = log_py_f - term1 - term2 - term3 return log_prior diff --git a/tests/kernels/test_gp_kernel.py b/tests/kernels/test_gp_kernel.py index f0a944f..17633af 100644 --- a/tests/kernels/test_gp_kernel.py +++ b/tests/kernels/test_gp_kernel.py @@ -165,4 +165,6 @@ def test_rbf_kern_cov(): assert c[i,i] == 1 assert c[-1,0] < 0.0001 - assert c[0,-1] < 0.0001 \ No newline at end of file + assert c[0,-1] < 0.0001 + + assert np.linalg.det(c) > 0 \ No newline at end of file