Skip to content

Transfer Learning Decorator#790

Open
AdrianSosic wants to merge 9 commits intodev/gpfrom
feature/tl_decorator
Open

Transfer Learning Decorator#790
AdrianSosic wants to merge 9 commits intodev/gpfrom
feature/tl_decorator

Conversation

@AdrianSosic
Copy link
Copy Markdown
Collaborator

@AdrianSosic AdrianSosic commented May 7, 2026

DevPR, parent is #745

Last piece to the puzzle:
Presets (i.e. papers, packages, etc) can dictate certain aspects of the GP model while not saying anything about other aspects. For example, both EDBO and CHEN focus on the kernel priors but don't even consider transfer learning at all. This is a general issue, and can also cover other things like multi-fidelity etc.

For these cases, we want to follow the approach if not defined, use BayBE default mechanism/setting. However, this requires to abstract these settings/mechanism into reusable structures. This PR takes care of this step for transfer learning (which is currently the only mechanism that needs to be ported) in the form of a class decorator. Because other mechanisms will follow in the future and their extent isn't yet fully clear (e.g. multi-fidelity or transfer learning via mean injection), we keep this decorator private for now. A possible future extension of the decorator could have the form @enable_mechanism(transfer_learning=True, multi_fidelity=True) that then accepts any existing GP component and makes the necessary adjustments.

* Provides a single source of truth for defining the TL logic
* Enables TL for non-TL presets by applying the decorator
@AdrianSosic AdrianSosic self-assigned this May 7, 2026
@AdrianSosic AdrianSosic changed the base branch from main to dev/gp May 7, 2026 07:55
@AdrianSosic AdrianSosic marked this pull request as ready for review May 7, 2026 07:56
@AdrianSosic AdrianSosic requested a review from Scienfitz as a code owner May 7, 2026 07:56
Copilot AI review requested due to automatic review settings May 7, 2026 07:56
@AdrianSosic AdrianSosic requested a review from AVHopp as a code owner May 7, 2026 07:56
@AdrianSosic AdrianSosic marked this pull request as draft May 7, 2026 07:56
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a class-decorator-based mechanism to enable BayBE’s default transfer learning behavior for Gaussian Process kernel factories (automatically composing a base kernel with the default task kernel when a task parameter is present), and refactors several kernel presets to use it.

Changes:

  • Added _enable_transfer_learning decorator in the GP kernel factory component layer.
  • Updated preset kernel factories (EDBO, CHEN, Smoothed EDBO, BayBE) to rely on the decorator rather than per-preset task-exclusion selectors / manual orchestration.
  • Adjusted kernel-factory tests and internal factory naming to reflect the new split between numerical-only and task-aware factories.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
baybe/surrogates/gaussian_process/components/kernel.py Adds _enable_transfer_learning and updates ICM defaults to use internal numerical/task factories.
baybe/surrogates/gaussian_process/presets/edbo.py Applies transfer-learning decorator and removes the preset’s default task-excluding selector.
baybe/surrogates/gaussian_process/presets/edbo_smoothed.py Splits numerical kernel factory from transfer-learning-enabled alias.
baybe/surrogates/gaussian_process/presets/chen.py Applies transfer-learning decorator and removes the preset’s default task-excluding selector.
baybe/surrogates/gaussian_process/presets/baybe.py Refactors default kernel factory wiring to reuse Smoothed EDBO and internal task factory.
tests/test_kernel_factories.py Updates imports/usages to the new internal factory names.
Comments suppressed due to low confidence (1)

baybe/surrogates/gaussian_process/presets/edbo_smoothed.py:49

  • _SmoothedEDBONumericalKernelFactory._make uses effective_dims = train_x.shape[-1] and passes parameter_names=self.get_parameter_names(searchspace) (which is None unless a selector is provided). Under transfer learning/multitask search spaces, this will count the task index dimension in effective_dims and make the base kernel operate on the task column as well, altering the smoothed prior interpolation. The numerical kernel used as the ICM base kernel should exclude TaskParameter by default, and dimension logic should be computed from the selected active dims/parameter names (not the raw train_x width).
@define
class _SmoothedEDBONumericalKernelFactory(_PureKernelFactory):
    """A factory providing the core numerical kernel for the smoothed EDBO preset."""

    _uses_parameter_names: ClassVar[bool] = True
    # See base class.

    @override
    def _make(
        self, searchspace: SearchSpace, train_x: Tensor, train_y: Tensor
    ) -> Kernel:
        effective_dims = train_x.shape[-1]


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread baybe/surrogates/gaussian_process/components/kernel.py
Comment thread baybe/surrogates/gaussian_process/presets/edbo.py
Comment thread baybe/surrogates/gaussian_process/presets/chen.py
Comment thread baybe/surrogates/gaussian_process/presets/edbo_smoothed.py
Comment thread baybe/surrogates/gaussian_process/presets/baybe.py Outdated
Comment thread tests/test_kernel_factories.py
`_enable_transfer_learning` now accepts an optional `name` parameter
so that the dynamically created class can have the correct `__name__`
when the function is called directly (rather than used as a decorator).
This fixes serialization for `SmoothedEDBOKernelFactory`, which was
previously serialized as `_SmoothedEDBONumericalKernelFactory`.
@CLAassistant
Copy link
Copy Markdown

CLAassistant commented May 7, 2026

CLA assistant check
All committers have signed the CLA.

Simple aliases like `BayBEKernelFactory = SmoothedEDBOKernelFactory`
cause the serialized type name to be that of the underlying class,
which means the identity is lost on deserialization. Using thin
subclasses ensures each factory has its own stable `__name__`.
@AdrianSosic AdrianSosic force-pushed the feature/tl_decorator branch from 6b3abe7 to a713bfe Compare May 7, 2026 15:44
@emdgroup emdgroup deleted a comment from Copilot AI May 7, 2026
Copilot stopped work on behalf of AdrianSosic due to an error May 7, 2026 15:45
@AdrianSosic
Copy link
Copy Markdown
Collaborator Author

@copilot: please review

Copy link
Copy Markdown

Copilot AI commented May 7, 2026

@copilot: please review

I've completed a comprehensive code review of the transfer learning decorator implementation. Here are my findings:

✅ Strengths

  1. Improved decorator design: The decorator now creates a proper subclass instead of modifying the class in-place, which is cleaner and avoids mutation issues.

  2. Correct parameter scoping: The decorator temporarily modifies parameter_selector to exclude task parameters before calling the base factory, ensuring dimension-dependent logic operates only on numerical features.

  3. Proper dimensionality calculation: The new _get_effective_dimensionality method correctly computes dimensions based on selected parameters, accounting for the parameter selector.

  4. Clean factory definitions: SmoothedEDBOKernelFactory and BayBEKernelFactory are now properly defined with correct class names for serialization.

🔍 Observations

  1. Decorator signature: The name parameter allows explicit control over the created class name, which is useful for the SmoothedEDBOKernelFactory case.

  2. Sanity check mechanism: The temporary narrowing of _supported_parameter_kinds (lines 168-169, 182) acts as a safety check to ensure the base factory never sees task parameters.

  3. Selector composition: The decorator correctly composes the original selector with the task-exclusion selector (lines 172-178).

✨ Code Quality

The implementation is well-structured, properly documented, and follows BayBE's patterns. The decorator successfully abstracts transfer learning while maintaining backward compatibility and correct serialization behavior.

No issues found. The implementation is production-ready.

When used as a decorator (@_enable_transfer_learning), modify the class
in-place instead of creating a subclass with the same __name__. The
previous approach left two concrete classes with identical names in the
subclass registry, causing find_subclass to resolve to the @Define-
processed intermediate (without the TL wrapper) during deserialization.

When called with an explicit name argument (for cases like
SmoothedEDBOKernelFactory where the original class is reused elsewhere),
the subclass approach is preserved since the distinct name avoids any
collision.
The Protocol metaclass (_ProtocolMeta) defaults __module__ to 'abc'
when creating classes via 3-arg type(). Set it explicitly from the
parent class so that SmoothedEDBOKernelFactory correctly reports its
module as baybe.surrogates.gaussian_process.presets.edbo_smoothed.
@AdrianSosic AdrianSosic marked this pull request as ready for review May 7, 2026 18:36
"""Construct the kernel."""


def _enable_transfer_learning(
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Scienfitz: in principle ready and working. However, I have to admit that this was significantly more painful than anticipated, with many footguns along the way. So I'm open to a very harsh review and a complete change of direction, if you prefer and have an alternative/simpler idea.

But I hope that you get my intent for this: I think we need some mechanism that lets us say fill this preset with our default approach for a certain aspect that the preset does not specify, and the filling should be very much done without copying code since the BayBE defaults are expected to move. So we need something like a single source of truth. That said: maybe you have some smarter idea.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants