機器學習之梯度降低法

機器學習

梯度降低法

參考連接python

基本概念

梯度降低法(gradient descent),又名最速降低法(steepest descent)是求解無約束最優化問題最經常使用的方法,它是一種迭代方法,每一步主要的操做是求解目標函數的梯度向量,將當前位置的負梯度方向做爲搜索方向(由於在該方向上目標函數降低最快,這也是最速降低法名稱的由來)。算法

梯度降低,其實就是一個公式:1594463588290網絡

公式推導

![img](file:///E:\qq聊天記錄\1713176942\Image\C2C\2D65DC80FB67F846BD86FE94D6FF8215.jpg)app

基本梯度降低步驟

步驟1594380571542dom

η爲學習率,ε爲收斂條件。梯度降低法屬於機器學習,本質爲:不斷迭代判斷是否知足條件,會用到循環語句。機器學習

st=>start: 首先設定一個較小的正數m,n;
op=>operation: 求當前位置處的各個偏導數;
修改當前函數的參數值;
cond=>condition: 參數變化量小於n
sub1=>subroutine: 回退迭代
io=>inputoutput: 求得極小值
e=>end: 結束框
st->op->cond
cond(yes)->io->e
cond(no)->sub1(right)->op

1594382365355

1594382407187

批量梯度降低(BGD)

Batch gradient descent::批量梯度降低算法(BGD),其須要計算整個訓練集的梯度,即:函數

bgd.png

其中η爲學習率,用來控制更新的「力度」/"步長"。學習

  • 優勢:

對於凸目標函數,能夠保證全局最優; 對於非凸目標函數,能夠保證一個局部最優。優化

  • 缺點:

速度慢; 數據量大時不可行; 沒法在線優化(即沒法處理動態產生的新樣本)。code

代碼實現

#引庫
#引入matplotlib庫,用於畫圖
import matplotlib.pyplot as plt
from math import pow
#圖片嵌入jupyter
#matplotlib inline

#爲了便於取用數據,咱們將數據分爲x,y,在直角座標系中(x,y)是點
x = [1,2,3,4,5,6]
y = [13,14,20,21,25,30]
print("打印初始數據圖...")
plt.scatter(x,y)
plt.xlabel("X")
plt.ylabel("Y")
plt.show()

#超參數設定
alpha = 0.01#學習率/步長
theta0 = 0#θ0
theta1 = 0#θ1
epsilon = 0.001#偏差
m = len(x)

count = 0
loss = []

for time in range(1000):
    count += 1
    #求偏導theta0和theta1的結果
    temp0 = 0#J(θ)對θ0求導的結果
    temp1 = 0#J(θ)對θ1求導的結果
    diss = 0
    for i in range(m):
        temp0 += (theta0+theta1*x[i]-y[i])/m
        temp1 += ((theta0+theta1*x[i]-y[i])/m)*x[i]

    #更新theta0和theta1
    for i in range(m):
        theta0 = theta0 - alpha*((theta0+theta1*x[i]-y[i])/m) 
        theta1 = theta1 - alpha*((theta0+theta1*x[i]-y[i])/m)*x[i]

    #求損失函數J(θ)
    for i in range(m):
        diss = diss + 0.5*(1/m)*pow((theta0+theta1*x[i]-y[i]),2)
    loss.append(diss)

    #看是否知足條件
    '''
    if diss<=epsilon:
        break
    else:
        continue
    '''
print("最終的結果爲:")
print("這次迭代次數爲:{}次,最終theta0的結果爲:{},最終theta1的結果爲:{}".format(count,theta0,theta1))
print("預測的最終迴歸函數爲:y={}+{}x\n".format(theta0,theta1))
print("迭代圖像繪製...")
plt.scatter(range(count),loss)
plt.show()

運行結果

1594475742309

隨機梯度降低(SGD)

Stochastic gradient descent:隨機梯度降低算法(SGD),僅計算某個樣本的梯度,即針對某一個訓練樣本 xi及其label yi更新參數:

sgd.png

逐步減少學習率,SGD表現得同BGD很類似,最後均可以有不錯的收斂。

  • 優勢:

更新頻次快,優化速度更快; 能夠在線優化(能夠沒法處理動態產生的新樣本);必定的隨機性致使有概率跳出局部最優(隨機性來自於用一個樣本的梯度去代替總體樣本的梯度)。

  • 缺點:

隨機性可能致使收斂複雜化,即便到達最優勢仍然會進行過分優化,所以SGD得優化過程相比BGD充滿動盪。

代碼實現

#引庫
#引入matplotlib庫,用於畫圖
import matplotlib.pyplot as plt
from math import pow
import numpy as np
#圖片嵌入jupyter
#matplotlib inline

#爲了便於取用數據,咱們將數據分爲x,y,在直角座標系中(x,y)是點
x = [1,2,3,4,5,6]
y = [13,14,20,21,25,30]
print("打印初始數據圖...")
plt.scatter(x,y)
plt.xlabel("X")
plt.ylabel("Y")
plt.show()

#超參數設定
alpha = 0.01#學習率/步長
theta0 = 0#θ0
theta1 = 0#θ1
epsilon = 0.001#偏差
m = len(x)

count = 0
loss = []

for time in range(1000):
    count += 1
    diss = 0
    #求偏導theta0和theta1的結果
    temp0 = 0#J(θ)對θ0求導的結果
    temp1 = 0#J(θ)對θ1求導的結果
    for i in range(m):
        temp0 += (theta0+theta1*x[i]-y[i])/m
        temp1 += ((theta0+theta1*x[i]-y[i])/m)*x[i]

    #更新theta0和theta1
    for i in range(m):
        theta0 = theta0 - alpha*((theta0+theta1*x[i]-y[i])/m) 
        theta1 = theta1 - alpha*((theta0+theta1*x[i]-y[i])/m)*x[i]

    #求損失函數J(θ)
    rand_i = np.random.randint(0,m)
    diss += 0.5*(1/m)*pow((theta0+theta1*x[rand_i]-y[rand_i]),2)
    loss.append(diss)

    #看是否知足條件
    '''
    if diss<=epsilon:
        break
    else:
        continue
    '''
print("最終的結果爲:")
print("這次迭代次數爲:{}次,最終theta0的結果爲:{},最終theta1的結果爲:{}".format(count,theta0,theta1))
print("預測的最終迴歸函數爲:y={}+{}x\n".format(theta0,theta1))
print("迭代圖像繪製...")
plt.scatter(range(count),loss)
plt.show()

運行結果

1594476028430

小批量梯度降低(MBGD)

Mini-batch gradient descent:小批量梯度降低算法(MBGD),計算包含n個樣本的mini-batch的梯度

mbgd.png

MBGD是訓練神經網絡最經常使用的優化方法。

  • 優勢:

參數更新時的動盪變小,收斂過程更穩定,下降收斂難度;能夠利用現有的線性代數庫高效的計算多個樣本的梯度。

代碼實現

#引庫
#引入matplotlib庫,用於畫圖
import matplotlib.pyplot as plt
from math import pow
import numpy as np
#圖片嵌入jupyter
#matplotlib inline

#爲了便於取用數據,咱們將數據分爲x,y,在直角座標系中(x,y)是點
x = [1,2,3,4,5,6]
y = [13,14,20,21,25,30]
print("打印初始數據圖...")
plt.scatter(x,y)
plt.xlabel("X")
plt.ylabel("Y")
plt.show()

#超參數設定
alpha = 0.01#學習率/步長
theta0 = 0#θ0
theta1 = 0#θ1
epsilon = 0.001#偏差
diss = 0#損失函數
m = len(x)

count = 0
loss = []

for time in range(1000):
    count += 1
    diss = 0
    #求偏導theta0和theta1的結果
    temp0 = 0#J(θ)對θ0求導的結果
    temp1 = 0#J(θ)對θ1求導的結果
    for i in range(m):
        temp0 += (theta0+theta1*x[i]-y[i])/m
        temp1 += ((theta0+theta1*x[i]-y[i])/m)*x[i]

    #更新theta0和theta1
    for i in range(m):
        theta0 = theta0 - alpha*((theta0+theta1*x[i]-y[i])/m) 
        theta1 = theta1 - alpha*((theta0+theta1*x[i]-y[i])/m)*x[i]

    #求損失函數J(θ)
    result = []
    for i in range(3):
        rand_i = np.random.randint(0,m)
        result.append(rand_i)
    for j in result:
        diss += 0.5*(1/m)*pow((theta0+theta1*x[j]-y[j]),2)
    loss.append(diss)

    #看是否知足條件
    '''
    if diss<=epsilon:
        break
    else:
        continue
    '''
print("最終的結果爲:")
print("這次迭代次數爲:{}次,最終theta0的結果爲:{},最終theta1的結果爲:{}".format(count,theta0,theta1))
print("預測的最終迴歸函數爲:y={}+{}x\n".format(theta0,theta1))
print("迭代圖像繪製...")
plt.scatter(range(count),loss)
plt.show()

運行結果

1594476309210

相關文章
相關標籤/搜索