深入淺出最優(yōu)化(1) 最優(yōu)化問題概念與基本知識

1 最優(yōu)化問題

1.1 什么是最優(yōu)化問題

最優(yōu)化問題大體上分為連續(xù)最優(yōu)化問題和離散最優(yōu)化問題兩種祠丝。后者涉及到離散數(shù)學(xué)、組合數(shù)學(xué)等學(xué)科装哆,屬于計(jì)算機(jī)專業(yè)的專業(yè)課程伐厌,而前者的雛形在微積分課程中,甚至在高中褐望、初中勒庄、小學(xué)的數(shù)學(xué)課堂上就有所涉及。

我們還記得求一個(gè)定義域內(nèi)連續(xù)可微的一元實(shí)函數(shù)的最小值點(diǎn)的求解方法:求導(dǎo)瘫里,尋找導(dǎo)數(shù)為0的點(diǎn)实蔽,再求二階導(dǎo),這些點(diǎn)當(dāng)中二階導(dǎo)大于0的點(diǎn)是我們需要的極值點(diǎn)谨读,再將這些極點(diǎn)對應(yīng)的函數(shù)值進(jìn)行對比局装,函數(shù)值最小的點(diǎn)就是我們需要的最小值點(diǎn)。

上述問題就是一個(gè)最基本的最優(yōu)化問題劳殖,但它已經(jīng)充分描述了最優(yōu)化問題的基本目標(biāo):求解函數(shù)的最小值點(diǎn)铐尚。當(dāng)然,求解最大值點(diǎn)的方法也是相同的哆姻,因此我們再討論最優(yōu)化問題時(shí)只討論最小化問題宣增。

若函數(shù)定義域?yàn)?img class="math-inline" src="https://math.jianshu.com/math?formula=R" alt="R" mathimg="1">,則該最優(yōu)化問題為無約束最優(yōu)化問題矛缨。否則爹脾,就是約束最優(yōu)化問題

下面箕昭,針對多元函數(shù)灵妨,我們提出最優(yōu)化問題規(guī)范化的描述。

1.2 名詞與符號

  • 最優(yōu)點(diǎn)x^*
  • 最優(yōu)值f(x^*)
  • 最優(yōu)解(x^*,f(x^*))^T
  • 可行域D落竹,對應(yīng)于基本問題中的定義域
  • 梯度g=\nabla f(x)泌霍,對應(yīng)于基本問題中的一階導(dǎo)數(shù)
  • 黑森矩陣G=\nabla^2f(x),對于n元函數(shù)筋量,(i,j)\quad i,j\in n位置的值為\frac{\partial^2 f(x)}{\partial x_i\partial x_j}烹吵,對應(yīng)于基本問題中的二階導(dǎo)數(shù)
  • 局部最優(yōu)解:在x^*附近一個(gè)鄰域內(nèi)f(x^*)最小碉熄,對應(yīng)基本問題中的極值點(diǎn)
  • 全局最優(yōu)解:在D內(nèi)f(x^*)最小,對應(yīng)基本問題中的最小值點(diǎn)

1.3 最優(yōu)解條件

  1. 一階必要條件:f(x)一階連續(xù)可微且g^*=\nabla f(x^*)=0x^*為f(x)的局部最優(yōu)解的必要條件肋拔。滿足g^*=\nabla f(x^*)=0的點(diǎn)稱為駐點(diǎn)锈津。駐點(diǎn)分為:極小點(diǎn),極大點(diǎn)凉蜂,鞍點(diǎn)
在這里插入圖片描述

僅從三維空間來看琼梆,梯度為0的幾何意義是該處曲面水平。當(dāng)然這個(gè)曲面還可以拓展到更高維的空間中窿吩,在此不再贅述

  1. 二階充分條件:f(x)二階連續(xù)可微且\nabla f(x^*)=0, \nabla^2f(x^*)正定茎杂,是x^*為f(x)的嚴(yán)格局部最優(yōu)解的充分條件。如果說一階條件刻畫了f(x)在x處切平面的法向纫雁,二階條件就刻畫了曲面的彎曲方向煌往,而\nabla^2f(x^*)正定代表了此處曲面向上彎曲

