Add TL override path to new GP factory - #868
Conversation
There was a problem hiding this comment.
Pull request overview
Adds an explicit transfer-learning override on TaskParameter and updates the GP surrogate’s kernel resolution to honor that override by dispatching between IndexKernel and PositiveIndexKernel, including new error types and test coverage updates.
Changes:
- Introduce
TransferLearningModeandTaskParameter.override_transfer_learning_modeto explicitly select the task kernel type. - Add override-aware kernel resolution in
GaussianProcessSurrogate(including task-kernel attachment and incompatibility handling). - Harden reduced-searchspace behavior with a dedicated
AttributeErrorsubclass and extend tests/strategies accordingly.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
baybe/surrogates/gaussian_process/core.py |
Implements override-aware kernel dispatch/assembly and adds kernel-stripping helper. |
baybe/parameters/categorical.py |
Adds TaskParameter.override_transfer_learning_mode field. |
baybe/parameters/enum.py |
Introduces TransferLearningMode. |
baybe/parameters/__init__.py |
Re-exports TransferLearningMode. |
baybe/searchspace/core.py |
Raises UnsupportedSearchSpaceAttributeError for blocked reduced-searchspace attribute access. |
baybe/exceptions.py |
Adds IncompatibleOverrideError and UnsupportedSearchSpaceAttributeError. |
tests/test_kernel_factories.py |
Adds tests for override dispatch scenarios. |
tests/test_reduced_searchspace.py |
Adds test asserting the dedicated reduced-searchspace exception type. |
tests/hypothesis_strategies/parameters.py |
Extends TaskParameter strategy to optionally include overrides. |
tests/hypothesis_strategies/kernels.py |
Updates index-kernel strategy to include both index kernel variants. |
CHANGELOG.md |
Documents the new override feature and enum. |
Comments suppressed due to low confidence (1)
baybe/surrogates/gaussian_process/core.py:447
- In the override path, when
kernel_factoryis a callable (i.e., not aPlainGPComponentFactory), the returned BayBE kernel is accepted as-is and later converted viato_gpytorch(searchspace=searchspace)on the full search space. If that kernel hasparameter_names=None(default for many basic kernels) or otherwise still references the task parameter, it will end up acting on the task dimension as well, causing an overlap with the explicitly attached task kernel. This contradicts the intended “task-free base kernel” behavior and can yield incorrect models.
if not isinstance(factory_kernel, Kernel):
raise IncompatibleOverrideError(incompatible_message)
base_spec = factory_kernel
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
89de707 to
a7b119a
Compare
AVHopp
left a comment
There was a problem hiding this comment.
General logic looks good, but there is missing coverage for the case of factory being provided and one bug related to this
Scienfitz
left a comment
There was a problem hiding this comment.
not ready for review, please rebase
a7b119a to
c3f7efd
Compare
202e2fa to
bfa8983
Compare
AdrianSosic
left a comment
There was a problem hiding this comment.
Hi @kalama-ai, thanks for taking care of this absolutely nontrivial mechanism 👍🏼
9b4c197 to
063c4c3
Compare
- Add `TaskParameter.override_transfer_learning_mode` and the `TransferLearningMode` enum to force `IndexKernel`/`PositiveIndexKernel` - Resolve the task kernel in `GaussianProcessSurrogate._resolve_kernel`, combining it with a task-free base kernel - Raise `IncompatibleOverrideError` for unsupported kernels/factories
e8dc7c0 to
968c52b
Compare
Override for dispatching between
PositiveIndexKernelandIndexKernelforTaskParameter1) Optional
override_transfer_learning_modeonTaskParameterA
TaskParametercan now carry an optionaloverride_transfer_learning_mode. When left at its default (None), the kernel factory controls how the task dimension is treated. When set, it instructs the GP surrogateto attach the requested task kernel:
2) Dispatch in
GaussianProcessSurrogate._resolve_kernela) No override — the surrogate uses the kernel factory on the full search space. Unchanged behavior.
b) Override set — the surrogate constructs the requested
IndexKernel / PositiveIndexKernelon the task column and multiplies it with a task-free base kernel. How that base kernel is obtained depends on what was passed askernel_or_factory:Case 1 (
NoneorBayBEKernelFactory):BayBEKernelFactorydispatches internally between_ChenNumericalKernelFactory(returns a BayBE Kernel) and_CustomScaledNumericalKernelFactory(returns a rawgpytorchkernel and callsget_comp_rep_parameter_indices). The reduced searchspace blocksget_comp_rep_parameter_indicesand we can not reduce thegpytorchcomponent to the non-task parameters. The surrogate therefore routes throughICMKernelFactoryon the full search space with the prescribed task kernel directly.A
BayBEKernelFactorywith a customparameter_selectoris handled like a callable factory (Case 3), i.e. evaluated on the reduced search space. This works on substance search spaces (Chen returns a name-based BayBE kernel) but currently raisesIncompatibleOverrideErroron non-substance ones, where the default factory yields agpytorchkernel.Case 2 (fixed kernel object (
PlainGPComponentFactory)):PlainGPComponentFactoryignores the searchspace entirely, so calling it on a reduced space returns the same object unchanged. The task parameter is instead stripped directly from the kernel via_strip_task_from_kernel, which removes the task name fromparameter_namesonBasicKernelsand single-levelScaleKernels, and raises for other composite kernels.Case 3 (callable factory): The factory is called on a task-free reduced search space (
SearchSpace._drop_parameters). Since the task parameter is absent, the factory produces atask-free kernel. The result must be a BayBE Kernel. If the output is a raw
gpytorchkernel it raisesIncompatibleOverrideError.In all override cases the base kernel's
to_gpytorchis called on the full search space, so itsactive_dimsalign with the actual training tensor, and the task kernel is attached on the task column.Raises
IncompatibleOverrideErrorfor: rawgpytorchkernels, composite kernels other thanScaleJKernel, task-aware factories, and factories that do not yield a BayBE kernel on the reduced space.3) Tests
The dispatch logic is exercised directly in
tests/test_kernel_factories.py, following the following scenarioskernel_or_factory(with override)MaternKernel(parameter_names=("x", "Task"))MaternKernel(parameter_names=("x",))MaternKernel()ScaleKernel(MaternKernel())gpytorch.kernels.MaternKernel(active_dims=[0, 1])IncompatibleOverrideErrorgpytorch.kernels.MaternKernel()IncompatibleOverrideErrorICMKernelFactory(...)(task-aware factory)IncompatibleOverrideErrorBayBEKernelFactory()(no substance parameter)ICMKernelFactory)IndexKernel(parameter_names=("Task",))MaternKernel(...) * IndexKernel(...)(product kernel)IncompatibleOverrideError