1.2. Approximation

1.2.1. Introduction

This example shows how to use pSeven Core to approximate the Branin function:

\begin{eqnarray} &y(x_1, x_2) = a \cdot (x_2 - b \cdot x_1^2 + c \cdot x_1 - d)^2 + e \cdot (1 - f) \cdot cos(x_1) + e \\ &a = 1, ~ b = 5.1/(4\pi^2), ~ c = 5/\pi, ~ d = 6, ~ e = 10, ~ f=1/(8\pi) \\ &-5 \leq x_1 \leq 10 \\ &0 \leq x_2 \leq 15 \end{eqnarray}

Start by importing the Generic Tool for Approximation (GTApprox) module:

from da.p7core import gtapprox

1.2.2. Model Training

At first, define the branin() function:

import numpy as np

def branin(x):
  a = 1.0
  b = 5.1 / (4.0*(np.pi**2))
  c = 5.0 / np.pi
  d = 6.0
  e = 10.0
  f = 1.0 / (8.0*np.pi)
  return np.array(a * (x[:, 1] - b * (x[:, 0]**2) + c * x[:, 0] - d)**2 + e * (1.0 - f) * np.cos(x[:,0]) + e)

Generate a training sample:

import numpy as np
x_sample = np.hstack((15.0*np.random.rand(100, 1)-5.0, 15.0*np.random.rand(100, 1)))
y_sample = branin(x_sample)

Create the approximation model builder (a gtapprox.Builder instance):

builder = gtapprox.Builder()

You can tune the approximator by setting builder options (see Options Interface). For example, enable accuracy evaluation (AE). AE is a GTApprox feature, which purpose is to estimate model accuracy at different points of the design space.

builder.options.set('GTApprox/AccuracyEvaluation', 'on')

If you want to get information from the model builder during training, set a logger (see Loggers). For simple logging you can use the default StreamLogger, which prints to the standard output. Its default verbosity level is INFO, which includes all messages except detailed debug information.

from da.p7core import loggers

logger = loggers.StreamLogger()
builder.set_logger(logger)

You can also add a watcher with set_watcher(). A watcher is a callable object which receives messages from the builder. You can implement a custom watcher (see Watchers) and use it to interrupt training: if your watcher returns False under some condition, training stops. For this example, use the default watcher, which always returns True and never interrupts the process:

from da.p7core import watchers

watcher = watchers.DefaultWatcher()
builder.set_watcher(watcher)

Finally, start training the model using the configured builder and the training sample generated earlier:

model = builder.build(x_sample, y_sample)

1.2.3. Using the Model

Trained model returned by build() is a gtapprox.Model instance — see its description for full details. This section shows basic model usage.

Print a readable model summary:

print(model)

Save the model and reload it from disk:

model.save('branin_model.gtapprox')
loaded_model = gtapprox.Model('branin_model.gtapprox')

Get model’s prediction at some point (evaluate the model):

point = [2.5, 7.5]
m_calc = model.calc(point)

Calculate model gradient:

m_grad = model.grad(point)

Get an estimate of model’s error at some point (AE):

m_ae = model.calc_ae(point)

Get the actual model error at a reference point to compare it with AE:

m_err = m_calc - branin(np.array([point]))

1.2.4. Full Example Code

import numpy as np

from da.p7core import gtapprox
from da.p7core import loggers
from da.p7core import watchers

def branin(x):
  a = 1.0
  b = 5.1 / (4.0*(np.pi**2))
  c = 5.0 / np.pi
  d = 6.0
  e = 10.0
  f = 1.0 / (8.0*np.pi)
  return np.array(a * (x[:, 1] - b * (x[:, 0]**2) + c * x[:, 0] - d)**2 + e * (1.0 - f) * np.cos(x[:,0]) + e)

x_sample = np.hstack((15.0*np.random.rand(100, 1)-5.0, 15.0*np.random.rand(100, 1)))
y_sample = branin(x_sample)

builder = gtapprox.Builder()

builder.options.set('GTApprox/AccuracyEvaluation', 'on')
logger = loggers.StreamLogger()
builder.set_logger(logger)
watcher = watchers.DefaultWatcher()
builder.set_watcher(watcher)

print('\n'+'='*80+'\n')
model = builder.build(x_sample, y_sample)

print('\n'+'='*80+'\n')
print(model)
model.save('branin_model.gtapprox')
loaded_model = gtapprox.Model('branin_model.gtapprox')

point = [2.5, 7.5]
m_calc = model.calc(point)
m_grad = model.grad(point)
m_ae = model.calc_ae(point)
m_err = m_calc - branin(np.array([point]))

print('\n'+'='*80+'\n')
print("Model prediction at %s: %s" % (point, m_calc))
print("Model gradient at %s: %s" % (point, m_grad))
print("Model accuracy evaluation at %s: %s" % (point, m_ae))
print("Actual model error at %s: %s" % (point, m_err))