Update consider_prior Behavior and Remove Support for False #6007
Update consider_prior Behavior and Remove Support for False #6007nabenabe0928 merged 17 commits intooptuna:masterfrom
consider_prior Behavior and Remove Support for False #6007Conversation
nabenabe0928
left a comment
There was a problem hiding this comment.
Thank you for the PR, I left some preliminary comments.
optuna/samplers/_tpe/sampler.py
Outdated
| ) + ("From v4.3.0 onward, `consider_prior` is always `True`.") | ||
| warnings.warn(msg, FutureWarning) |
There was a problem hiding this comment.
[nit] Automatic falling back is more exact in the meaning.
| ) + ("From v4.3.0 onward, `consider_prior` is always `True`.") | |
| warnings.warn(msg, FutureWarning) | |
| ) | |
| warnings.warn( | |
| f"{msg} From v4.3.0 onward, `consider_prior` automatically falls back to `True`.", | |
| FutureWarning, | |
| ) |
| if parameters.prior_weight is None: | ||
| raise ValueError("Prior weight must be specified because consider_prior==True.") | ||
| elif parameters.prior_weight <= 0: | ||
| raise ValueError("Prior weight must be positive.") |
There was a problem hiding this comment.
[nit] As consider_prior cannot be used anymore, we can merge these errors.
| if parameters.prior_weight is None: | |
| raise ValueError("Prior weight must be specified because consider_prior==True.") | |
| elif parameters.prior_weight <= 0: | |
| raise ValueError("Prior weight must be positive.") | |
| if parameters.prior_weight is None or parameters.prior_weight <= 0: | |
| raise ValueError(f"A positive value must be specified for prior_weight, but got {parameters.prior_weight}.") |
| if len(transformed_observations) == 0: | ||
| weights = np.array([1.0]) | ||
| elif parameters.consider_prior: | ||
| else: | ||
| assert parameters.prior_weight is not None | ||
| weights = np.append(weights, [parameters.prior_weight]) |
There was a problem hiding this comment.
As prior_weight is already guaranteed to be not None from the earlier line, we can simply code like this:
weights = np.append(weights, [parameters.prior_weight])| consider_prior = True | ||
| n_kernels = len(observations) + consider_prior |
There was a problem hiding this comment.
[nit] An inline comment is sufficient.
| consider_prior = True | |
| n_kernels = len(observations) + consider_prior | |
| n_kernels = len(observations) + 1 # NOTE(sawa): +1 for prior. |
| maxsigma = 1.0 * (high - low + step_or_0) | ||
| if parameters.consider_magic_clip: | ||
| # TODO(contramundum53): Remove dependency of minsigma on consider_prior. | ||
| consider_prior = True |
There was a problem hiding this comment.
What about it?
| consider_prior = True | |
| n_kernels = len(observations) + 1 # NOTE(sawa): +1 for prior. |
| prior_mu = 0.5 * (low + high) | ||
| prior_sigma = 1.0 * (high - low + step_or_0) | ||
| mus = np.append(mus, [prior_mu]) | ||
| sigmas = np.append(sigmas, [prior_sigma]) |
There was a problem hiding this comment.
[nit] Reduced definitions of unused variables.
| prior_mu = 0.5 * (low + high) | |
| prior_sigma = 1.0 * (high - low + step_or_0) | |
| mus = np.append(mus, [prior_mu]) | |
| sigmas = np.append(sigmas, [prior_sigma]) | |
| # Add the stats for non-informative prior. | |
| mus = np.append(mus, [0.5 * (low + high)]) | |
| sigmas = np.append(sigmas, [1.0 * (high - low + step_or_0)]) |
| ], | ||
| [ | ||
| np.asarray([-0.4, 0.4, 0.41, 0.42]), | ||
| {"prior": False, "magic_clip": True, "endpoints": True}, |
There was a problem hiding this comment.
I believe we can remove unit tests for prior=False as the tests for prior=True already cover the functionality.
But please check carefully whether the removed tests are really covered by the existing tests.
There was a problem hiding this comment.
Thank you for your review. Since this is the only test in test_calculate that uses magic_clip = True, I believe it should be retained.
|
@nabenabe0928 Thank you for your advice. Everything should be updated now. PTAL! |
|
@gen740 @nabenabe0928 Could you review this PR? |
| # counts.astype(float) is necessary for weight calculation in ParzenEstimator. | ||
| return _ScottParzenEstimator( | ||
| param_name, rounded_dist, counts.astype(np.float64), consider_prior, prior_weight | ||
| param_name, rounded_dist, counts.astype(np.float64), True, prior_weight |
There was a problem hiding this comment.
[nit] It would be better to pass arguments with keys as consider_prior is hard-coded.
| param_name, rounded_dist, counts.astype(np.float64), True, prior_weight | |
| param_name=param_name, | |
| dist=rounded_dist, | |
| counts=counts.astype(np.float64), | |
| consider_prior=True, | |
| prior_weight=prior_weight, |
optuna/samplers/_tpe/sampler.py
Outdated
|
|
||
| self._parzen_estimator_parameters = _ParzenEstimatorParameters( | ||
| consider_prior, | ||
| True, |
There was a problem hiding this comment.
Could you use the keyword args here for more clarity?
| True, | |
| consider_prior=True, |
| ) | ||
| assert len(mpe._mixture_distribution.weights) == max(len(mus) + int(prior), 1) | ||
| assert len(mpe._mixture_distribution.weights) == max( | ||
| len(mus) + 1, 1 |
There was a problem hiding this comment.
We don't need the max operator.
| len(mus) + 1, 1 | |
| len(mus) + 1 |
nabenabe0928
left a comment
There was a problem hiding this comment.
I left some comments except for the unit tests of PED-ANOVA.
| ) | ||
| assert len(mpe._mixture_distribution.weights) == max(len(mus) + int(prior), 1) | ||
| assert len(mpe._mixture_distribution.weights) == max( | ||
| len(mus) + 1, 1 |
There was a problem hiding this comment.
Same here. We don't need the max operator.
| len(mus) + 1, 1 | |
| len(mus) + 1 |
|
Let me reassign the reviewer since gen740 is busy for a while. |
|
@nabenabe0928 Thank you for your review. I updated the code based on your suggestion and I also made some changes to the unit tests of PED-ANOVA. PTAL! |
|
@nabenabe0928 @not522 I would really appreciate it if you could take a moment to review the code. Thank you! |
not522
left a comment
There was a problem hiding this comment.
How about remove consider_prior from _ParzenEstimatorParameters? Since it is an internal class, we can break the compatibility.
|
@not522 Thank you for your advice. I decided to remove |
|
|
||
| class _ParzenEstimatorParameters(NamedTuple): | ||
| consider_prior: bool | ||
| prior_weight: float | None |
There was a problem hiding this comment.
How about remove None from the prior_weight type?
| prior_weight: float | None | |
| prior_weight: float |
optuna/samplers/_tpe/sampler.py
Outdated
| ) | ||
|
|
||
| self._parzen_estimator_parameters = _ParzenEstimatorParameters( | ||
| consider_prior=True, |
There was a problem hiding this comment.
Could you simply remove only this line and keep the keyword argument as is?
| # Prior is used for regularization. | ||
| self._consider_prior = True | ||
| # Control the regularization effect. | ||
| # Control the regularization effect of prior. |
There was a problem hiding this comment.
| # Control the regularization effect of prior. | |
| # Control the regularization effect by prior. |
There was a problem hiding this comment.
I still need to check the changes in this file.
|
I’ve made some modifications based on your suggestion. PTAL! @not522 @nabenabe0928 |
not522
left a comment
There was a problem hiding this comment.
Thank you for your update. It's almost LGTM.
I left nit comments. Please check them.
| raise ValueError("Prior weight must be specified when consider_prior==True.") | ||
| elif parameters.prior_weight <= 0: | ||
| raise ValueError("Prior weight must be positive.") | ||
| if parameters.prior_weight is None or parameters.prior_weight <= 0: |
There was a problem hiding this comment.
| if parameters.prior_weight is None or parameters.prior_weight <= 0: | |
| if parameters.prior_weight <= 0: |
|
|
||
| n_kernels = len(observations) + parameters.consider_prior | ||
| n_kernels = len(observations) + 1 # NOTE(sawa3030): +1 for prior. | ||
| assert parameters.prior_weight is not None |
There was a problem hiding this comment.
| assert parameters.prior_weight is not None |
|
@not522 Thank you for your support. I've made the updates accordingly. |
| counts=counts, | ||
| consider_prior=False, | ||
| prior_weight=0.0, | ||
| prior_weight=1.0, |
There was a problem hiding this comment.
I believe this part should still test prior_weight=0.0 to check whether PED-ANOVA works with prior_weight==0.0.
| counts=_counts, | ||
| consider_prior=False, | ||
| prior_weight=0.0, | ||
| prior_weight=1.0, |
There was a problem hiding this comment.
| prior_weight=1.0, | |
| prior_weight=0.0, |
nabenabe0928
left a comment
There was a problem hiding this comment.
Sorry for the late response 🙇
I left some comments on the test file for PED-ANOVA.
Basically, PED-ANOVA tests prior_weight=0.0 just because the original paper uses prior_weight=0.0 actually.
| counts=_counts, | ||
| consider_prior=False, | ||
| prior_weight=0.0, | ||
| prior_weight=1.0, |
There was a problem hiding this comment.
| prior_weight=1.0, | |
| prior_weight=0.0, |
6be7b57 to
a8e0ab2
Compare
a8e0ab2 to
6329097
Compare
|
@nabenabe0928 I modified |
In fact, PED-ANOVA was originally expected to be used without prior and |
|
@nabenabe0928 Thank you for your advice. I think I made the necessary updates. PTAL! |
nabenabe0928
left a comment
There was a problem hiding this comment.
Thank you very much for the hard work on this PR, LGTM:)
Motivation
consider_priorto always beTrue.consider_priorpositional args in the following PR.Description of Changes
consider_prioris now alwaysTrue.consider_prior = Truewhen constructing_ParzenEstimatorParameters.consider_prior = False.