罗兰对MATLAB的艺术

将想法转化为MATLAB

请注意

罗兰对MATLAB的艺术已退役,不会更新。

自动分化优化工具箱™

本专栏由Alan Weiss撰写,他是Optimization Toolbox文档的作者。把它拿走,艾伦。

嗨,各位。你可能知道,解决一个优化问题,也就是找到一个函数最小的点,当你有函数的梯度时,会更容易。这很容易理解:梯度指向上坡,所以如果你朝相反的方向行进,你通常会到达一个最小值。优化工具箱算法基于比这更复杂的算法,然而这些更复杂的算法也受益于梯度。

如何在求解函数的同时给出一个梯度呢?直到最近,您还必须将梯度作为单独的输出来计算,这带来了所有的痛苦和错误的可能性。然而,在R2020b中,基于问题的方法使用自动微分来计算一般非线性优化问题的问题梯度。我将解释所有这些词的意思。简而言之,只要你的函数是由多项式、三角函数和指数等初等函数组成的,最优化工具箱就会自动计算和使用你的函数的梯度,而不需要你付出任何努力。

“一般非线性”一词的意思是自动微分适用于以下问题fminconfminunc求解,这是一般的约束或无约束最小化,而不是线性规划或最小二乘或其他问题类型调用其他专门的求解器。

自动微分,也称为AD,是一种符号导数,它将函数转换为计算特定点的函数值和导数值的代码。这个过程是透明的;您不需要编写任何特殊的代码来使用AD。实际上,正如您稍后将看到的,您必须指定一些名称-值对,以便不让求解器使用AD。

内容

具体问题具体分析优化

基于问题的优化方法是根据优化变量和表达式来编写问题。例如,为了最小化单元磁盘$x^2+y^2\le 1$中的测试函数${\rm fun}(x,y) = 100(y-x^2)^2 + (1-x)^2$,您首先创建优化变量。

X = optimvar()“x”);Y = optimvar()“y”);

然后使用这些变量创建优化表达式。

Fun = 100*(y - x^2)^2 + (1 - x)^2;Unitdisk = x^2 + y^2 <= 1;

在适当的问题字段中使用这些表达式创建一个优化问题。

问题=最优问题“客观”有趣的,“约束”, unitdisk);

通过打电话来解决问题解决,从x = 0, y = 0开始。

x0。X = 0;x0。Y = 0;Sol = solve(prob,x0)
使用fmincon解决问题。找到满足约束的局部最小值。由于目标函数在可行方向上不减小,优化完成到最优性容限范围内,约束满足到约束容限范围内。Sol = struct with fields: x: 0.7864 y: 0.6177

解决函数调用fmincon解决问题。事实上,解决使用AD来加快解决方案的过程。让我们更详细地研究解决方案过程,看看它是如何工作的。但首先,在单位圆盘上画出1加上目标函数的对数,在解处画一个红圈。

[R,TH] = ndgrid(linspace(0,1,100),linspace(0,2*pi,200));[X,Y] = pol2cart(TH,R);surf(X,Y,log(1+100*(Y - X) ^2)²+ (1 - x)²)“EdgeColor”“没有”) colorbar视图(0,90)轴平等的持有plot3 (sol.x sol.y 1,“罗”“MarkerSize”, 10)

自动分化效应

要更详细地检查解决过程,请再次解决问题,这次要求更多解决输出。检查求解器执行的迭代次数和函数求值。

[sol,fval,exitflag,output] = solve(prob,x0);流(fmincon需要%g次迭代和%g次函数求值。\noutput.iterations output.funcCount)
使用fmincon解决问题。找到满足约束的局部最小值。由于目标函数在可行方向上不减小,优化完成到最优性容限范围内,约束满足到约束容限范围内。Fmincon需要24次迭代和34次函数求值。

输出结构显示求解器进行了24次迭代和34次函数计数。再次运行该问题,这一次强制求解器不使用AD。

[sol2,fval2,exitflag2,output2] = solve(prob,x0,“ObjectiveDerivative”“有限差分”“ConstraintDerivative”“有限差分”);流(fmincon需要%g次迭代和%g次函数求值。\noutput2.iterations,output2.funcCount) plot([1 2],[output. count])funcCount output2.funcCount),的r -[1 - 2],[输出。funcCount output2.funcCount),“罗”) ylabel (函数计算的) xlim([0.8 2.2]) ylim([0.90]) legend(“功能计数(越低越好)”“位置”“西北”) ax = gca;斧子。XTick = [1,2];斧子。XTickLabel = {“广告”没有广告的};
使用fmincon解决问题。找到满足约束的局部最小值。由于目标函数在可行方向上不减小,优化完成到最优性容限范围内,约束满足到约束容限范围内。Fmincon需要24次迭代和84次函数求值。

这一次求解器需要84个函数计数,而不是34个。产生这种差异的原因是自动分化。

有或没有金宝搏官方网站AD的解决方案几乎是一样的:

