AIworx-Labs / chocolate

A fully decentralized hyperparameter optimization framework
http://chocolate.readthedocs.io
BSD 3-Clause "New" or "Revised" License
120 stars 41 forks source link

ValueError for Bayesian .next() #21

Closed Bacoknight closed 5 years ago

Bacoknight commented 5 years ago

Hi,

I'm currently trying to used Bayesian optimisation through Chocolate, but I get an inconsistent error on the first iteration. When first calling .next() on the chocolate.Bayes object, I get the following error:

  File "c:\Users\tests.py", line 252, in StatsBayes
    token, nextParams = solver.next()
  File "C:\Users\Anaconda3\lib\site-packages\chocolate\base.py", line 159, in next
    return self._next()
  File "C:\Users\Anaconda3\lib\site-packages\chocolate\search\bayes.py", line 58, in _next
    gp, y = self._fit_gp(X, Xpending, y)
  File "C:\Users\Anaconda3\lib\site-packages\chocolate\search\bayes.py", line 73, in _fit_gp
    gp.fit(X, y)
  File "C:\Users\Anaconda3\lib\site-packages\sklearn\gaussian_process\gpr.py", line 196, in fit
    X, y = check_X_y(X, y, multi_output=True, y_numeric=True)
  File "C:\Users\Anaconda3\lib\site-packages\sklearn\utils\validation.py", line 756, in check_X_y
    estimator=estimator)
  File "C:\Users\Anaconda3\lib\site-packages\sklearn\utils\validation.py", line 552, in check_array
    "if it contains a single sample.".format(array))
ValueError: Expected 2D array, got 1D array instead:
array=[].
Reshape your data either using array.reshape(-1, 1) if your data has a single feature or array.reshape(1, -1) if it contains a single sample.

Should I be instantiating the model with an initial guess? The examples don't seem to suggest this.

Bacoknight commented 5 years ago

I have managed to reproduce the error by modifying the example code. Is it because this is a 1D function? Here is the code:

import chocolate as choco

numIters = 2

def objective_function(condition, x=None, y=1):
    """An objective function returning ``1 - x`` when *condition* is 1 and 
    ``y - 6`` when *condition* is 2.

    Raises:
        ValueError: If condition is different than 1 or 2.
    """
    if condition == 1:
        return 1 - x
    elif condition == 2:
        return y - 6
    raise ValueError("condition must be 1 or 2, got {}.".format(condition))

# Define the conditional search space 
space = [
            {"condition": 1, "x": choco.uniform(low=1, high=10)},
            #{"condition": 2, "y": choco.log(low=-2, high=2, base=10)}
        ]

# Establish a connection to a SQLite local database
conn = choco.SQLiteConnection("sqlite:///my_db.db")

# Construct the optimizer
sampler = choco.Bayes(conn, space, utility_function = "ei", n_bootstrap = int(numIters/10), clear_db = True)

# Sample the next point
token, params = sampler.next()

# Calculate the loss for the sampled point (minimized)
loss = objective_function(**params)

# Add the loss to the database
sampler.update(token, loss)
Bacoknight commented 5 years ago

Another update: I think it may have something to do with n_bootstrap value. Since it is 0 in this example, there is no data in the database (if I delete it). The error then shows up. If it set it to something non-zero, it seems to work okay. I don't know if there's any other reasons you could think of so I'll leave this open for now.

leconteur commented 5 years ago

You're right about the cause of the error. Is there a reason why you need a bootstrap value of 0?

Bacoknight commented 5 years ago

No, it was just an unfortunate concequence of some other parameters in my program changing (namely numIters).

Thanks anyway!

leconteur commented 5 years ago

I'll add a check in the constructor so it is easier to catch in the future. Thank you!