1. 程式人生 > >機器學習:梯度下降和牛頓法

機器學習:梯度下降和牛頓法

一、問題描述

考慮將基本梯度下降和牛頓法應用到表中的資料上。

(a)用這兩種演算法對二維資料給出 的判別。對梯度下降法取 。畫出以迭代次數為準則函式的曲線。

(b)估計這兩種方法的數學運算量。

(c)畫出收斂時間-學習率曲線。求出無法收斂的最小學習率。

二、演算法核心思想分析

1、線性判別函式

的各個分量的線性組合而成的函式:

這裡 是“權向量”, 被稱為“閾值權”。對於二分類器來說,若 ,則判定為 ,若 ,則判定為 。方程 定義了一個判定面,把兩個類分開,被稱為“超平面”。

2、廣義線性判別函式

線性判別函式 可寫成:

其中係數 是權向量 的分量。通過加入另外的項(

的各對向量之間的乘積),我們得到二次判別函式:

因為 ,不失一般性我們可以假設 。由此,二次判別函式擁有更多係數來產生複雜的分隔面。此時 定義的分隔面試一個二階曲面或說是“超二次曲面”。

若繼續加入更高次的項,我們就得到多項式判別函式。這可看做對某一判別函式 做級數展開,然後取其截尾逼近,此時廣義線性判別函式可寫成:

這裡 通常被稱為“增廣特徵向量”,類似地, 被稱為“增廣權向量”,設 ,可寫成:

對於兩類線性可分的情況,使用判別函式 來劃分 ,若 ,則判定為 ,若 ,則判定為

通常引入邊界裕量 限制解區域,要求解向量滿足:

3、梯度下降

我們在尋找滿足線性不等式組

的解時所採用的方法是:定義一個準則函式 ,當 是解向量時, 為最小。這樣就將問題簡化為一個標量函式的極小化問題——通常可用梯度下降法來解決。梯度下降的原理非常簡單,首先從一個任意選擇的權向量 開始,計算其梯度向量 ,下一個值 由自 向下降最陡的方向移一段距離而得到,即沿梯度的負方向。通常 由等式

計算, 是正的比例因子,或者說是用於設定步長的“學習率”(learning rate)。我們希望得到這樣一個權向量序列:最終收斂到一個使 極小化的解上。

步驟:初始化權向量 、閾值 和學習率 ,不斷迭代更新 ,直到 ,使得準則函式達到一個極小值, 收斂。

4、牛頓法

牛頓法權向量的更新公式為:

其中, 為準則函式的赫森矩陣。收斂條件為:

因為牛頓法使用了準則函式的二次偏導,因此牛頓法比梯度下降每一步都給出了更好的步長,也就更快收斂。但是每次遞迴都要計算赫森矩陣 的逆,時間複雜度為 ,運算量更大。

三、題目分析

1、題目分析

本題表格中給出用於求判別函式中解向量的資料,二維資料 共20組。需要假設用於判別的準則函式,使用梯度下降演算法和牛頓法分別與準則函式結合,求出解向量,從而求得線性判別函式。並畫出以迭代次數為準則函式的曲線。

本題中假設準則函式為:

梯度如下:

其中 為解向量, 為訓練資料, 為邊界裕量。

2、梯度下降

使用LMS演算法進行迭代。學習率設為0.001,閾值設為0.01,沿負梯度方向更新權值,最後畫出【迭代次數-準則函式曲線】、【分類介面】、【學習率-迭代次數曲線】,並得出無法收斂的最小學習率。

3、牛頓法

黑塞矩陣H由準則函式的二階偏導求得,為 ,代入樣本計算即可,將其求逆並與梯度相乘,更新權重。最後畫出【迭代次數-準則函式曲線】和【分類介面】。

4、Notice:

  • 學習率 的選擇對於梯度下降演算法收斂至關重要。如果 太小,收斂將非常慢;如果 太大的話可能會過沖(overshoot),甚至發散。
  • 對於資料的使用需要注意,不是直接利用原始資料進行訓練,而是將原始資料增加一列,將其變成增廣矩陣。
  • 邊界裕量 的取值任意
  • 牛頓法中學習率為 ,所以需要赫森矩陣 是非奇異矩陣。

四、程式碼及執行結果

1、梯度下降

# -*- coding:utf-8 -*-
import xlrd
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False


# 讀取資料
def read_data():
    x = []
    data = xlrd.open_workbook("lab4_data.xlsx")
    table = data.sheets()[0]
    rows = table.nrows
    for i in range(1, rows):
        row_value = table.row_values(i)
        if row_value[2] == 1 or row_value[2] == 3:
            x.append(row_value)
    return x


