Skip to content

Commit

Permalink
finish revising docs/wiki/4_SurrogateModel.md to make sure all exampl…
Browse files Browse the repository at this point in the history
…es are runnable and all statements are correct
  • Loading branch information
xuyuting committed Aug 15, 2024
1 parent e0699cb commit ea6ae06
Showing 1 changed file with 103 additions and 72 deletions.
175 changes: 103 additions & 72 deletions docs/wiki/4_SurrogateModel.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,133 +4,164 @@

The `obsidian.surrogates` submodule is a key component of the Obsidian Bayesian optimization library. It provides a collection of surrogate models used to approximate the objective function in the optimization process. These surrogate models are essential for efficient exploration of the parameter space and for making informed decisions about which points to evaluate next.

## 2. Available Surrogate Models
## 2. How to Use Surrogate Models - Basic Syntax

The `obsidian.surrogates` submodule offers several types of surrogate models:
To use a surrogate model in your optimization process, you typically don't need to interact with it directly. The `obsidian.optimizer` submodule will handle the creation and management of the surrogate model. However, if you need to create a surrogate model manually, you can do so using the `SurrogateBoTorch` class.

1. **Gaussian Process (GP)**: The default surrogate model, suitable for most optimization tasks.
2. **Mixed Gaussian Process (MixedGP)**: A GP model that can handle mixed continuous and categorical input spaces.
3. **Deep Kernel Learning GP (DKL)**: A GP model with a neural network feature extractor.
4. **Flat GP**: A GP model with non-informative or no prior distributions.
5. **Prior GP**: A GP model with custom prior distributions.
6. **Multi-Task GP (MTGP)**: A GP model for multi-output optimization.
7. **Deep Neural Network (DNN)**: A dropout neural network model.
Below is a simple example using the default standard GP surrogate:

## 3. How to Use Surrogate Models

To use a surrogate model in your optimization process, you typically don't need to interact with it directly. The Obsidian optimizer will handle the creation and management of the surrogate model. However, if you need to create a surrogate model manually, you can do so using the `SurrogateBoTorch` class:
### Define the parameter space:
```python
from obsidian.parameters import ParamSpace, Param_Continuous
params = ParamSpace([Param_Continuous('X1', 0, 1),Param_Continuous('X2', 0, 1)])
X_space = ParamSpace(params)
```

### Simulate training data:
```python
from obsidian.surrogates import SurrogateBoTorch
from obsidian.parameters import ParamSpace, Target
from obsidian.experiment import ExpDesigner
designer = ExpDesigner(X_space, seed = 789)
X_train = designer.initialize(m_initial = 10, method='Sobol')

# Define your parameter space
param_space = ParamSpace([...]) # Define your parameters here
from obsidian.parameters import Target
target = Target(name = 'Y', f_transform = 'Standard', aim='max')

# Create a surrogate model (default is GP)
surrogate = SurrogateBoTorch(model_type='GP')
from obsidian.experiment import Simulator
from obsidian.experiment.benchmark import paraboloid
simulator = Simulator(X_space, paraboloid, name='Y')
y_train = simulator.simulate(X_train)
y_train_transformed = target.transform_f(y_train, fit = True)

# Fit the model to your data
surrogate.fit(X, y)
import pandas as pd
print(pd.concat([X_train, y_train_transformed], axis=1).to_markdown())
```

# Make predictions
| | X1 | X2 | Y Trans |
|---:|---------:|----------:|----------:|
| 0 | 0.709874 | 0.891838 | -0.692069 |
| 1 | 0.316783 | 0.0374523 | -1.283 |
| 2 | 0.102254 | 0.517022 | -0.229447 |
| 3 | 0.99438 | 0.412149 | -1.33756 |
| 4 | 0.80163 | 0.663557 | 0.252902 |
| 5 | 0.162435 | 0.265744 | -0.351742 |
| 6 | 0.385264 | 0.788242 | 0.507141 |
| 7 | 0.523473 | 0.140918 | 0.113744 |
| 8 | 0.588516 | 0.604981 | 1.423 |
| 9 | 0.445465 | 0.465715 | 1.59703 |


### Create a surrogate model (using the default 'GP' model), and fit the model to the training data:
```python
from obsidian.surrogates import SurrogateBoTorch
surrogate = SurrogateBoTorch(model_type='GP', seed = 123)
surrogate.fit(X_train, y_train_transformed,cat_dims=[],task_feature=None)
```

### Generate new input experimental conditions and make predictions:
```python
X_new = designer.initialize(m_initial = 3, method='Sobol')
mean, std = surrogate.predict(X_new)

df = X_new.assign(pred_mean=mean,pred_std=std)
print(df.to_markdown())
```

## 4. Customization Options
| | X1 | X2 | pred_mean | pred_std |
|---:|---------:|----------:|------------:|-----------:|
| 0 | 0.709874 | 0.891838 | -0.669406 | 0.120078 |
| 1 | 0.316783 | 0.0374523 | -1.25515 | 0.119587 |
| 2 | 0.102254 | 0.517022 | -0.217739 | 0.12007 |


### 4.1 Model Selection
## 3. Customization Options

You can choose different surrogate models by specifying the `model_type` parameter when creating a `SurrogateBoTorch` instance. Available options are:
### 3.1 Available Surrogate Models

