def testGPPrior(self): # see how GP works with the dataprior... def foo(x): return sum(sin(x * 20)) bounds = [[0., 1.]] # train prior pX = lhcSample([[0., 1.]], 100, seed=6) pY = [foo(x) for x in pX] prior = RBFNMeanPrior() prior.train(pX, pY, bounds, k=10, seed=102) X = lhcSample([[0., 1.]], 2, seed=7) Y = [foo(x) for x in X] kernel = GaussianKernel_ard(array([.1])) GP = GaussianProcess(kernel, X, Y, prior=prior) GPnoprior = GaussianProcess(kernel, X, Y) S = arange(0, 1, .01) nopriorErr = mean([(foo(x) - GPnoprior.mu(x))**2 for x in S]) priorErr = mean([(foo(x) - GP.mu(x))**2 for x in S]) self.failUnless(priorErr < nopriorErr * .5) if False: figure(1) clf() plot(S, [prior.mu(x) for x in S], 'g-', alpha=0.3) plot(S, [GPnoprior.mu(x) for x in S], 'b-', alpha=0.3) plot(S, [GP.mu(x) for x in S], 'k-', lw=2) plot(X, Y, 'ko') show()
def test2DpyEI(self): f = lambda x: sum(sin(x)) bounds = [[0., 5.], [0., 5.]] X = lhcSample(bounds, 5, seed=24) Y = [f(x) for x in X] kernel = GaussianKernel_ard(array([1.0, 1.0])) GP = GaussianProcess(kernel, X, Y) maxei = maximizeEI(GP, bounds) if False: figure(1) c0 = [(i / 50.) * (bounds[0][1] - bounds[0][0]) + bounds[0][0] for i in range(51)] c1 = [(i / 50.) * (bounds[1][1] - bounds[1][0]) + bounds[1][0] for i in range(51)] z = array([[GP.ei(array([i, j])) for i in c0] for j in c1]) ax = plt.subplot(111) cs = ax.contour(c0, c1, z, 10, alpha=0.5, cmap=cm.Blues_r) plot([x[0] for x in X], [x[1] for x in X], 'ro') for i in range(len(X)): annotate('%2f' % Y[i], X[i]) plot(maxei[1][0], maxei[1][1], 'ko') show()
def testPriorAndPrefs(self): S5 = Shekel5() pX = lhcSample(S5.bounds, 100, seed=13) pY = [S5.f(x) for x in pX] prior = RBFNMeanPrior() prior.train(pX, pY, S5.bounds, k=10) hv = .1 hyper = [hv, hv, hv, hv] gkernel = GaussianKernel_ard(hyper) GP = PrefGaussianProcess(gkernel, prior=prior) X = [array([i + .5] * 4) for i in range(5)] valX = [x.copy() for x in X] prefs = [] for i in range(len(X)): for j in range(i): if S5.f(X[i]) > S5.f(X[j]): prefs.append((X[i], X[j], 0)) else: prefs.append((X[j], X[i], 0)) GP.addPreferences(prefs) opt, optx = maximizeEI(GP, S5.bounds)
def testShekelGPPrior(self): # see how the GP works on the Shekel function S5 = Shekel5() pX = lhcSample(S5.bounds, 100, seed=8) pY = [S5.f(x) for x in pX] prior = RBFNMeanPrior() prior.train(pX, pY, S5.bounds, k=10, seed=103) X = lhcSample(S5.bounds, 10, seed=9) Y = [S5.f(x) for x in X] hv = .1 hyper = [hv, hv, hv, hv] gkernel = GaussianKernel_ard(hyper) priorGP = GaussianProcess(gkernel, X, Y, prior=prior) nopriorGP = GaussianProcess(gkernel, X, Y) S = lhcSample(S5.bounds, 1000, seed=10) nopriorErr = mean([(S5.f(x)-nopriorGP.mu(x))**2 for x in S]) priorErr = mean([(S5.f(x)-priorGP.mu(x))**2 for x in S]) # print '\nno prior Err =', nopriorErr # print 'prior Err =', priorErr self.failUnless(priorErr < nopriorErr*.8)
def _testKernelMaxEI(self): # test different methods of optimizing kernel S5 = Shekel5() hv = 0.1 testkernels = [GaussianKernel_iso([hv]), GaussianKernel_ard([hv, hv, hv, hv]), MaternKernel3([hv, 1.0])] # MaternKernel5([hv, 1.0])] for kernel in testkernels: # print # print kernel.__class__ # train GPs X = lhcSample(S5.bounds, 10, seed=0) Y = [S5.f(x) for x in X] GP = GaussianProcess(kernel, X, Y) eif = EI(GP) dopt, doptx = direct(eif.negf, S5.bounds, maxiter=10) copt, coptx = cdirect(eif.negf, S5.bounds, maxiter=10) mopt, moptx = maximizeEI(GP, S5.bounds, maxiter=10) # print dopt, doptx # print copt, coptx # print mopt, moptx self.failUnlessAlmostEqual(dopt, copt, 4) self.failUnlessAlmostEqual(-dopt, mopt, 4) self.failUnlessAlmostEqual(-copt, mopt, 4) self.failUnless(sum(abs(doptx-coptx)) < .01) self.failUnless(sum(abs(moptx-coptx)) < .01) self.failUnless(sum(abs(moptx-doptx)) < .01) # train GP w/prior pX = lhcSample(S5.bounds, 100, seed=101) pY = [S5.f(x) for x in pX] prior = RBFNMeanPrior() prior.train(pX, pY, bounds=S5.bounds, k=10, seed=102) GP = GaussianProcess(kernel, X, Y, prior=prior) eif = EI(GP) pdopt, pdoptx = direct(eif.negf, S5.bounds, maxiter=10) pcopt, pcoptx = cdirect(eif.negf, S5.bounds, maxiter=10) pmopt, pmoptx = maximizeEI(GP, S5.bounds, maxiter=10) self.failIfAlmostEqual(pdopt, dopt, 3) self.failUnlessAlmostEqual(pdopt, pcopt, 4) self.failUnlessAlmostEqual(-pdopt, pmopt, 4) self.failUnlessAlmostEqual(-pcopt, pmopt, 4) self.failUnless(sum(abs(pdoptx-pcoptx)) < .01) self.failUnless(sum(abs(pmoptx-pcoptx)) < .01) self.failUnless(sum(abs(pmoptx-pdoptx)) < .01)
def testMaxEIPrior(self): # make sure that the prior works with the different methods of EI # maximization S5 = Shekel5() pX = lhcSample(S5.bounds, 100, seed=511) pY = [S5.f(x) for x in pX] prior = RBFNMeanPrior() prior.train(pX, pY, bounds=S5.bounds, k=10, seed=504) hv = .1 hyper = [hv, hv, hv, hv] kernel = GaussianKernel_ard(hyper) # train GPs X = lhcSample(S5.bounds, 10, seed=512) Y = [S5.f(x) for x in X] # validation valX = list(x.copy() for x in X) valY = copy(Y) GP = GaussianProcess(kernel, X, Y, prior=prior) eif = EI(GP) copt, _ = cdirect(eif.negf, S5.bounds, maxiter=20) mopt, _ = maximizeEI(GP, S5.bounds, maxiter=20) self.failUnlessAlmostEqual(-copt, mopt, 2) for i in xrange(len(GP.X)): self.failUnless(all(valX[i]==GP.X[i])) self.failUnless(valY[i]==GP.Y[i]) GP.prior.mu(GP.X[0]) self.failUnless(all(valX[0]==GP.X[0])) # print GP.X for i in xrange(len(GP.X)): self.failUnless(all(valX[i]==GP.X[i])) self.failUnless(valY[i]==GP.Y[i]) GP.prior.mu(GP.X[0]) self.failUnless(all(valX[0]==GP.X[0]))
def test1DcEI(self): f = lambda x: float(sin(x*5.)) X = lhcSample([[0., 1.]], 5, seed=22) Y = [f(x) for x in X] kernel = GaussianKernel_ard(array([1.0])) GP = GaussianProcess(kernel) GP.addData(X, Y) # should use optimizeGP.cpp maxei = maximizeEI(GP, [[0., 1.]]) if False: figure(1) plot(X, Y, 'ro') plot([x/100 for x in xrange(100)], [GP.ei(x/100) for x in xrange(100)]) plot(maxei[1][0], maxei[0], 'ko') show()
def test1DcUCB(self): f = lambda x: float(sin(x * 5.)) X = lhcSample([[0., 1.]], 5, seed=22) Y = [f(x) for x in X] kernel = GaussianKernel_ard(array([1.0])) GP = GaussianProcess(kernel) GP.addData(X, Y) # should use optimizeGP.cpp ucbf = UCB(GP, 1) dopt, doptx = direct(ucbf.negf, [[0., 1.]], maxiter=10) copt, coptx = cdirect(ucbf.negf, [[0., 1.]], maxiter=10) mopt, moptx = maximizeUCB(GP, [[0., 1.]], maxiter=10) self.failUnlessAlmostEqual(dopt, copt, 4) self.failUnlessAlmostEqual(-dopt, mopt, 4) self.failUnlessAlmostEqual(-copt, mopt, 4) self.failUnless(sum(abs(doptx - coptx)) < .01) self.failUnless(sum(abs(moptx - coptx)) < .01) self.failUnless(sum(abs(moptx - doptx)) < .01)
def demoObservations(): """ Simple demo for a scenario where we have direct observations (ie ratings or responses) with noise. The model has three parameters, but after initial training, we fix one to be 1.0 and optimize the other two. At each step, we visualize the posterior mean, variance and expected improvement. We then find the point of maximum expected improvement and ask the user for the scalar response value. To see how the model adapts to inputs, try rating the first few values higher or lower than predicted and see what happens to the visualizations. """ # the kernel parameters control the impact of different values on the # parameters. we are defining a model with three parameters kernel = GaussianKernel_ard(array([.5, .5, .3])) # we want to allow some noise in the observations -- the noise parameter # is the variance of the additive Gaussian noise Y + N(0, noise) noise = 0.1 # create the Gaussian Process using the kernel we've just defined GP = GaussianProcess(kernel, noise=noise) # add some data to the model. the data must have the same dimensionality # as the kernel X = [ array([1, 1.5, 0.9]), array([.8, -.2, -0.1]), array([2, .8, -.2]), array([0, 0, .5]) ] Y = [1, .7, .6, -.1] print 'adding data to model' for x, y in zip(X, Y): print '\tx = %s, y = %.1f' % (x, y) GP.addData(X, Y) # the GP.posterior(x) function returns, for x, the posterior distribution # at x, characterized as a normal distribution with mean mu, variance # sigma^2 testX = [array([1, 1.45, 1.0]), array([-10, .5, -10])] for tx in testX: mu, sig2 = GP.posterior(tx) print 'the posterior of %s is a normal distribution N(%.3f, %.3f)' % ( tx, mu, sig2) # now, let's find the best points to evaluate next. we fix the first # dimension to be 1 and for the others, we search the range [-2, 2] bound = [[1, 1], [-1.99, 1.98], [-1.99, 1.98]] figure(1, figsize=(5, 10)) while True: _, optx = maximizeEI(GP, bound, xi=.1) # visualize the mean, variance and expected improvement functions on # the free parameters x1 = arange(bound[1][0], bound[1][1], 0.1) x2 = arange(bound[2][0], bound[2][1], 0.1) X1, X2 = meshgrid(x1, x2) ei = zeros_like(X1) m = zeros_like(X1) v = zeros_like(X1) for i in xrange(X1.shape[0]): for j in xrange(X1.shape[1]): z = array([1.0, X1[i, j], X2[i, j]]) ei[i, j] = -EI(GP).negf(z) m[i, j], v[i, j] = GP.posterior(z) clf() for i, (func, title) in enumerate( ([m, 'prediction (posterior mean)' ], [v, 'uncertainty (posterior variance)'], [ei, 'utility (expected improvement)'])): ax = subplot(3, 1, i + 1) cs = ax.contourf(X1, X2, func, 20) ax.plot(optx[1], optx[2], 'wo') colorbar(cs) ax.set_title(title) ax.set_xlabel('x[1]') ax.set_ylabel('x[2]') ax.set_xticks([-2, 0, 2]) ax.set_yticks([-2, 0, 2]) show() m, v = GP.posterior(optx) try: response = input( '\nmaximum expected improvement is at parameters x = [%.3f, %.3f, %.3f], where mean is %.3f, variance is %.3f. \nwhat is the value there (non-numeric to quit)? ' % (optx[0], optx[1], optx[2], m, v)) except: break GP.addData(optx, response) print 'updating model.'