如何更改 sklearn 高斯过程回归使用的优化函数中的 max_iter?
How to change max_iter in optimize function used by sklearn gaussian process regression?
我正在使用 sklearn 的 GPR 库,但偶尔 运行 进入这个恼人的警告:
ConvergenceWarning: lbfgs failed to converge (status=2):
ABNORMAL_TERMINATION_IN_LNSRCH.
Increase the number of iterations (max_iter) or scale the data as shown in:
https://scikit-learn.org/stable/modules/preprocessing.html
_check_optimize_result("lbfgs", opt_res)
不仅我几乎找不到关于此警告的文档,而且 max_iter 根本不是 sklearn 的 GPR 模型中的参数。
我尝试按照建议重新缩放数据,但它没有用,坦率地说我不明白(我还需要缩放输出吗?同样,文档很少)。
增加优化过程中的最大迭代次数是有道理的,但 sklearn 似乎没有办法做到这一点,这令人沮丧,因为他们建议这样做是为了响应这个警告。
查看 GPR source code,这就是 sklearn 调用优化器的方式,
def _constrained_optimization(self, obj_func, initial_theta, bounds):
if self.optimizer == "fmin_l_bfgs_b":
opt_res = scipy.optimize.minimize(
obj_func, initial_theta, method="L-BFGS-B", jac=True,
bounds=bounds)
_check_optimize_result("lbfgs", opt_res)
theta_opt, func_min = opt_res.x, opt_res.fun
elif callable(self.optimizer):
theta_opt, func_min = \
self.optimizer(obj_func, initial_theta, bounds=bounds)
else:
raise ValueError("Unknown optimizer %s." % self.optimizer)
return theta_opt, func_min
其中 scipy.optimize.minimize()
的默认值为
scipy.optimize.minimize(fun, x0, args=(), method='L-BFGS-B', jac=None, bounds=None,
tol=None, callback=None, options={'disp': None, 'maxcor': 10, 'ftol': 2.220446049250313e-09,
'gtol': 1e-05, 'eps': 1e-08, 'maxfun': 15000, 'maxiter': 15000, 'iprint': -1, 'maxls': 20})
根据 scipy docs.
我想完全按照 GPR 源代码中所示使用优化器,但将 maxiter 更改为更大的数字。换句话说,我不想更改优化器的行为,而不是通过增加最大迭代次数所做的更改。
挑战在于其他参数,如 obj_func, initial_theta, bounds
是在 GPR 源代码中设置的,无法从 GPR 对象访问。
这就是我调用 GPR 的方式,请注意,除了 n_restarts_optimizer 和内核之外,这些大部分都是默认参数。
for kernel in kernels:
gp = gaussian_process.GaussianProcessRegressor(
kernel = kernel,
alpha = 1e-10,
copy_X_train = True,
optimizer = "fmin_l_bfgs_b",
n_restarts_optimizer= 25,
normalize_y = False,
random_state = None)
您想扩展 and/or 修改现有 Python 对象的行为,这听起来像是一个很好的继承用例。
一个解决方案可能是继承 scikit-learn 实现,并确保使用您想要的参数调用常用的优化器。这是一个草图,但请注意,这还没有经过测试。
from functools import partial
from sklearn.gaussian_process import GaussianProcessRegressor
import scipy.optimize
class MyGPR(GaussianProcessRegressor):
def __init__(self, *args, max_iter=15000, **kwargs):
super().__init__(*args, **kwargs)
self._max_iter = max_iter
def _constrained_optimization(self, obj_func, initial_theta, bounds):
def new_optimizer(obj_func, initial_theta, bounds):
return scipy.optimize.minimize(
obj_func,
initial_theta,
method="L-BFGS-B",
jac=True,
bounds=bounds,
max_iter=self._max_iter,
)
self.optimizer = new_optimizer
return super()._constrained_optimization(obj_func, initial_theta, bounds)
对我有用的是以下内容。
我使用继承,我还重新定义了 _constrained_optimization 方法。
class MyGPR(GaussianProcessRegressor):
def __init__(self, *args, max_iter=2e05, gtol=1e-06, **kwargs):
super().__init__(*args, **kwargs)
self._max_iter = max_iter
self._gtol = gtol
def _constrained_optimization(self, obj_func, initial_theta, bounds):
if self.optimizer == "fmin_l_bfgs_b":
opt_res = scipy.optimize.minimize(obj_func, initial_theta, method="L-BFGS-B", jac=True, bounds=bounds, options={'maxiter':self._max_iter, 'gtol': self._gtol})
_check_optimize_result("lbfgs", opt_res)
theta_opt, func_min = opt_res.x, opt_res.fun
elif callable(self.optimizer):
theta_opt, func_min = self.optimizer(obj_func, initial_theta, bounds=bounds)
else:
raise ValueError("Unknown optimizer %s." % self.optimizer)
return theta_opt, func_min
为此,除了您通常的导入之外,您还应该导入以下内容
from sklearn.utils.optimize import _check_optimize_result
我正在使用 sklearn 的 GPR 库,但偶尔 运行 进入这个恼人的警告:
ConvergenceWarning: lbfgs failed to converge (status=2):
ABNORMAL_TERMINATION_IN_LNSRCH.
Increase the number of iterations (max_iter) or scale the data as shown in:
https://scikit-learn.org/stable/modules/preprocessing.html
_check_optimize_result("lbfgs", opt_res)
不仅我几乎找不到关于此警告的文档,而且 max_iter 根本不是 sklearn 的 GPR 模型中的参数。 我尝试按照建议重新缩放数据,但它没有用,坦率地说我不明白(我还需要缩放输出吗?同样,文档很少)。
增加优化过程中的最大迭代次数是有道理的,但 sklearn 似乎没有办法做到这一点,这令人沮丧,因为他们建议这样做是为了响应这个警告。
查看 GPR source code,这就是 sklearn 调用优化器的方式,
def _constrained_optimization(self, obj_func, initial_theta, bounds):
if self.optimizer == "fmin_l_bfgs_b":
opt_res = scipy.optimize.minimize(
obj_func, initial_theta, method="L-BFGS-B", jac=True,
bounds=bounds)
_check_optimize_result("lbfgs", opt_res)
theta_opt, func_min = opt_res.x, opt_res.fun
elif callable(self.optimizer):
theta_opt, func_min = \
self.optimizer(obj_func, initial_theta, bounds=bounds)
else:
raise ValueError("Unknown optimizer %s." % self.optimizer)
return theta_opt, func_min
其中 scipy.optimize.minimize()
的默认值为
scipy.optimize.minimize(fun, x0, args=(), method='L-BFGS-B', jac=None, bounds=None,
tol=None, callback=None, options={'disp': None, 'maxcor': 10, 'ftol': 2.220446049250313e-09,
'gtol': 1e-05, 'eps': 1e-08, 'maxfun': 15000, 'maxiter': 15000, 'iprint': -1, 'maxls': 20})
根据 scipy docs.
我想完全按照 GPR 源代码中所示使用优化器,但将 maxiter 更改为更大的数字。换句话说,我不想更改优化器的行为,而不是通过增加最大迭代次数所做的更改。
挑战在于其他参数,如 obj_func, initial_theta, bounds
是在 GPR 源代码中设置的,无法从 GPR 对象访问。
这就是我调用 GPR 的方式,请注意,除了 n_restarts_optimizer 和内核之外,这些大部分都是默认参数。
for kernel in kernels:
gp = gaussian_process.GaussianProcessRegressor(
kernel = kernel,
alpha = 1e-10,
copy_X_train = True,
optimizer = "fmin_l_bfgs_b",
n_restarts_optimizer= 25,
normalize_y = False,
random_state = None)
您想扩展 and/or 修改现有 Python 对象的行为,这听起来像是一个很好的继承用例。
一个解决方案可能是继承 scikit-learn 实现,并确保使用您想要的参数调用常用的优化器。这是一个草图,但请注意,这还没有经过测试。
from functools import partial
from sklearn.gaussian_process import GaussianProcessRegressor
import scipy.optimize
class MyGPR(GaussianProcessRegressor):
def __init__(self, *args, max_iter=15000, **kwargs):
super().__init__(*args, **kwargs)
self._max_iter = max_iter
def _constrained_optimization(self, obj_func, initial_theta, bounds):
def new_optimizer(obj_func, initial_theta, bounds):
return scipy.optimize.minimize(
obj_func,
initial_theta,
method="L-BFGS-B",
jac=True,
bounds=bounds,
max_iter=self._max_iter,
)
self.optimizer = new_optimizer
return super()._constrained_optimization(obj_func, initial_theta, bounds)
对我有用的是以下内容。 我使用继承,我还重新定义了 _constrained_optimization 方法。
class MyGPR(GaussianProcessRegressor):
def __init__(self, *args, max_iter=2e05, gtol=1e-06, **kwargs):
super().__init__(*args, **kwargs)
self._max_iter = max_iter
self._gtol = gtol
def _constrained_optimization(self, obj_func, initial_theta, bounds):
if self.optimizer == "fmin_l_bfgs_b":
opt_res = scipy.optimize.minimize(obj_func, initial_theta, method="L-BFGS-B", jac=True, bounds=bounds, options={'maxiter':self._max_iter, 'gtol': self._gtol})
_check_optimize_result("lbfgs", opt_res)
theta_opt, func_min = opt_res.x, opt_res.fun
elif callable(self.optimizer):
theta_opt, func_min = self.optimizer(obj_func, initial_theta, bounds=bounds)
else:
raise ValueError("Unknown optimizer %s." % self.optimizer)
return theta_opt, func_min
为此,除了您通常的导入之外,您还应该导入以下内容
from sklearn.utils.optimize import _check_optimize_result