Python梯度下降法

本文主要講解梯度下降算法,以及Python的實現一個簡單的例子

梯度下降法又稱為最速下降法,是 1847 年有數學家柯西提出的,是解析法中最古老的一種,其他解析方法或是它的變形,活受到啟發得到,因此它是最優化方法的基礎。

對于一個無約束問題的目標函數

可微函數

是一階連續可微。由泰勒展開式得到:

泰勒展開式

選取

迭代方程

其中r(gamma)是迭代步長,這就是梯度下降法。當然由于梯度方向是變化最快的放向,取定x的變化方向為梯度的反方向,可以保證迭代速度最快,當然這個算法的缺點就是

  • 只使用一階導數,迭代的速度較慢,控制好步長及初值,否則可能出現迭代不收斂的情況
  • 迭代到靠近極值的時候,迭代的速度減慢
  • 如果函數不是凸函數,則很可能只是局部最優解,而不是全局最優解。當然極值和最值概念,讀者肯定清楚

接下來給一個例子幫助理解:

考慮函數 f(x) = x^2 -3x + 5此函數在x=1.5 時取得最小值為2.75
迭代初值為x(0)=3,迭代步長為r=0.01

f(x) 的梯度即為函數的導數df/dx = 2x - 3
x(n + 1) = x(n) - r df/dx =x(n) - h*(2 x(n) - 3)
x(n + 1) = 0.98 x(n) + 0.03
到此為止,可以通過求解以上數列的通項公式,然后求極限得到最終收斂1.5。在此我使用迭代1000次得到的結果為x=1.5000000008414838說明通過求解橫坐標的收斂值,最終可以得到函數的最小值。

梯度下降法實現的思路:

  • 通過迭代橫坐標最終收斂的值,確定函數取得極值的橫坐標。
  • 迭代前后函數值的差小于某一個指定常數eps,如|f(x) - f(x0)| < eps,則跳出循環,否則繼續迭代方程

下面給出兩種實現方法的Python代碼

def grad_dec(eps=1e-8, delta=0.001):
    """
    :param eps: 函數值誤差
    :param delta: 迭代步長
    """
    x0 = 3.0
    f = lambda a: a * a - 3.0 * a + 5.0
    while True:
        x = x0 - delta * (2.0 * x0 - 3.0)
        if abs(x - x0) < eps: # 指定橫坐標收斂跳出循環
            break
        x0 = x
    print(x, f(x))


if __name__ == '__main__':
    grad_dec()

輸出結果為:
1.500004984618336  2.7500000000248463
def grad_dec(eps=1e-8, delta=0.001):
    """
    :param eps: 函數值誤差
    :param delta: 迭代步長
    """
    x = 3.0
    f = lambda a: a * a - 3.0 * a + 5.0
    while True:
        f_start = f(x)
        x = x - delta * (2.0 * x - 3.0)
        f_end = f(x)
        if f_start - f_end < eps:
            break
    print(x, f(x))


if __name__ == '__main__':
    grad_dec()

輸出結果為:
1.5015783203943125  2.750002491095267

仔細看程序,及輸出的精度,你會發現什么?

我是邊學邊寫筆記,如果寫的不好的地方,請大神指出。(限于markdown輸出LaTeX數學公式不是很方便,所以給出公式不是很多)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容