tensorflow / tensorflow/probability
Bug in lbfgs_minimize: Checking convergence with objective value doesn't work for negative objectives
Nobody has claimed this yet.
- Dominant language
- Jupyter Notebook
- Stars
- 4.4k
- Forks
- 1.1k
- PR merge metrics
- No merged PRs in 30d
Description
I believe I found a bug in the lbfgs_minimize function:
When I try to use the change in the objective value as a termination criterion (e.g. setting f_relative_tolerance=1e-10as in the minimal failing example below), this only works if the objective value at the minimum is positive.
For this see below example where the high-dimensional bowl is first shifted by +0.1 (which works) and then by -0.1 (which fails).
I think the bug is in line 381 of bfgs_utils.py where the convergence is checked with the objective value itself, while it should be its absolute value.
I propose changing the mentioned line to
f_relative_tolerance * tf.math.abs(current_objective))
or something similar.
Please find the minimal failing example below.
import numpy as np
import tensorflow_probability as tfp
import tensorflow as tf
# A high-dimensional quadratic bowl.
ndims = 60
minimum = np.ones([ndims], dtype='float64')
scales = np.arange(ndims, dtype='float64') + 1.0
# The objective function and the gradient.
def quadratic_loss_and_gradient_positive_objective(x):
return tfp.math.value_and_gradient(
lambda x: 0.1 + tf.reduce_sum(
scales * tf.math.squared_difference(x, minimum), axis=-1),
x)
# A different objective function, only difference: The objective value at
# the minimum is -0.1 instead of +0.1
def quadratic_loss_and_gradient_negative_objective(x):
return tfp.math.value_and_gradient(
lambda x: -0.1 + tf.reduce_sum(
scales * tf.math.squared_difference(x, minimum), axis=-1),
x)
start = np.arange(ndims, 0, -1, dtype='float64')
#For the positive objective this works
optim_results_pos = tfp.optimizer.lbfgs_minimize(
quadratic_loss_and_gradient_positive_objective,
initial_position=start,
num_correction_pairs=10,
tolerance=0.,
f_relative_tolerance=1e-10)
# Check that the search converged
assert(optim_results_pos.converged)
# Check that the argmin is close to the actual value.
np.testing.assert_allclose(optim_results_pos.position, minimum)
#But it fails for the negative objective
optim_results_neg = tfp.optimizer.lbfgs_minimize(
quadratic_loss_and_gradient_negative_objective,
initial_position=start,
num_correction_pairs=10,
tolerance=0.,
f_relative_tolerance=1e-10)
# Check that the search converged
assert(optim_results_neg.converged)
# Check that the argmin is close to the actual value.
np.testing.assert_allclose(optim_results_neg.position, minimum)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in tensorflow_probability/python/optimizer/bfgs_utils.py at line 381, then run the minimal 60-dimensional quadratic example from the issue with both positive and negative objective offsets. Done means f_relative_tolerance correctly reports convergence for the negative objective as well as the positive one, with the resulting position matching the minimum.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- machine-learning
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 55/100