# 準則函式
def get_j(a, b, y):
    j = 0.5 * np.power(np.linalg.norm((y * a - b)), 2)
    print("j", j)
    return j


# 準則函式的梯度
def get_gradient(a, b, y):
    gradient = y.T * (y * a - b)
    print("gradient", np.shape(gradient), "\n", gradient)
    return gradient


# 權向量的變化
def get_delta(eta, a, b, y):
    gradient = get_gradient(a, b, y)
    delta = eta * gradient
    print("delta", np.shape(delta), "\n", delta)
    return delta


# 解向量
def get_a(a_k, delta):
    a = a_k - delta
    print("a", np.shape(a), "\n", a)
    return a


# 線性判別函式
def get_gx(a, y):
    gx = a.T * y
    return gx


# 梯度下降:傳入學習率,返回收斂時間、準則函式
def gradient_decent(eta, a, b, y, theta):
    iteration = []
    J = []
    count = 0
    loop_max = 100

    j = get_j(a, b, y)
    print("(", count, j, ")")
    iteration.append(count)
    J.append(j)
    delta = get_delta(eta, a, b, y)
    while np.linalg.norm(delta) >= theta:
        count += 1
        if count >= loop_max:
            print("break!")
            break
        delta = get_delta(eta, a, b, y)
        a = get_a(a, delta)  # 更新a
        j = get_j(a, b, y)
        iteration.append(count)
        J.append(j)
        print("(", count, j, ")")

    return iteration, J


def main():
    data = read_data()
    # print("data\n", np.mat(data))
    w = [x[:2] for x in filter(lambda x: x, data)]
    y = list(map(lambda x: [1, *x], w))
    # print("y\n", np.mat(y))

    # 規範化
    w1 = [x[:2] for x in filter(lambda x: x[2] == 1, data)]
    w3 = [x[:2] for x in filter(lambda x: x[2] == 3, data)]
    test = []
    for i in range(len(w1)):
        w1[i].insert(0, 1)
        test.append(w1[i])
    # w3 = (-1 * np.mat(w3)).tolist()
    for i in range(len(w3)):
        w3[i].insert(0, -1)
        test.append(w3[i])
    print(np.mat(test))
    y = test

    # initial
    a = [1, 1, 1]  # 權向量a
    theta = 0.01  # 閾值θ
    eta = 0.001  # 學習率η
    b = [1 for i in range(len(y))]  # 邊界裕量

    y = np.mat(y)
    a = np.mat(a).T
    b = np.mat(b).T

    print("y", np.shape(y), "\n", y)
    print("a", np.shape(a), "\n", a)
    print("b", np.shape(b))  # , "\n", b

    # Gradient Decent
    fig1 = plt.figure(1)

    iteration, J = gradient_decent(eta, a, b, y, theta)
    plt.plot(iteration, J)  # 準則函式

    plt.title(u"學習率η = " + str(eta))
    plt.xlabel(u"迭代次數")
    plt.ylabel(u"準則函式")

    # 繪製樣本點
    fig2 = plt.figure(2)
    w1 = [x[:2] for x in filter(lambda x: x[2] == 1, data)]
    w3 = [x[:2] for x in filter(lambda x: x[2] == 3, data)]
    w1x1 = [x[0] for x in filter(lambda x: x, w1)]
    w1x2 = [x[1] for x in filter(lambda x: x, w1)]
    w3x1 = [x[0] for x in filter(lambda x: x, w3)]
    w3x2 = [x[1] for x in filter(lambda x: x, w3)]

    plt.scatter(w1x1, w1x2, c='r')
    plt.scatter(w3x1, w3x2, c='g')
    plt.xlabel("x1")
    plt.ylabel("x2")
    plt.title(u"分類介面")

    # # 準則函式分隔面
    x = [np.linspace(-5.1, 6.8, 100)]  # [1 for i in range(len(y))],
    x = np.mat(x).T

    x2 = (a[0, 0] + a[1, 0] * x) / a[2, 0]
    plt.plot(x, x2)

    # 學習率-收斂時間
    fig3 = plt.figure(3)
    learn_rate = [0.0005, 0.001, 0.0015, 0.002, 0.0025, 0.003, 0.0035, 0.004, 0.0045, 0.005, 0.0055]
    convergence = []
    for i in range(len(learn_rate)):
        iteration, J = gradient_decent(learn_rate[i], a, b, y, theta)
        convergence.append(iteration[-1])

    print(learn_rate, "\n", convergence)
    plt.plot(learn_rate, convergence)
    for xy in zip(learn_rate, convergence):
        plt.annotate("(%s,%s)" % xy, xy=xy, xytext=(-20, 10), textcoords='offset points')
    plt.xlabel(u"學習率")
    plt.ylabel(u"收斂時間")
    plt.title(u"學習率-收斂時間")

    plt.show()


if __name__ == '__main__':
    main()

【迭代次數-準則函式曲線】

學習率為0.001時,在所設閾值下,梯度下降16次收斂

【分類介面】

權向量為[ 0.73775053 -0.19529194 0.23079494 ]

可以看到LMS演算法並未給出最優解

【學習率-迭代次數曲線】

當學習率達到0.0045左右時,梯度下降無法收斂

2、牛頓法

# -*- coding:utf-8 -*-
import xlrd
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False


# 讀取資料
def read_data():
    x = []
    data = xlrd.open_workbook("lab4_data.xlsx")
    table = data.sheets()[0]
    rows = table.nrows
    for i in range(1, rows):
        row_value = table.row_values(i)
        if row_value[2] == 1 or row_value[2] == 3:
            x.append(row_value)
    return x


# 準則函式
def get_j(a, b, y):
    j = 0.5 * np.power(np.linalg.norm((y * a - b)), 2)
    print("j", j)
    return j


# 準則函式的梯度
def get_gradient(a, b, y):
    gradient = y.T * (y * a - b)
    print("gradient", np.shape(gradient), "\n", gradient)
    return gradient


# 權向量的變化
def get_delta(H, a, b, y):
    gradient = get_gradient(a, b, y)
    delta = H * gradient
    print("delta", np.shape(delta), "\n", delta)
    return delta


# 解向量
def get_a(a_k, delta):
    a = a_k - delta
    print("a", np.shape(a), "\n", a)
    return a


# 線性判別函式
def get_gx(a, y):
    gx = a.T * y
    return gx


def newton(H, a, b, y, theta):
    iteration = []
    J = []
    count = 0
    loop_max = 100

    j = get_j(a, b, y)
    print("(", count, j, ")")
    iteration.append(count)
    J.append(j)
    delta = get_delta(H, a, b, y)
    while np.linalg.norm(delta) >= theta:
        count += 1
        if count >= loop_max:
            print("break!")
            break
        delta = get_delta(H, a, b, y)
        a = get_a(a, delta)  # 更新a
        j = get_j(a, b, y)
        iteration.append(count)
        J.append(j)
        print("(", count, j, ")")
    return iteration, J


def main():
    data = read_data()
    # print("data\n", np.mat(data))
    w = [x[:2] for x in filter(lambda x: x, data)]
    y = list(map(lambda x: [1, *x], w))
    # print("y\n", np.mat(y))

    # 規範化
    w1 = [x[:2] for x in filter(lambda x: x[2] == 1, data)]
    w3 = [x[:2] for x in filter(lambda x: x[2] == 3, data)]
    test = []
    for i in range(len(w1)):
        w1[i].insert(0, 1)
        test.append(w1[i])
    # w3 = (-1 * np.mat(w3)).tolist()
    for i in range(len(w3)):
        w3[i].insert(0, -1)
        test.append(w3[i])
    print(np.mat(test))
    y = test

    # initial
    a = [1, 1, 1]  # 權向量a
    theta = 0.001  # 閾值θ
    H = 0  # 學習率 黑塞矩陣的逆
    b = [1 for i in range(len(y))]  # 邊界裕量

    y = np.mat(y)
    a = np.mat(a).T
    b = np.mat(b).T

    print("y", np.shape(y), "\n", y)
    print("a", np.shape(a), "\n", a)
    print("b", np.shape(b))  # , "\n", b

    H = (y.T * y).I
    print("H", H)

    fig1 = plt.figure(1)

    iteration, J = newton(H, a, b, y, theta)
    plt.plot(iteration, J)  # 準則函式

    plt.xlabel(u"迭代次數")
    plt.ylabel(u"準則函式")
    plt.title(u"迭代次數-準則函式")

    # 繪製樣本點
    fig2 = plt.figure(2)
    w1 = [x[:2] for x in filter(lambda x: x[2] == 1, data)]
    w3 = [x[:2] for x in filter(lambda x: x[2] == 3, data)]
    w1x1 = [x[0] for x in filter(lambda x: x, w1)]
    w1x2 = [x[1] for x in filter(lambda x: x, w1)]
    w3x1 = [x[0] for x in filter(lambda x: x, w3)]
    w3x2 = [x[1] for x in filter(lambda x: x, w3)]

    plt.scatter(w1x1, w1x2, c='r')
    plt.scatter(w3x1, w3x2, c='g')
    plt.xlabel("x1")
    plt.ylabel("x2")
    plt.title(u"分類介面")

    # 準則函式分隔面
    x = [np.linspace(-6, 7, 100)]  # [1 for i in range(len(y))],
    x = np.mat(x).T

    x2 = (a[0, 0] + a[1, 0] * x) / a[2, 0]
    plt.plot(x, x2)

    plt.show()