以上兩個(gè)條件雖然拓展到了高維,但實(shí)際上和一元函數(shù)最優(yōu)化問題的條件是通過1.2中給出的對應(yīng)關(guān)系對應(yīng)的轧邪,結(jié)合起來就不難理解

2 用計(jì)算機(jī)求解問題

2.1 迭代搜索

我們最終的目標(biāo)是要實(shí)現(xiàn)讓計(jì)算機(jī)代替我們?nèi)ふ易顑?yōu)化問題的解刽脖。我們不能指望計(jì)算機(jī)具有和我們一樣的智能、對于一個(gè)方程可以使用人類總結(jié)出來的諸如分離變量之類的各種方法去求解忌愚。我們只能使用數(shù)值方法曲管,通過循環(huán)迭代解出一個(gè)逼近于最優(yōu)解的答案。這個(gè)過程稱為迭代搜索硕糊。

我們考慮如圖所示的一個(gè)三維曲面院水,x_k是當(dāng)前我們所在點(diǎn)。假如這個(gè)點(diǎn)不是我們需要的最優(yōu)解简十,我們就需要移動到下一個(gè)點(diǎn)檬某。移動需要確定方向和距離,因此我們有迭代搜索的基本元素如下:

  • 步長:迭代搜索第k步的長度螟蝙,用\alpha_k表示

  • 下降方向:迭代搜索第k步的方向橙喘,用d_k表示,沿該方向函數(shù)值需要下降胶逢,這樣才能保證算法的收斂性。其中可行方向表示沿著該方向搜索饰潜,存在使得下一個(gè)點(diǎn)不超出可行域的步長

在這里插入圖片描述
  • 終止準(zhǔn)則:考慮一階必要條件初坠,即\nabla f(x)=0,我們將這個(gè)條件作為迭代終止的準(zhǔn)則彭雾。如果我們當(dāng)前所在點(diǎn)滿足準(zhǔn)則碟刺,就不需要再尋找下一個(gè)點(diǎn)了。當(dāng)然薯酝,對于搜索算法來說半沽,我們不能保證我們一定可以通過有限步的搜索找到精確地滿足\nabla f(x)=0的點(diǎn)爽柒,而我們在實(shí)際工程運(yùn)用中對于最小值點(diǎn)的要求也并非是絕對精確的。因此者填,引入一個(gè)精確度\epsilon浩村,只要梯度滿足||g(x_k)||\leq \epsilon即可認(rèn)為滿足了終止準(zhǔn)則。

根據(jù)基本元素占哟,我們可以得出n元函數(shù)迭代搜索的步驟:

  1. 給出x_0\in R^n,0\leq \epsilon<<1,k=0
  2. 如果在x_k點(diǎn)終止準(zhǔn)則被滿足心墅,停止迭代
  3. 確定x_k點(diǎn)下降方向d_k
  4. 確定步長因子\alpha_k
  5. x_{k+1}=x_k+\alpha_kd_k,轉(zhuǎn)步驟2

2.2 質(zhì)量評估

  1. 收斂性:對于迭代序列x^{(k)}榨乎,嚴(yán)格的收斂定義要求k趨近于正無窮時(shí)等于最優(yōu)點(diǎn)怎燥,弱化的收斂定義要求k趨近于無窮時(shí)一階偏導(dǎo)向量的范數(shù)為0
  2. 收斂速度x^{(k)}為p階收斂,則\displaystyle\lim_{k→∞}\frac{||x^{(k+1)}-x^*||}{||x^{(k)}-x^*||^P}=\beta<+∞
    1. p=1,0<\beta<1蜜暑,則算法線性收斂
    2. p=1,\beta=0铐姚,則算法超線性收斂
    3. p=2,\beta>0,則算法二階收斂肛捍。二階收斂必定超線性收斂隐绵,且二階收斂的算法收斂速度高于線性收斂的算法
  3. 二次終止性:若某個(gè)算法對于任意的正定二次函數(shù),從任意初始點(diǎn)出發(fā)篇梭,都能經(jīng)過有限步迭代達(dá)到極小值氢橙,則稱算法具有二次終止性

