因为导师的要求,正在学习数值优化,尤其是其中凸优化的内容。
此文将作为学习过程后的总结,并可能放一些写好的代码。
什么是数值优化
其实生活中数值优化并不少见,不如说到处都是。比如开包子店的老板希望自己一天卖出去的包子的利润最大,也就是:
f(x)表示包子老板赚到的利润,其中x是一个向量,代表跟利润相关的变量,比如工作时间,猪肉价格等等。A表示这些条件所在的范围,比如很显然工作时间和猪肉价格肯定是大于0的。对于数值优化问题,我们往往不会写成一个求maximum的形式,所以我们可以将上面的公式这样写:
实际上约束A也是可以细分的,比如time>=0,originalPrice>=0等等
一般将上述问题称为优化问题,将-f(x)称为目标函数,其中的x称为设计点,设计点可以包含多个设计变量,将A称为约束,代表对设计点x的限制,其中可以是等式也可以是不等式。
那么数值优化的工作就是在A中找到一个设计点x*,使得-f(x*)取得最小值。
那么问题来了,该怎么找到这个最小值点,或者换个说法,哪些点可能是最小值点?
关键点
上过高中的朋友想必明白,求一个函数的最值,往往就是在求这个函数的极值,也就是求那些导函数为0的点。
但导函数为0的点并不一定是最值点,甚至可能并不是极值点。
不是最值点很好理解,因为最值可能出现在边界上,或者有多个极值点,形如下图,显然x*并不是最值点。对于不是最小值的极值点我们称之为局部最小值点,对于最小值点我们则称之为全局最小值点。
但不是极值点呢?
首先需要知道极值点的定义:对于一个点x*,若使得
且满足
的x均有f(x*)<=f(x),我们称之为极小值点,若均有f(x*)>=f(x),我们称之为极大值点。
因为数值优化总是求minimum的过程,因此这里只考虑极小值点的选取。
对于极小值点,定义说明不仅仅要求导函数为0,(x*-δ,x*+δ)区间内的值也要大于f(x*),注意这里的δ是可以无限取接近于0的。因此x^3的导函数为0的点不是极值点,形如下图
f(x*-δ)<f(x*),不是极小值点,同理,也不是极大值点,我们称这类点为鞍点。观察到该点左右的二阶导符号相反,因此该点也是拐点。注意,拐点并不要求一阶导为0。
对于f(x*-δ)=f(x*)=f(x*+δ),形如下图,我们称该点为弱极值点,若满足极值点定义并去掉等号则为强极值点。
由上面的例子我们知道了导函数为0的点不但不一定是最值点,甚至不一定是极值点。同时,我们称导函数为0的点为驻点,驻点包括极值点和鞍点。
对于单变量的情况,我们需要一个点的一阶导数等于0且二阶导数大于0才能确定该点是极小值点,若二阶导也为0,就需要一直求n阶导到不为0,若n是偶数且n阶导大于0,该点才为极小值点。
对于多变量的情况,类似的,当该点的偏导均为0,且该点的hessian矩阵正定的时候该点为极小值点。若该点的hessian矩阵负定,说明该点为极大值点。若该点的hessian矩阵不定,则为鞍点。
形如下图,依次是局部极大值,鞍点和局部极小值。
如下图所示,为hessian矩阵,可以理解成多变量函数的二阶导,也是一阶梯度的jacobian矩阵:
至于正定,负定,矩阵之类的线性代数概念,可以自行搜索学习。
待编辑更新