if __name__ == '__main__':
    main()

【迭代次數-準則函式曲線】

在所設閾值下,牛頓法收斂步數遠小於梯度下降

【分類介面】

權向量為[ 0.39200249 -0.15039118 0.2144672 ]

牛頓法和梯度下降都是為了尋找準則函式的極小值,所以兩者最後收斂結果一致,僅在演算法複雜度和收斂步數有區別。

3、運算量分析

梯度下降運算量:取決於收斂的步數,即迭代的次數,學習量與迭代次數成正比。

牛頓法運算量:不僅取決於收斂的步數,同時取決於赫森矩陣H 的運算複雜度。

五、總結

基本梯度下降法和牛頓法都能求得最終的權向量,使得準則函式取得一個極小值。一般來說,即使有了最佳的η(k) ,牛頓法也比梯度下降法在每一步都給出了更好的步長,所以收斂速度更快。但是當赫森矩陣H 為奇異矩陣時就不能用牛頓法了。而且,即使H 是非奇異的,每次遞迴時計算H 逆矩陣所需的 時間可輕易地將牛頓法帶來的好處給抵消了。實際上,將η(k) 設定為比較小的常數 ,雖然比每一步都使用最優的η(k) 將需要更多步驟來校正,但通常總的時間開銷卻更少。

如有錯誤請指正

相關推薦

機器學習梯度下降牛頓

一、問題描述 考慮將基本梯度下降和牛頓法應用到表中的資料上。 (a)用這兩種演算法對二維資料給出 和 的判別。對梯度下降法取 。畫出以迭代次數為準則函式的曲線。 (b)估計這兩種方法的數學運算量。 (c)畫出收斂時間-學習率曲線。求出無法收斂的最小學習率。 二、

機器學習詳解】解無約束優化問題梯度下降牛頓、擬牛頓

無約束優化問題是機器學習中最普遍、最簡單的優化問題。 x∗=minxf(x),x∈Rn 1.梯度下降 梯度下降是最簡單的迭代優化演算法,每一次迭代需求解一次梯度方向。函式的負梯度方向代表使函式值減小最快的方向。它的思想是沿著函式負梯度方向移動逐步逼

機器學習梯度下降gradient descent

視屏地址:https://www.bilibili.com/video/av10590361/?p=6  引數優化方法:梯度下降法  learning rate  learning rate : 選擇rate大小 1、自動調learning ra

機器學習之--梯度下降最小二乘法算線性回歸

http 線性 nbsp mat 需要 圖片 span 數據 .com o1 = 0 o2 = 0 o3 = 0 a = 0.002 x = [1,3,5,3,5,7,2,6,7,3,6,9,4,8,9,6,5,3,3,2,7,1,1,1,2,2,2,3,3,3

機器學習梯度下降牛頓的比較

在機器學習的優化問題中,梯度下降法和牛頓法是常用的兩種凸函式求極值的方法,他們都是為了求得目標函式的近似解。在邏輯斯蒂迴歸模型的引數求解中,一般用改良的梯度下降法,也可以用牛頓法。由於兩種方法有些相似,我特地拿來簡單地對比一下。下面的內容需要讀者之前熟悉兩種演算

機器學習梯度下降

梯度 學習 模型 最快 參數 nbsp 函數 bsp 每一個 在吳恩達的機器學習課程中,講了一個模型,如何求得一個參數令錯誤函數值的最小,這裏運用梯度下降法來求得參數。 首先任意選取一個θ 令這個θ變化,怎麽變化呢,怎麽讓函數值變化的快,變化的小怎麽變化,那麽函數值怎麽才能

吳恩達機器學習筆記——梯度下降

1:假設函式的引數更新要做到同時更新,即先將求得的引數放在統一的temp中,然後同時賦值給對應的引數w0,w1,w2,w3..... 2:特徵縮放和收斂速度問題 倘若,特徵向量中一些特徵值相差太大,就會導致代價函式特徵引數的函式曲線很密集,以至於需要多次迭代才能達到最小值。 學習率:決定

機器學習梯度下降詳解

一、導數 導數 就是曲線的斜率,是曲線變化快慢的一個反應。 二階導數 是斜率變化的反應,表現曲線的 凹凸性 y

影象與機器學習-1-梯度下降與ubuntu

現值研一,進入了飛行器控制實驗室,在我迷茫不知學什麼的時候,這時候劉洋師兄帶著影象識別與跟蹤這個課題來到了我們面前,師兄傾其所有交給我們學習的方法和步驟與資料,第一節課,師兄給我們講解了影象識別與跟蹤以及機器學習或深度學習的應用和前景以及基本框架和概念。可以說帶領我進入了影象與機器學習的第一步。

機器學習(7)--梯度下降(GradientDescent)的簡單實現

曾經在  機器學習(1)--神經網路初探  詳細介紹了神經網路基本的演算法,在該文中有一句weights[i] += 0.2 * layer.T.dot(delta) #0.2學習效率,應該是一個小於0.5的數,同時在  tensorflow例項(2)--機器學習初試

機器學習梯度下降數學推導--分類

PS:本文中的log等同於我們國內的ln sigmoid函式     之前那一文中提到了一般的梯度上升的公式推導,但是在《機器學習實戰》一書中,實現的是分類方法,因此,雖然最終的結果相似,但是其實本質有很大的不同。     一般來講我們把實物分

機器學習梯度下降原理及用其解決線性迴歸問題的C語言實現

本文講梯度下降(Gradient Descent)前先看看利用梯度下降法進行監督學習(例如分類、迴歸等)的一般步驟: 1, 定義損失函式(Loss Function) 2, 資訊流forward propagation,直到輸出端 3, 誤差訊號back propagation。採用“鏈式法則”,求損失函式關

對數幾率回歸梯度下降,隨機梯度下降牛頓)與線性判別(LDA)

