最速下降方法和Newton方法


《Convex Optimization》

最速下降方法

\(f(x+v)\)\(v=0\)處的一階泰勒展開為:

\[f(x+v)\approx \hat{f}(x+v) = f(x) + \nabla f(x)^{T}v \]

\(\nabla f(x)^{T}v\)\(f\)\(x\)處沿\(v\)的方向導數。它近似給出了\(f\)沿小的步徑\(v\)會發生的變化。
\(v\)的大小固定的前提下,討論如何選擇\(v\)使得方向導數最小是有意義的,即:

\[\Delta x_{nsd}= argmin\{\nabla f(x)^{T}v \:|\: \|v\|=1\} \]

最速下降方向就是一個使\(f\)的線性近似下降最多的具有單位范數的步徑。注意,這里的單位范數,並不局限於Euclid范數。
我們先給出最速下降方法的算法,再介紹幾種范數約束。
在這里插入圖片描述

Euclid范數和二次范數

Euclid范數

顯然,這時的方向就是負梯度方向。

二次范數

我們考慮二次范數

\[\|z\|_P=(z^TPz)^{1/2}=\|P^{1/2}z\| \]

其中P為n階對稱正定矩陣。

這時的最優解為:

\[\Delta x_{nsd}=-(\nabla f(x)^{T}P^{-1}\nabla f(x))^{-1/2}P^{-1}\nabla f(x) \]

這個最優解,可以通過引入拉格朗日乘子,求解對偶函數KKT條件獲得,並不難,就不寫了。

基於坐標變換的解釋

二次范數,可以從坐標變換的角度給出一個解釋。
我們定義線性變換:

\[\bar{u}=P^{1/2}u \]

那么:

\[g(\bar{u})=f(P^{-1/2}\bar{u})=f(u) \]

\(g\)\(\bar{x}\)出的負梯度方向為:

\[\Delta \bar{x}=-\nabla \bar{f}(\bar{x})=-P^{-1/2}\nabla f(P^{-1/2}\bar{x})=-P^{-1/2}\nabla f(x) \]

注意,並沒有歸一化。
又,我們已經知道\(\Delta x = -P^{-1} \nabla f(x)\)(只是方向而已),所以:

\[\Delta \bar{x}=P^{1/2}\Delta x \]

同樣的線性變換。換言之,二次范數\(\|\cdot\|_P\)下的最速下降方向可以理解為對原問題進行坐標變換\(\bar{x}=P^{1/2}x\)后的梯度方向。輔以下圖便於理解。
二次范數

采用\(\ell_1\)-范數的最速下降方向

這個問題的刻畫如下:

\[\Delta x_{nsd}=argmin\{\nabla f(x)^Tv \: | \: \|v\|_1=1\} \]

\(\ell_1\)即各分量絕對值之和,所以,只需把\(\nabla f(x)\)絕對值分量最大的那個部分找出來即可。不妨設,第\(i\)個分量就是我們要找的,那么:

\[\Delta x_{nsd}=-sign(\frac{\partial f(x)}{\partial x_i})e_i \]

其中,\(e_i\)表示第\(i\)個基向量。
所以,在每次下降過程中,都只是改變一個分量,所以\(\ell_1\)-范數的下降,也稱為坐標下降算法。
輔以下圖以便理解:
l1范數

至於收斂性分析,與先前的相反,我們不在這里給出(打起來太麻煩了實際上,有需求直接翻書就好了)。

數值試驗

我們依然選擇\(f(x)=e^{x_1+3x_2-0.1}+e^{x_1-3x_2-0.1}+e^{-x_1-0.1}\)\(\alpha=0.2,\beta=0.7\),初始點為\((7, 3)\),下圖為我們展示了一種較為極端的坐標下降的方式。
在這里插入圖片描述

代碼只需要改變gradient2的幾行而已。

def gradient2(x):
    x0 = x[0]
    x1 = x[1]
    grad1 = np.exp(x0+3*x1-0.1) \
            + np.exp(x0-3*x1-0.3) \
            - np.exp(-x0-0.1)
    grad2 = 3 * np.exp(x0+3*x1-0.1) \
            -3 * np.exp(x0-3*x1-0.3)
    if abs(grad1) > abs(grad2):
        return np.array([grad1/abs(grad1),0])
    else:
        return np.array([0, grad2/abs(grad2)])

Newton 方法

最開始看的時候,還很疑惑,后來才發現,原來這個方法在很多地方都出現過。除了《凸優化》(《Convex Optimization》),數學分析(華師大)和托馬斯微積分都講到過。雖然,或者將的一元的特殊情況,而且,后者的問題是尋找函數的零值點。起初,還不知道怎么把倆者聯系起來,仔細一想,導函數的零值點不就是我們所要的嗎?當然,得要求函數是凸的。

實際上,Newton方法是一種特殊的二次范數方法。特殊在,\(P\)的選取為Hessian矩陣\(\nabla^2 f(x)。\)我們還沒有分析,二次范數的\(P\)應該如何選擇。在下降方法的收斂性分析中,我們強調了條件數的重要性。加上剛剛分析過的坐標變換,坐標變換后,新的Hessian矩陣變為:

\[P^{-1/2}\nabla^2 f(x)P^{-1/2} \]