一個(gè)可行的收斂算法必須滿足收斂性,收斂速度越快的算法性質(zhì)越好恬偷,而具有二次終止性的算法可以在求解二次函數(shù)最優(yōu)化問題時(shí)具有廣泛的應(yīng)用價(jià)值悍手。但證明這些性質(zhì)并不作為本系列教程的重點(diǎn)。本教程會給出每一種算法性質(zhì)的結(jié)論與相關(guān)證明教程鏈接袍患,有興趣的讀者可以自行查閱

3 最小二乘問題——無約束最優(yōu)化問題實(shí)例

點(diǎn)列的曲線擬合是我們高中開始就接觸過的問題坦康。為了尋找一個(gè)待定系數(shù)的函數(shù),可以以最小的誤差去描述點(diǎn)列诡延,我們需要用到最小二乘法滞欠。有關(guān)最小二乘法可以參閱:https://www.zhihu.com/question/37031188

最小二乘法是我們研究無約束最優(yōu)化問題的一個(gè)出色的實(shí)例。它具有廣泛的應(yīng)用價(jià)值肆良,而且目標(biāo)函數(shù)的局部最優(yōu)解就是全局最優(yōu)解筛璧。我們在接下來的無約束最優(yōu)化問題部分將針對一個(gè)最小二乘法例題進(jìn)行研究。

例題:

min\displaystyle\sum_{i=1}^{11}(y_i-\hat{f}(x,t_i))^2,\hat{f}(x,t)=\frac{x_1(t^2+x_2 t)}{t^2+x_3t+x_4}

在這里插入圖片描述

給出了11組(t_i,y_i)的數(shù)據(jù)惹恃,要求我們通過最小二乘法解出x_i,i\in1,2,3,4夭谤,使得函數(shù)\hat{f}(x,t)可以最好地?cái)M合y=f(t)

代碼實(shí)現(xiàn)

本博客所有代碼在https://github.com/HarmoniaLeo/optimization-in-a-nutshell開源,如果幫助到你巫糙,請點(diǎn)個(gè)star朗儒,謝謝這對我真的很重要!

本次代碼實(shí)現(xiàn)內(nèi)容是梯度、梯度二范數(shù)醉锄、黑森矩陣等最優(yōu)化問題基本件的python數(shù)值解法乏悄,以及簡化的python線性代數(shù)庫

梯度、梯度二范數(shù)恳不、黑森矩陣求法參考自博客檩小,有修改:https://www.cnblogs.com/kisetsu/p/9145393.html

制作一個(gè)文件Fuction.py,在里面寫入:

import numpy as np

class Function:
    def __init__(self, _f):
        self.fun = _f

    def value(self, val):
        return self.fun(val)

    def part(self, var_index, val):
        a = self.fun(val)
        b = a + 1
        i = 0
        e = 2 ** 10 - 1
        e1 = 2 ** 10
        while 10 ** (-6) < e < e1 or i > -6:
            e1 = e
            a = b
            val_ = list(val)
            val_[var_index] += 10 ** i
            m = self.fun(val_)
            n = self.fun(val)
            b = (m - n) / 10 ** i
            i -= 2
            e = abs(b - a)
        return a

    def part_2(self, x_index, y_index, val):
        return self.__diff_(x_index).__diff_(y_index).value(val)

    def diff(self, val):
        a = self.fun(val)
        b = a + 1
        i = 0
        e = 2 ** 10 - 1
        e1 = 2 ** 10
        while 10 ** (-6) < e < e1 or i > -6:
            e1 = e
            a = b
            val_ = val + 10 ** i
            m = self.fun(val_)
            n = self.fun(val)
            b = (m - n) / 10 ** i
            i -= 2
            e = abs(b - a)
        return a

    def grad(self, val):
        g = np.array(val).astype('float')
        for i in range(0, g.size):
            g[i] = self.part(i, val)
        return np.array(g)

    def __diff_(self, index):
        def diff_f(vals):
            vals_ = list(vals)
            vals_[index] = vals_[index] + 10 ** (-6)
            m = self.fun(vals_)
            n = self.fun(vals)
            return (m - n) / 10 ** (-6)
        return Function(diff_f)

    def hesse(self, val):
        v = np.mat(val)
        G = np.mat(np.dot(v.T, v)).astype('float')
        for i in range(0, v.size):
            for j in range(0, v.size):
                p = self.part_2(i, j, val)
                G[i, j] = p
        G=np.array(G)
        return G
    
    def norm(self, val):
        s = 0
        for x in self.grad(val):
            s += x ** 2
        return np.sqrt(s)

在之后的每個(gè)方法實(shí)現(xiàn)中妆够,我們都會用到Fuction.py

from Function import Function

tar=Function(func)  #func是一個(gè)以列表為參數(shù)的多元函數(shù)
val=tar.val(para)   #傳入?yún)?shù)獲取值
diff=tar.diff(para) #一元函數(shù)求導(dǎo)
part=tar.part(index,para)   #對第index個(gè)參數(shù)求導(dǎo)
grad=tar.grad(para) #求梯度數(shù)組
hesse=tar.hesse(para)   #求hesse陣
norm=tar.norm(para) #求梯度范數(shù)

另外制作一個(gè)文件lagb.py识啦,在里面寫入:

import numpy as np

def turn(a):    #轉(zhuǎn)置
    if len(a.shape)==1:
        a=a.reshape((1,a.shape[0]))
        return a
    else:
        return np.array(np.mat(a).T)

def dot(a,b):   #點(diǎn)乘
    if len(a.shape)==1:
        a=a.reshape((a.shape[0],1))
    if len(b.shape)==1:
        b=b.reshape((b.shape[0],1))
    res=np.array(np.mat(a)*np.mat(b))
    if res.shape==(1,1):
        return res[0][0]
    else:
        if res.shape[1]==1:
            return res.squeeze()
        else:
            return res

def muldot(*args):  #連乘
    res=args[0]
    for i in range(1,len(args)):
        res=dot(res,args[i])
    return res

def rev(a): #求逆
    return np.array(np.mat(a).I)

在之后的每個(gè)方法實(shí)現(xiàn)中,我們也都會用到lagb.py

from lagb import *

#輸入?yún)?shù)可以為向量或矩陣神妹,即numpy創(chuàng)建的數(shù)組
#用numpy創(chuàng)建的一維數(shù)組會默認(rèn)為列向量
a=turn(a)   #求轉(zhuǎn)置
c=dot(a,b)  #點(diǎn)乘颓哮,視情況會返回向量、矩陣鸵荠、數(shù)值
d=dot([a,b,c])  #連續(xù)的點(diǎn)乘
b=rev(a)    #求逆矩陣
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末冕茅,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子蛹找,更是在濱河造成了極大的恐慌姨伤,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件庸疾,死亡現(xiàn)場離奇詭異乍楚,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)届慈,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進(jìn)店門徒溪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人金顿,你說我怎么就攤上這事臊泌。” “怎么了揍拆?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵渠概,是天一觀的道長。 經(jīng)常有香客問我嫂拴,道長播揪,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任筒狠,我火速辦了婚禮剪芍,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘窟蓝。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布运挫。 她就那樣靜靜地躺著状共,像睡著了一般。 火紅的嫁衣襯著肌膚如雪谁帕。 梳的紋絲不亂的頭發(fā)上峡继,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天,我揣著相機(jī)與錄音匈挖,去河邊找鬼碾牌。 笑死,一個(gè)胖子當(dāng)著我的面吹牛儡循,可吹牛的內(nèi)容都是我干的舶吗。 我是一名探鬼主播,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼择膝,長吁一口氣:“原來是場噩夢啊……” “哼誓琼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起肴捉,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤腹侣,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后齿穗,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體傲隶,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年窃页,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了跺株。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,841評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡腮出,死狀恐怖帖鸦,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情胚嘲,我是刑警寧澤作儿,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站馋劈,受9級特大地震影響攻锰,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜妓雾,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一娶吞、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧械姻,春花似錦妒蛇、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽吏奸。三九已至,卻和暖如春陶耍,著一層夾襖步出監(jiān)牢的瞬間奋蔚,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工烈钞, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留泊碑,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓毯欣,卻偏偏與公主長得像馒过,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子仪媒,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評論 2 354