- `'GP'`: Standard Gaussian Process
- `'MixedGP'`: Mixed input Gaussian Process
- `'DKL'`: Deep Kernel Learning GP
- `'GPflat'`: Flat (non-informative prior) GP
- `'GPprior'`: Custom prior GP
- `'MTGP'`: Multi-Task GP
- `'DNN'`: Dropout Neural Network
The `obsidian.surrogates` submodule offers several types of surrogate models.
You can choose different surrogate models by specifying the `model_type` parameter when creating a `SurrogateBoTorch` instance.
Available options are:

### 4.2 Hyperparameters
- `'GP'`: Standard Gaussian Process, which is the default surrogate model suitable for most optimization tasks.
- `'MixedGP'`: Mixed input Gaussian Process, which is a GP model that can handle mixed continuous and categorical input spaces.
- `'DKL'`: Deep Kernel Learning GP, which is a GP model with a neural network feature extractor.
- `'GPflat'`: A GP model with non-informative or no prior distributions.
- `'GPprior'`: A GP model with custom prior distributions.
- `'MTGP'`: Multi-Task GP, which is a GP model for multi-output optimization.
- `'DNN'`: Dropout Neural Network model.

You can pass custom hyperparameters to the surrogate model using the `hps` parameter:
### 3.2 Hyperparameters

You can pass custom hyperparameters to the surrogate model using the `hps` argument as:
> surrogate = SurrogateBoTorch(model_type='GP', hps={'custom_param_1': value_1, 'custom_param_2': value_2, ...})
Some specific examples:
```python
surrogate = SurrogateBoTorch(model_type='GP', hps={'your_custom_param': value})
surrogate = SurrogateBoTorch(model_type='FlatGP', hps={'nu': 1.5})
surrogate = SurrogateBoTorch(model_type='DNN', hps={'p_dropout': 0.1, 'h_width': 15, 'h_layers': 4, 'num_outputs': 2})
```

### 4.3 Custom GP Models
### 3.3 Custom GP Models

The submodule provides several custom GP implementations:

- `PriorGP`: A GP with custom prior distributions
- `FlatGP`: A GP with non-informative or no prior distributions
- `DKLGP`: A GP with a neural network feature extractor

### 4.4 Custom Neural Network Model

The `DNN` class provides a customizable dropout neural network model. You can adjust parameters such as dropout probability, hidden layer width, and number of hidden layers.

## 5. Examples

### 5.1 Using a standard GP surrogate

```python
from obsidian.surrogates import SurrogateBoTorch
from obsidian.parameters import ParamSpace, Target
import pandas as pd

# Define your parameter space
param_space = ParamSpace([...]) # Define your parameters here
### 3.4 Custom Neural Network Model

# Assume X and y are your input features and target variables
X = pd.DataFrame(...)
y = pd.Series(...)
The `DNN` class provides a customizable dropout neural network model.
The 'hps' parameter allows you to customize the DNN architecture.
You can adjust multiple DNN hyperparameters such as dropout probability, hidden layer width, and number of hidden layers.

surrogate = SurrogateBoTorch(model_type='GP')
surrogate.fit(X, y)
## 4. Additional Examples

# Make predictions
X_new = pd.DataFrame(...)
mean, std = surrogate.predict(X_new)
```

### 5.2 Using a Mixed GP for categorical and continuous variables
### 4.1 Using a Mixed GP for categorical and continuous variables

```python
# DO NOT RUN
surrogate = SurrogateBoTorch(model_type='MixedGP')
# cat_dims should be a list of indices for categorical variables in your input space
surrogate.fit(X, y, cat_dims=[0, 2]) # Assuming columns 0 and 2 are categorical
```

### 5.3 Using a DNN surrogate
### 4.2 Using a DNN surrogate

```python
# The 'hps' parameter allows you to customize the DNN architecture
surrogate = SurrogateBoTorch(model_type='DNN', hps={'p_dropout': 0.1, 'h_width': 32, 'h_layers': 3})
surrogate.fit(X, y)
surrogate.fit(X_train, y_train_transformed,cat_dims=[],task_feature=None)
```

## 6. Advanced Usage
## 5. Advanced Usage

### 6.1 Saving and Loading Models
### 5.1 Saving and Loading Models

You can save and load surrogate models using the `save_state()` and `load_state()` methods:
You can save and load surrogate models to/from dictionary objects using the `save_state()` and `load_state()` methods,
which enable saving the trained model to json files and reload for future usage:

```python
# Save model state
state = surrogate.save_state()
import json

# Save model state as dictionary to json file
with open('surrogate.json', 'w') as f:
surrogate_dict = surrogate.save_state()
json.dump(surrogate_dict, f)

# Load model state
loaded_surrogate = SurrogateBoTorch.load_state(state)
# Load model state dictionary from json file
with open('surrogate.json', 'r') as f:
surrogate_dict = json.load(f)
surrogate_reload = SurrogateBoTorch.load_state(surrogate_dict)
```

### 6.2 Model Evaluation
### 5.2 Model Evaluation

You can evaluate the performance of a surrogate model using the `score()` method:

```python
loss, r2_score = surrogate.score(X_test, y_test)
y_new = simulator.simulate(X_new)
y_new_transformed = target.transform_f(y_new, fit = False)
loss, r2_score = surrogate.score(X_new, y_new_transformed)
```

This concludes the user guide for the `obsidian.surrogates` submodule. For more detailed information, please refer to the source code and docstrings in the individual files.

0 comments on commit ea6ae06

Please sign in to comment.