所以,如果我們取\(P =\nabla^2f(x^*)\),那么新的Hessian矩陣在最有點附近就近似為\(I\),這樣就能保證快速收斂。如果,每次都能選擇\(P=\nabla^2 f(x)\),這就是Newton方法了。下圖反映了為什么這么選擇會加速收斂:
Hessian范數

Newton 步徑

Newton步徑:

\[\Delta x_{nt}=-\nabla^2 f(x)^{-1}\nabla f(x) \]

則:

\[\nabla f(x)^T\Delta x_{nt}=-\nabla f(x)^T\nabla^2f(x)^{-1}\nabla f(x)<0 \]

因為我們假設Hessian矩陣正定,所以上述不等式在\(\nabla f(x) \ne 0\)時都成立。

二階近似的最優解

\(f(x+v)\)\(v=0\)處的二階近似為:

\[\hat{f}(x+v)=f(x)+\nabla f(x)^Tv+\frac{1}{2}v^T \nabla^2f(x)v \]

這是\(v\)的二次凸函數,在\(v=\Delta x_{nt}\)處到達最小值。下圖即是該性質的一種形象地刻畫:
二階近似的最優解

線性化最優性條件的解

如果我們在\(x\)附近對最優性條件\(\nabla f(x^*)=0\)處進行線性化,可以得到:

\[\nabla f(x+v) \approx \nabla f(x) + \nabla^2 f(x) v=0 \]

這個實際上就是我在最開始對Newton方法的一個解釋。不多贅述。

Newton 步徑的仿射不變性

在這里插入圖片描述

這個在代數里面是不是叫做同構?

Newton 減量

我們將

\[\lambda (x)=(\nabla f(x)^T \nabla^2 f(x)^{-1}\nabla f(x))^{1/2} \]

稱為Newton減量。
有如下的性質:

\[f(x) = \mathop{inf} \limits_{y} \hat{f}(y)=f(x)-\hat{f}(x+\Delta x_{nt})=\frac{1}{2}\lambda (x)^2 \]

\[\lambda (x) = (\Delta x_{nt}^T \nabla^2f(x) \Delta x_{nt})^{1/2} \]

\[\nabla f(x)^T \Delta x_{nt}=-\lambda (x)^2 \]

Newton步徑同樣是仿射不變的。
Newton步徑常常用作停止准則的設計。

Newton 方法

算法如下:

在這里插入圖片描述

收斂性分析

收斂性分為倆個階段,證明比較多,這里只給出結果。

在這里插入圖片描述
第一階段為阻尼Newton階段,第二階段為二次收斂階段。

數值實驗

我們依然選擇\(f(x)=e^{x_1+3x_2-0.1}+e^{x_1-3x_2-0.1}+e^{-x_1-0.1}\)\(\alpha=0.2,\beta=0.7\),初始點為\((7, 3)\),下圖采用牛頓方法的圖(代碼應該沒寫錯吧)。
(7, 3)
下圖初始點為\((-5, 3)\)
(-5, 3)

代碼

def hessian(x):
    x0 = x[0]
    x1 = x[1]
    hessian = np.zeros((2, 2), dtype=float)
    element1 = np.exp(x0 + 3 * x1 - 0.1)
    element2 = np.exp(x0 - 3 * x1 - 0.1)
    element3 = np.exp(-x0 - 0.1)
    hessian[0, 0] = element1 + element2 + element3
    hessian[0, 1] = 3 * element1 - 3 * element2
    hessian[1, 0] = 3 * element1 - 3 * element2
    hessian[1, 1] = 9 * element1 + 9 * element2

    return np.linalg.inv(hessian)

下降方法也修改了一下:

    def grad3(self, gradient, alpha, beta, error=1e-5):
        """回溯直線收縮算法 Newton步徑
        gradient: 梯度需要給出
        alpha: 下降的期望值 (0, 0.5)
        beta:每次更新的倍率 (0, 1)
        error: 梯度的誤差限,默認為1e-5
        """
        assert hasattr(gradient, "__call__"), \
            "Invalid gradient"
        assert 0 < alpha < 0.5, \
            "alpha should between (0, 0.5), but receive {0}".format(alpha)
        assert 0 < beta < 1, \
            "beta should between (0, 1), but receive {0}".format(beta)
        error = error if error > 0 else 1e-5

        def search_t(alpha, beta, grad, hessian_inv):
        	"""回溯"""
            t = 2
            t_old = 2
            step = grad @ hessian_inv
            grad_module = grad @ step
            assert grad_module >= 0, "wrong in grad_module"
            while True:
                newx = self.x + t * step
                newy = self.__f(newx)
                if newy < self.y - alpha * t * grad_module: 
                    return t_old
                else:
                    t_old = t
                    t = t_old * beta
        while True:
            grad = -gradient(self.x)
            hessian_inv = hessian(self.x)
            t = search_t(alpha, beta, grad, hessian_inv)
            x = self.x + t * grad @ hessian_inv
            lam = grad @ hessian_inv @ grad
            if lam / 2 < error: #判別准則變了
                break
            else:
                self.x = x
                self.y = self.__f(self.x)
                self.__process.append((self.x, self.y))


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM