-
Notifications
You must be signed in to change notification settings - Fork 50
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Chimera Objective #455
base: main
Are you sure you want to change the base?
Chimera Objective #455
Conversation
@AVHopp @AdrianSosic PR in draft mode, NOT for review |
baybe/objectives/chimera.py
Outdated
|
||
@define(frozen=True, slots=False) | ||
class ChimeraObjective(Objective): | ||
"""An objective scalarizing multiple targets using desirability values.""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wrong docstring mentioning desirability
incude a link to the publication, see other code parts (eg edbo) for how to properly include links
baybe/objectives/chimera.py
Outdated
) | ||
"The targets considered by the objective." | ||
|
||
targets_threshold_values: tuple[float, ...] = field( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
targets_
in fornt is not necessary for either of the two threshold
attributes
baybe/objectives/chimera.py
Outdated
"""The softness parameter regulating the Heaviside function.""" | ||
|
||
@targets_threshold_values.default | ||
def _default_targets_threshold_values(self) -> tuple[float, ...]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think there are no rasonable defaults so these should not have defaults
apart from that the defaults you specified do not satisfy the requirements ge(0.0)
arg = -value / softness | ||
return np.exp(-np.logaddexp(0, arg)) | ||
|
||
def _hard_heaviside(self, value: float) -> float: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is the hard function really needed? I think the soft heavyside should just recover the hard one for an extreme value of softness
. If so that can simply be sued wherever a hard heaviside is needed
|
||
@st.composite | ||
def chimera_objectives(draw: st.DrawFn): | ||
"""Generate :class:`baybe.objectives.chimera.ChimeraObjective` and its reference.""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"and its reference" is not accurate anymore
targets = draw( | ||
st.lists( | ||
numerical_targets(intervals), | ||
min_size=3, # At least 2 targets. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is it set to 3?
# Now draw threshold values one-by-one based on each threshold type. | ||
threshold_values = [] | ||
for i, tt in enumerate(threshold_types): | ||
if tt == ThresholdType.ABSOLUTE: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for singletons, always use is
and never ==
return are_close | ||
|
||
|
||
@settings(max_examples=2) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i assume this is for your testing purposes and not supposed to be here genereally?
@settings(max_examples=2) | ||
@given(chimera_obj=chimera_objectives(), data=st.data()) | ||
def test_chimera_merits(chimera_obj, data): | ||
"""Validating chimerra merits value with external reference.""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo
absolutes=[ | ||
tt.value.upper() == "ABSOLUTE" for tt in chimera_obj.threshold_types | ||
], | ||
goals=[g.lower() for g in goals], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
duplicated application of lower?
] | ||
|
||
target_vals = data.draw(data_frames(columns=columns)) | ||
assume(target_vals.shape[0] >= 6) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
does data_frames
not have options to specify the amount of rows?
Also, why 6 specifically?
This PR introduces Chimera, a general-purpose achievement scalarizing function for multi-target optimization that allows users to establish a hierarchy of targets with relative or absolute thresholds for concurrent optimization.
This implementation includes a new objective class,
ChimeraObjective
, which follows a similar approach to theDesirabilityObjective
. It scalarizes multiple targets into a single score, termedChimera Merits
, which is to be minimized.For further details, please refer to the following publication:
F. Häse, L.M. Roch, and A. Aspuru-Guzik. Chimera: enabling hierarchy-based multi-objective optimization for self-driving laboratories. Chemical Science 2018, 9(39), 7642-7655.
WIP:
ChimeraObjective
implementation.DesirabilityObjective
.ChimeraObjective
.