def test_opt():
    space = DesignSpace().parse([{
        'name': 'x1',
        'type': 'num',
        'lb': -3.0,
        'ub': 3.0
    }])
    acq = ToyExample()
    opt = EvolutionOpt(space, acq, pop=10)
    rec = opt.optimize(initial_suggest=space.sample(3))
    x, xe = space.transform(rec)
    assert (approx(1.0, 1e-3) == acq(x, xe)[:, 0].squeeze().item())
def test_opt_int():
    space = DesignSpace().parse([{
        'name': 'x1',
        'type': 'num',
        'lb': -3.0,
        'ub': 3.0
    }, {
        'name': 'x2',
        'type': 'int',
        'lb': -3.0,
        'ub': 3.0
    }])
    acq = ToyExample()
    opt = EvolutionOpt(space, acq, pop=10)
    rec = opt.optimize()
    assert (approx(1.0,
                   1e-3) == acq(*space.transform(rec))[:, 0].squeeze().item())
Example #3
0
def test_contextual_opt(opt_cls):
    space = DesignSpace().parse([
        {'name' : 'x0', 'type' : 'int', 'lb' : 0, 'ub' : 7},
        {'name' : 'x1', 'type' : 'int', 'lb' : 0, 'ub' : 7},
        ])
    opt = opt_cls(space, rand_sample = 2, model_name = 'rf')
    for i in range(2):
        n_suggestions = 8 if opt.support_parallel_opt else 1
        rec = opt.suggest(n_suggestions = n_suggestions, fix_input = {'x0' : 3})
        y   = (rec[['x0', 'x1']].values ** 2).sum(axis = 1, keepdims =True)
        assert((rec['x0'] == 3).all())
        opt.observe(rec, y)
Example #4
0
def parse_space_from_bayesmark(api_config) -> DesignSpace:
    """
    Parse design space of bayesmark (https://github.com/uber/bayesmark)
    """
    space  = DesignSpace()
    params = []
    for param_name in api_config:
        param_conf   = api_config[param_name]
        param_type   = param_conf['type']
        param_space  = param_conf.get('space', None)
        param_range  = param_conf.get("range", None)
        param_values = param_conf.get("values", None)

        bo_param_conf = {'name' : param_name}
        if param_type == 'int': # ignore 'log' space # TODO: support log-scale int
            bo_param_conf['type'] = 'int'
            bo_param_conf['lb']   = param_range[0]
            bo_param_conf['ub']   = param_range[1]
        elif param_type == 'bool':
            bo_param_conf['type'] = 'bool'
        elif param_type in ('cat', 'ordinal'):
            bo_param_conf['type']       = 'cat'
            bo_param_conf['categories'] = list(set(param_values))
        elif param_type == 'real':
            if param_space in ('log', 'logit'):
                bo_param_conf['type'] = 'pow'
                bo_param_conf['base'] = 10
                bo_param_conf['lb']   = param_range[0]
                bo_param_conf['ub']   = param_range[1]
            else:
                bo_param_conf['type'] = 'num'
                bo_param_conf['lb']   = param_range[0]
                bo_param_conf['ub']   = param_range[1]
        else:
            assert False, "type %s not handled in API" % param_type
        params.append(bo_param_conf)
    space.parse(params)
    return space
Example #5
0
def test_opt(model_name, opt_cls):
    space = DesignSpace().parse([
        {'name' : 'x0', 'type' : 'num', 'lb' : -3, 'ub' : 7},
        {'name' : 'x1', 'type' : 'cat', 'categories' : ['a', 'b', 'c']}
        ])
    opt = opt_cls(space, rand_sample = 10, model_name = model_name)
    for i in range(11):
        num_suggest = 8 if opt.support_parallel_opt else 1
        rec = opt.suggest(n_suggestions = num_suggest)
        y   = obj(rec)
        if y.shape[0] > 1 and i > 0:
            y[np.argmax(y.reshape(-1))] = np.inf
        opt.observe(rec, y)
        if opt.y.shape[0] > 11:
            break
def test_mo():
    space = DesignSpace().parse([{
        'name': 'x1',
        'type': 'num',
        'lb': -3.0,
        'ub': 3.0
    }, {
        'name': 'x2',
        'type': 'int',
        'lb': -3.0,
        'ub': 3.0
    }])
    acq = ToyExampleMO()
    opt = EvolutionOpt(space, acq, pop=10)
    rec = opt.optimize()
    assert (rec.shape[0] == 10)
def test_opt_fix():
    space = DesignSpace().parse([{
        'name': 'x1',
        'type': 'num',
        'lb': -3.0,
        'ub': 3.0
    }, {
        'name': 'x2',
        'type': 'num',
        'lb': -3.0,
        'ub': 3.0
    }])
    acq = ToyExample()
    opt = EvolutionOpt(space, acq, pop=10)
    rec = opt.optimize(fix_input={'x1': 1.0})
    print(rec)
    assert (rec['x1'].values == approx(1.0, 1e-3))
def test_design_space():
    space = DesignSpace().parse([{
        'name': 'x0',
        'type': 'num',
        'lb': 0,
        'ub': 7
    }, {
        'name': 'x1',
        'type': 'int',
        'lb': 0,
        'ub': 7
    }, {
        'name': 'x2',
        'type': 'pow',
        'lb': 1e-4,
        'ub': 1e-2,
        'base': 10
    }, {
        'name': 'x3',
        'type': 'cat',
        'categories': ['a', 'b', 'c']
    }, {
        'name': 'x4',
        'type': 'bool'
    }])
    assert space.numeric_names == ['x0', 'x1', 'x2', 'x4']
    assert space.enum_names == ['x3']
    assert space.num_paras == 5
    assert space.num_numeric == 4
    assert space.num_categorical == 1

    samp = space.sample(10)
    x, xe = space.transform(samp)
    x_, xe_ = space.transform(space.inverse_transform(x, xe))
    assert (x - x_).abs().max() < 1e-4

    assert (space.opt_lb <= space.opt_ub).all()

    assert not space.paras['x0'].is_discrete
    assert space.paras['x1'].is_discrete
    assert not space.paras['x2'].is_discrete
    assert space.paras['x3'].is_discrete
    assert space.paras['x4'].is_discrete
Example #9
0
    dir_list.sort()

    #  [t_lateral_f, left_right_rim_res, left_rim_f, four_side_rim_res, four_side_rim_latf, angvel]  [5,]
    param_list = [{
        'name': 'res',
        'type': 'num',
        'lb': .5,
        'ub': .95
    }, {
        'name': 'f',
        'type': 'num',
        'lb': 0.,
        'ub': .8
    }]
    np.random.seed(99)
    space = DesignSpace().parse(param_list)
    opt = HEBO(space)

    # init value
    rec = pd.DataFrame({
        'res': [.9, .7, .95, .59, .67, .75, .62, .8],
        'f': [.1, .3, .45, .6, .01, .4, .6, .7]
    })

    data = []

    objs = []
    params = []
    n_sugg = 15
    fileHeader = ["iters", "res", "f", "objs"]
    with open(
Example #10
0
def test_cond(output_noise, rand_prior, num_processes):
    space = DesignSpace().parse([
        {
            'name': 'param_A',
            'type': 'bool'
        },
        {
            'name': 'param_B',
            'type': 'num',
            'lb': 0,
            'ub': 1
        },
        {
            'name': 'param_C',
            'type': 'num',
            'lb': 0,
            'ub': 1
        },
        {
            'name': 'param_D',
            'type': 'num',
            'lb': 0,
            'ub': 1
        },
        {
            'name': 'param_A2',
            'type': 'cat',
            'categories': ['a', 'b', 'c']
        },
        {
            'name': 'param_B2',
            'type': 'num',
            'lb': 0,
            'ub': 1
        },
    ])
    X = space.sample(50)
    y = torch.randn(50, 1)
    cond = {
        'param_A': None,
        'param_B': ('param_A', True),
        'param_C': ('param_A', True),
        'param_D':
        ('param_A',
         [True]),  # XXX: enable value could be scaler value or list of values
        'param_A2': None,
        'param_B2': ('param_A2', ['a'])
    }
    model = ConditionalDeepEnsemble(4,
                                    0,
                                    1,
                                    space,
                                    cond,
                                    num_epoch=1,
                                    rand_prior=rand_prior,
                                    num_processes=num_processes,
                                    output_noise=output_noise)
    model.fit(*space.transform(X), y)
    model.fit(*space.transform(X), y)  # test warm-starting

    with torch.no_grad():
        py, ps2 = model.predict(*space.transform(X))
        disabled = ((X.param_A == False) & (X.param_A2 != 'a')).values
        assert (py[disabled].var() == approx(0., abs=1e-4))
Example #11
0
def sklearn_tuner(model_class,
                  space_config: [dict],
                  X: np.ndarray,
                  y: np.ndarray,
                  metric: Callable,
                  greater_is_better: bool = True,
                  n_splits=5,
                  max_iter=16,
                  report=False) -> (dict, pd.DataFrame):
    """Tuning sklearn estimator

    Parameters:
    -------------------
    model_class: class of sklearn estimator
    space_config: list of dict, specifying search space
    X, y: data used to for cross-valiation
    metrics: metric function in sklearn.metrics
    greater_is_better: whether a larger metric value is better
    n_splits: split data into `n_splits` parts for cross validation
    max_iter: number of trials

    Returns:
    -------------------
    Best hyper-parameters and all visited data


    Example:
    -------------------
    from sklearn.datasets import load_boston
    from sklearn.ensemble import RandomForestRegressor
    from sklearn.metrics import r2_score, mean_squared_error
    from bo.sklearn_tuner import sklearn_tuner

    space_cfg = [
            {'name' : 'max_depth',        'type' : 'int', 'lb' : 1, 'ub' : 20},
            {'name' : 'min_samples_leaf', 'type' : 'num', 'lb' : 1e-4, 'ub' : 0.5},
            {'name' : 'max_features',     'type' : 'cat', 'categories' : ['auto', 'sqrt', 'log2']},
            {'name' : 'bootstrap',        'type' : 'bool'},
            {'name' : 'min_impurity_decrease', 'type' : 'pow', 'lb' : 1e-4, 'ub' : 1.0},
            ]
    X, y   = load_boston(return_X_y = True)
    result = sklearn_tuner(RandomForestRegressor, space_cfg, X, y, metric = r2_score, max_iter = 16)
    """
    space = DesignSpace().parse(space_config)
    opt = HEBO(space)
    for i in range(max_iter):
        rec = opt.suggest()
        model = model_class(**rec.iloc[0].to_dict())
        pred = cross_val_predict(model,
                                 X,
                                 y,
                                 cv=KFold(n_splits=n_splits, shuffle=True))
        score_v = metric(y, pred)
        sign = -1. if greater_is_better else 1.0
        opt.observe(rec, np.array([sign * score_v]))
        print('Iter %d, best metric: %g' % (i, sign * opt.y.min()))
    best_id = np.argmin(opt.y.reshape(-1))
    best_hyp = opt.X.iloc[best_id]
    df_report = opt.X.copy()
    df_report['metric'] = sign * opt.y
    if report:
        return best_hyp.to_dict(), df_report
    else:
        return best_hyp.to_dict()