如何为scipy.optimize.minimize的优化向量各元素设置不同eps参数?
为scipy.optimize.minimize的不同变量设置独立eps步长
默认情况下,scipy.optimize.minimize的eps参数是全局生效的,会对优化向量的所有元素使用相同的差分步长。要为不同元素设置独立步长,有两种可靠的实现方式:
方法1:自定义数值梯度(推荐)
如果没有提供解析梯度函数,minimize会自动用全局eps计算数值梯度。我们可以手动实现数值梯度计算,给每个变量分配单独的步长。
示例代码
import numpy as np from scipy.optimize import minimize # 目标函数(以Rosenbrock函数为例) def objective(x): return (x[0] - 1)**2 + 100 * (x[1] - x[0]**2)**2 # 自定义梯度函数,为每个变量指定不同步长 def custom_jac(x): # 为每个变量设置独立步长:x[0]用1e-3,x[1]用1e-5 step_sizes = np.array([1e-3, 1e-5]) grad = np.zeros_like(x) for i in range(len(x)): # 中心差分计算偏导 x_plus = x.copy() x_plus[i] += step_sizes[i] x_minus = x.copy() x_minus[i] -= step_sizes[i] grad[i] = (objective(x_plus) - objective(x_minus)) / (2 * step_sizes[i]) return grad # 初始猜测值 x0 = np.array([0.0, 0.0]) # 调用minimize,传入自定义梯度函数 result = minimize(objective, x0, jac=custom_jac, method='L-BFGS-B') print("优化结果:", result.x)
这种方法完全绕过了全局eps参数,直接控制每个变量的差分步长,精度和灵活性都更高。
方法2:变量缩放转换
通过对优化变量进行线性缩放,将原变量x转换为新变量y,使得对y使用全局eps时,等效于原变量x使用不同步长。
示例代码
import numpy as np from scipy.optimize import minimize def objective(x): return (x[0] - 1)**2 + 100 * (x[1] - x[0]**2)**2 # 期望为每个变量设置的步长 desired_steps = np.array([1e-3, 1e-5]) # 变量转换:x = y * desired_steps,将原问题转换为以y为变量的优化问题 def scaled_objective(y): x = y * desired_steps return objective(x) # 初始值转换为缩放后的变量 x0 = np.array([0.0, 0.0]) y0 = x0 / desired_steps # 对缩放后的变量使用全局eps=1,等效于原变量使用desired_steps result_y = minimize(scaled_objective, y0, method='L-BFGS-B', eps=1) # 将结果转换回原变量 result_x = result_y.x * desired_steps print("优化结果:", result_x)
这种方法无需修改梯度计算逻辑,通过变量缩放间接实现不同步长,适合不想手动实现梯度的场景。
内容的提问来源于stack exchange,提问作者Dr. Paprika
相关产品推荐
相关产品推荐

