예제 #1
0
    def from_config(cls, config: Config) -> GPClassificationModel:
        """Alternate constructor for GPClassification model.

        This is used when we recursively build a full sampling strategy
        from a configuration. TODO: document how this works in some tutorial.

        Args:
            config (Config): A configuration containing keys/values matching this class

        Returns:
            GPClassificationModel: Configured class instance.
        """

        classname = cls.__name__
        inducing_size = config.getint(classname, "inducing_size", fallback=10)

        lb = config.gettensor(classname, "lb")
        ub = config.gettensor(classname, "ub")
        dim = config.getint(classname, "dim", fallback=None)

        mean_covar_factory = config.getobj(classname,
                                           "mean_covar_factory",
                                           fallback=default_mean_covar_factory)

        mean, covar = mean_covar_factory(config)
        max_fit_time = config.getfloat(classname,
                                       "max_fit_time",
                                       fallback=None)

        inducing_point_method = config.get(classname,
                                           "inducing_point_method",
                                           fallback="auto")

        likelihood_cls = config.getobj(classname, "likelihood", fallback=None)

        if likelihood_cls is not None:
            if hasattr(likelihood_cls, "from_config"):
                likelihood = likelihood_cls.from_config(config)
            else:
                likelihood = likelihood_cls()
        else:
            likelihood = None  # fall back to __init__ default

        return cls(
            lb=lb,
            ub=ub,
            dim=dim,
            inducing_size=inducing_size,
            mean_module=mean,
            covar_module=covar,
            max_fit_time=max_fit_time,
            inducing_point_method=inducing_point_method,
            likelihood=likelihood,
        )
예제 #2
0
    def from_config(cls, config: Config, name: str):
        gen_cls = config.getobj(name, "generator", fallback=SobolGenerator)
        generator = gen_cls.from_config(config)

        model_cls = config.getobj(name, "model", fallback=None)
        if model_cls is not None:
            model = model_cls.from_config(config)
        else:
            model = None

        acqf_cls = config.getobj(name, "acqf", fallback=None)
        if acqf_cls is not None and hasattr(generator, "acqf"):
            if generator.acqf is None:
                generator.acqf = acqf_cls
                generator.acqf_kwargs = generator._get_acqf_options(
                    acqf_cls, config)

        n_trials = config.getint(name, "n_trials")
        refit_every = config.getint(name, "refit_every", fallback=1)

        lb = config.gettensor(name, "lb")
        ub = config.gettensor(name, "ub")
        dim = config.getint(name, "dim", fallback=None)

        outcome_type = config.get(name,
                                  "outcome_type",
                                  fallback="single_probit")

        if model is not None and not generator._requires_model:
            if refit_every < n_trials:
                warnings.warn(
                    f"Strategy '{name}' has refit_every < n_trials even though its generator does not require a model. Consider making refit_every = n_trials to speed up point generation.",
                    RuntimeWarning,
                )

        return cls(
            lb=lb,
            ub=ub,
            dim=dim,
            model=model,
            generator=generator,
            n_trials=n_trials,
            refit_every=refit_every,
            outcome_type=outcome_type,
        )
예제 #3
0
def default_mean_covar_factory(
    config: Config,
) -> Tuple[gpytorch.means.ConstantMean, gpytorch.kernels.ScaleKernel]:
    """Default factory for generic GP models

    Args:
        config (Config): Object containing bounds (and potentially other
            config details).

    Returns:
        Tuple[gpytorch.means.Mean, gpytorch.kernels.Kernel]: Instantiated
            ConstantMean and ScaleKernel with priors based on bounds.
    """

    lb = config.gettensor("default_mean_covar_factory", "lb")
    ub = config.gettensor("default_mean_covar_factory", "ub")
    fixed_mean = config.getboolean("default_mean_covar_factory",
                                   "fixed_mean",
                                   fallback=False)
    lengthscale_prior = config.get("default_mean_covar_factory",
                                   "lengthscale_prior",
                                   fallback="gamma")
    outputscale_prior = config.get("default_mean_covar_factory",
                                   "outputscale_prior",
                                   fallback="box")
    kernel = config.getobj("default_mean_covar_factory",
                           "kernel",
                           fallback=gpytorch.kernels.RBFKernel)

    assert lb.shape[0] == ub.shape[0], "bounds shape mismatch!"
    dim = lb.shape[0]
    mean = gpytorch.means.ConstantMean()

    if fixed_mean:
        try:
            target = config.getfloat("default_mean_covar_factory", "target")
            mean.constant.requires_grad_(False)
            mean.constant.copy_(torch.tensor([norm.ppf(target)]))
        except NoOptionError:
            raise RuntimeError(
                "Config got fixed_mean=True but no target included!")

    if lengthscale_prior == "invgamma":

        ls_prior = gpytorch.priors.GammaPrior(
            concentration=__default_invgamma_concentration,
            rate=__default_invgamma_rate,
            transform=lambda x: 1 / x,
        )

        ls_prior_mode = ls_prior.rate / (ls_prior.concentration + 1)
    elif lengthscale_prior == "gamma":
        ls_prior = gpytorch.priors.GammaPrior(concentration=3.0, rate=6.0)
        ls_prior_mode = (ls_prior.concentration - 1) / ls_prior.rate
    else:
        raise RuntimeError(
            f"Lengthscale_prior should be invgamma or gamma, got {lengthscale_prior}"
        )

    if outputscale_prior == "gamma":
        os_prior = gpytorch.priors.GammaPrior(concentration=2.0, rate=0.15)
    elif outputscale_prior == "box":
        os_prior = gpytorch.priors.SmoothedBoxPrior(a=1, b=4)
    else:
        raise RuntimeError(
            f"Outputscale_prior should be gamma or box, got {outputscale_prior}"
        )

    ls_constraint = gpytorch.constraints.Positive(transform=None,
                                                  initial_value=ls_prior_mode)

    covar = gpytorch.kernels.ScaleKernel(
        kernel(
            lengthscale_prior=ls_prior,
            lengthscale_constraint=ls_constraint,
            ard_num_dims=dim,
        ),
        outputscale_prior=os_prior,
    )

    return mean, covar