3.1 初始 屬性 author alt closed sta lose cnblogs   本文主要使用了對數幾率回歸法與線性判別法(LDA)對數據集(西瓜3.0)進行分類。其中在對數幾率回歸法中,求解最優權重W時,分別使用梯度下降法,隨機梯度下降與牛頓法。 代碼如下:

機器學習模型評估選擇

val 上一個 bootstrap 自助法 break all 誤差 rec 數據集 2.1 經驗誤差與擬合 精度(accuracy)和錯誤率(error rate):精度=1-錯誤率 訓練誤差(training error)或經驗誤差(empirical error) 泛

機器學習筆記——梯度下降(Gradient Descent)

梯度下降演算法(Gradient Descent) 在所有的機器學習演算法中,並不是每一個演算法都能像之前的線性迴歸演算法一樣直接通過數學推導就可以得到一個具體的計算公式,而再更多的時候我們是通過基於搜尋的方式來求得最優解的,這也是梯度下降法所存在的意義。 不是一個機器學習演

機器學習之--梯度下降演算法

貌似機器學習最繞不過去的演算法,是梯度下降演算法。這裡專門捋一下。 1. 什麼是梯度 有知乎大神已經解釋的很不錯,這裡轉載並稍作修改,加上自己的看法。先給出連結,畢竟轉載要說明出處嘛。為什麼梯度反方向是函式值區域性下降最快的方向? 因為高等數學都忘光了,先從導數/偏倒數/方向

機器學習梯度消失(vanishing gradient)與梯度爆炸(exploding gradient)問題

1)梯度不穩定問題: 什麼是梯度不穩定問題:深度神經網路中的梯度不穩定性,前面層中的梯度或會消失,或會爆炸。 原因:前面層上的梯度是來自於後面層上梯度的乘乘積。當存在過多的層次時,就出現了內在本質上的不穩定場景,如梯度消失和梯度爆炸。 (2)梯度消失(vanishing gradient

【數學】梯度下降牛頓與擬牛頓

梯度下降 將f(x)f(x)一階泰勒展開: f(x)=f(x0)+(x−x0)f′(x0)f(x)=f(x0)+(x−x0)f′(x0) f(x)=f(x0)+Δxf′(x0)f(x)=f(x0)+Δxf′(x0) 如果當前處於x0x0節點,要使得前進同樣的

機器學習3- 梯度下降(Gradient Descent)

1、梯度下降用於求解無約束優化問題,對於凸問題可以有效求解最優解 2、梯度下降演算法很簡單就不一一列,其迭代公式: 3、梯度下降分類(BGD,SGD,MBGD) 3.1 批量梯度下降法(Batch Gradient Descent)     批量梯度下降法,是梯度

機器學習線性迴歸嶺迴歸入門程式碼

機器學習中運用python進行對房子價格的預測程式碼,資料庫直接使用sklearn自帶的boston,使用三種方法進行預測,分別是:線性迴歸直接預測、梯度下降預測、嶺迴歸預測 from sklearn.datasets import load_boston fr