流(“溶液差的范数是%g.\n”、规范([sol.x,索尔。[sol2.x,sol2.y]))
解差的范数为1.80128e-09。

什么是自动区分?

AD类似于符号微分:对每个函数本质上进行符号微分,并将结果转化为MATLAB运行计算导数的代码。查看结果代码的一种方法是使用prob2struct函数。让我们试穿一下概率

问题= prob2struct(prob);problem.objective
ans = function_handle with value: @ generatedobjobjective

prob2struct创建一个函数文件generatedObjective.m。这个函数包括一个自动生成的梯度。查看函数文件的内容。

函数[obj, grad] = generatedobjects (inputVariables)计算目标函数值和梯度% OBJ = generatedoobjective (INPUTVARIABLES)计算目标值% OBJ在INPUTVARIABLES点。% [OBJ, GRAD] = generatedoobjective (INPUTVARIABLES)额外计算%当前点的目标梯度值GRAD。%由prob2struct于2020年10月6日09:01:35自动生成%%变量索引。Xidx = 1;Yidx = 2;%%将基于求解器的变量映射为基于问题的变量。x = inputVariables(xidx);y = inputVariables(yidx);%%计算目标函数。Arg1 = (y - x ^2);Arg2 = 100;Arg3 = arg1.^2;= (1 - x);Obj = ((arg2 .* arg3) + arg4.^2);%%计算目标梯度。如果Nargout > 1 arg5 = 1;= 0 ([2,1]);arg6 (xidx:) = (- (arg5。* 2 * (arg4 (:)))) + ((-(( arg5。*最长(:))。* 2 * (__arg1(:))))。* 2 * (x (:)));Arg6 (yidx,:) = (arg5.*arg2(:)).*2.*(arg1(:)));Grad = arg6(:);结束结束

虽然这段代码对你来说可能不太清楚,但你可以将AD梯度计算与符号表达式进行比较,看看它们是相同的:

美元\微分算符({\ rm乐趣})= [-400 (x ^ 2) x - 2 (1 - x); \ 200 (x ^ 2)]美元

这种方式解决prob2struct将优化表达式转换为代码本质上与微积分学生学习的方式相同,取表达式的每个部分并应用微分规则。计算梯度的详细过程在自动鉴别背景,它描述了大多数AD软件使用的“向前”和“向后”进程。目前,优化工具箱只使用“向后”AD。

为了使用这些微分规则,软件必须对目标函数或约束函数中的每个函数都有微分规则。支持的运算符列表包括多项金宝app式、三角函数和指数函数及其逆,以及乘法和加法及其逆。看到金宝app支持的优化变量和表达式操作

自动区分有什么好处?

AD降低了求解器计算函数的次数。没有AD,非线性解算器通过有限差分估计梯度,例如$(f(x+\delta e_1) - f(x))/\delta,其中$e_1$是单位向量(1,0,…,0)。求解器计算n默认为这种形式的有限差分,其中n是问题变量的个数。对于有大量变量的问题,这个过程需要大量的函数求值。

使用AD和支持的函数,求金宝app解器不需要执行有限差分步骤,因此导数估计过程所需的函数评估更少,更准确。

这并不是说AD总是能够加速解算器。对于复杂的表达式,计算自动导数可能比计算有限差分更耗时。通常,当问题有大量变量且稀疏时,AD比有限差分更快。当问题变量少、函数复杂时,AD速度较慢。

不支持的操作怎么办?金宝app

到目前为止,我已经讨论了支持操作的自动微分。金宝app如果您有一个黑盒函数,其底层代码甚至可能不在MATLAB中,该怎么办?或者,如果您只是有一个不支持基于问题的优化的函数,比如贝塞尔函数,该怎么办?金宝app为了在基于问题的方法中包含这样的函数,可以使用fcn2optimexpr函数。例如,使用besselj函数,

fun2 = fcn2optimexpr (@ (x, y) besselj (1, x ^ 2 + y ^ 2), x, y);

fcn2optimexpr允许您在基于问题的方法中使用不受支持的操金宝app作。然而,fcn2optimexpr不支持AD。金宝app所以,当你使用fcn2optimexpr,使用有限差分来估计目标或非线性约束函数的梯度来解决由此产生的问题。有关更多信息,请参见在基于问题的工作流中提供衍生品

目前,AD不支持高阶导数。金宝app换句话说,您不能自动生成二阶或三阶导数的代码。你只能得到一阶导数(梯度)

最终的想法

在解决仅由支持的函数组成的优化问题时,AD有助于提高速度和可靠性。金宝app然而,在某些情况下,它并不能提高速度,并且目前AD还不能用于非线性最小二乘或方程求解问题。

在我看来,AD最有用的特性是在基于问题的优化中使用它是完全透明的。从R2020b开始,AD自动应用,无需您的任何努力。如果您发现它对解决您的优化问题有用,请发表评论,让我们知道在这里




用MATLAB®R2020b发布

|
  • 打印
  • 发送电子邮件