当求解器可能成功求解时
终点等于初始点
初始点可能是一个局部最小值或解,因为一阶最优性测度接近于 0。您可能对此结果不满意,因为求解器并未改进您的初始点。
如果您不确定初始点是否确实为局部最小值,请尝试:
从不同点开始 - 请参阅更改初始点。
检查您的目标和约束是否正确定义(例如,它们在某些点处是否返回了正确的值?)- 请参阅检查您的目标函数和约束函数。检查以确保不可行点不会导致函数中出现错误;请参阅迭代可能违反约束。
更改容差,例如
OptimalityTolerance
、ConstraintTolerance
和StepTolerance
- 请参阅使用适当的容差。缩放您的问题,使每个坐标具有大致相同的影响 - 请参阅重新缩放问题。
提供梯度和黑塞矩阵信息 - 请参阅提供解析梯度或雅可比矩阵和提供黑塞矩阵。
可能是局部最小值
求解器可能已达到局部最小值,但无法确定,因为一阶最优性测度不小于 OptimalityTolerance
容差。(要了解有关一阶最优性测度的更多信息,请参阅一阶最优性测度。)要查看报告的解是否可靠,请考虑以下建议。
1.非平滑函数 |
2.以终点作为起点重新执行优化 |
3.尝试不同算法 |
4.更改容差 |
5.重新缩放问题 |
6.检查附近的点 |
7.更改有限差分选项 |
8.提供解析梯度或雅可比矩阵 |
9.提供黑塞矩阵 |
1.非平滑函数
如果您尝试最小化非平滑函数,或具有非平滑约束,“可能是局部最小值”也许是最好的退出消息。这是因为,一阶最优性条件不适用于非平滑点。
为了让自己确信该解是充分的,请尝试检查附近的点。
2.以终点作为起点重新执行优化
如果在终点处重新开始优化,则可以生成具有更好的一阶最优性测度的解。更好(较低)的一阶最优性测度让您更有理由相信解是可靠的。
例如,假设有以下最小化问题,摘自示例使用符号数学和 Optimization Toolbox 求解器:
options = optimoptions('fminunc','Algorithm','quasi-newton'); funh = @(x)log(1 + (x(1) - 4/3)^2 + 3*(x(2) - (x(1)^3 - x(1)))^2); [xfinal fval exitflag] = fminunc(funh,[-1;2],options) Local minimum possible. fminunc stopped because it cannot decrease the objective function along the current search direction. xfinal = 1.3333 1.0370 fval = 8.5265e-014 exitflag = 5
退出标志值 5
表示一阶最优性测度大于函数容差。从 xfinal
开始再次运行最小化:
[xfinal2 fval2 exitflag2] = fminunc(funh,xfinal,options) Local minimum found. Optimization completed because the size of the gradient is less than the default value of the function tolerance. xfinal2 = 1.3333 1.0370 fval2 = 6.5281e-014 exitflag2 = 1
局部最小值是“找到”,而不是“可能”,exitflag 为 1
而不是 5
。这两个解实际上相同。然而,第二次运行有更令人满意的退出消息,因为一阶最优性测度相当低,是 7.5996e-007
,而不是 3.9674e-006
。
3.尝试不同算法
许多求解器都允许您选择算法。不同的算法可能会导致使用不同的停止条件。
例如,以终点作为起点重新执行优化会返回第一次运行时的 exitflag 5
。这次运行使用 quasi-newton
算法。
信赖域算法需要用户提供的梯度。betopt.m
包含目标函数和梯度的计算:
function [f gradf] = betopt(x) g = 1 + (x(1)-4/3)^2 + 3*(x(2) - (x(1)^3-x(1)))^2; f = log(g); gradf(1) = 2*(x(1)-4/3) + 6*(x(2) - (x(1)^3-x(1)))*(1-3*x(1)^2); gradf(1) = gradf(1)/g; gradf(2) = 6*(x(2) - (x(1)^3 -x(1)))/g;
使用 trust-region
算法运行优化会生成不同的 exitflag:
options = optimoptions('fminunc','Algorithm','trust-region','SpecifyObjectiveGradient',true); [xfinal3 fval3 exitflag3] = fminunc(@betopt,[-1;2],options) Local minimum possible. fminunc stopped because the final change in function value relative to its initial value is less than the default value of the function tolerance. xfinal3 = 1.3333 1.0370 fval3 = 7.6659e-012 exitflag3 = 3
退出条件优于 quasi-newton
条件,尽管前者仍不是最佳条件。从终点重新运行该算法会产生更好的点,其一阶最优性测度极小:
[xfinal4 fval4 eflag4 output4] = fminunc(@betopt,xfinal3,options) Local minimum found. Optimization completed because the size of the gradient is less than the default value of the function tolerance. xfinal4 = 1.3333 1.0370 fval4 = 0 eflag4 = 1 output4 = iterations: 1 funcCount: 2 cgiterations: 1 firstorderopt: 7.5497e-11 algorithm: 'trust-region' message: 'Local minimum found. Optimization completed because the size o...' constrviolation: []
4.更改容差
有时,收紧或放松容差会产生更令人满意的结果。例如,在尝试不同算法部分中选择较小的 OptimalityTolerance
值:
options = optimoptions('fminunc','Algorithm','trust-region',... 'OptimalityTolerance',1e-8,'SpecifyObjectiveGradient',true); % default=1e-6 [xfinal3 fval3 eflag3 output3] = fminunc(@betopt,[-1;2],options) Local minimum found. Optimization completed because the size of the gradient is less than the selected value of the function tolerance. xfinal3 = 1.3333 1.0370 fval3 = 0 eflag3 = 1 output3 = iterations: 15 funcCount: 16 cgiterations: 12 firstorderopt: 7.5497e-11 algorithm: 'trust-region' message: 'Local minimum found. Optimization completed because the size...' constrviolation: []
fminunc
比以前多进行了一次迭代,但得到的解更好。
5.重新缩放问题
尝试通过缩放和中心化,让每个坐标对目标函数和约束函数的影响大致相同。有关示例,请参阅中心化和缩放问题。
6.检查附近的点
在接近终点的点处计算您的目标函数和约束(如果它们存在)。如果终点是局部最小值,附近的可行点具有较大的目标函数值。有关示例,请参阅检查附近的点。
如果您有 Global Optimization Toolbox 许可证,请尝试从终点运行 patternsearch
(Global Optimization Toolbox) 求解器。patternsearch
会检查附近的点,并接受所有类型的约束。
7.更改有限差分选项
中心有限差分计算起来更费时,但更精确。当您的问题可能有高曲率时,请使用中心差分。
要在命令行中选择中心差分,请使用 optimoptions
将 'FiniteDifferenceType'
设置为 'central'
,而不是默认值 'forward'
。
8.提供解析梯度或雅可比矩阵
如果不提供梯度或雅可比矩阵,求解器会通过有限差分来估计梯度和雅可比矩阵。因此,提供这些导数可以节省计算时间,并可以提高准确度。基于问题的方法可以自动提供梯度;请参阅 Optimization Toolbox 中的自动微分。
对于约束问题,提供梯度还有另一个优势。求解器可以到达点 x
,这说明 x
是可行点,但 x
附近的有限差分总是导致不可行点。在这种情况下,求解器可能会失败或过早停止。提供梯度可允许求解器继续。
在文件中为目标函数和非线性约束函数提供梯度或雅可比矩阵。有关语法的详细信息,请参阅编写标量目标函数、编写向量和矩阵目标函数和非线性约束。
要检查梯度或雅可比函数是否正确,请使用 checkGradients
函数,如检查梯度或雅可比矩阵的有效性中所述。
如果您有 Symbolic Math Toolbox™ 许可证,您可以通过编程方式计算梯度和黑塞矩阵。有关示例,请参阅使用 Symbolic Math Toolbox 计算梯度和 Hessian。
有关使用梯度和雅可比矩阵的示例,请参阅使用梯度和黑塞矩阵的最小化、带梯度的非线性约束、使用 Symbolic Math Toolbox 计算梯度和 Hessian、求解不含和含雅可比矩阵的非线性系统 和具有雅可比矩阵的大型稀疏非线性方程组。对于基于问题的方法中的自动微分,请参阅自动微分在基于问题的优化中的作用。
9.提供黑塞矩阵
当您提供黑塞矩阵时,求解器的运行通常更可靠,迭代次数也更少。
以下求解器和算法接受黑塞矩阵:
fmincon
interior-point
.将黑塞矩阵编写为一个单独的函数。有关示例,请参阅使用解析黑塞函数的 fmincon 内点算法。fmincon
trust-region-reflective
.通过目标函数的第三个输出给出黑塞矩阵。有关示例,请参阅使用密集结构 Hessian 和线性等式进行最小化。fminunc
trust-region
.通过目标函数的第三个输出给出黑塞矩阵。有关示例,请参阅使用梯度和黑塞矩阵的最小化。
如果您有 Symbolic Math Toolbox 许可证,您可以通过编程方式计算梯度和黑塞矩阵。有关示例,请参阅使用 Symbolic Math Toolbox 计算梯度和 Hessian。要在基于问题的方法中提供黑塞矩阵,请参阅基于问题的工作流中的供应衍生品。
使用 Symbolic Math Toolbox 计算梯度和 Hessian中的示例说明 fmincon
在没有黑塞矩阵的情况下进行 77 次迭代,但在有黑塞矩阵的情况下只进行 19 次迭代。