梯度下降法-三種認識

前言

1、機器學習中的大部分問題都是優化問題,而絕大部分優化問題都可以使用梯度下降法處理。

2、梯度下降法 = 梯度+下降

3、想要了解梯度,必須要瞭解方向導數,想要了解方向導數,就要了解偏導數,想要了解偏導數,就要了解導數,所以學習梯度需要依次學習導數、偏導數、方向導數和梯度。

基礎知識

1、導數:函數在該點的瞬時變化率,針對一元函數而言

導數定義

2、偏導數:函數在座標軸方向上的變化率 

偏導數定義

3、方向導數:函數在某點沿某個特定方向的變化率 

方向導數定義

4、梯度:函數在該點沿所有方向變化率最大的那個方向

梯度定義

5、泰勒公式

直觀認識

1、一元函數求極小值點

如上圖所示,曲線代表目標函數(loss函數),如何在給定的初始x值情況下,找到目標函數極小值的座標x

1)若初始點爲x0,此點的導數值從給定的曲線來看必然大於0,此時我們可以嘗試:x0 := x0 - 導數值(爲什麼是減號,這裏就體現了梯度下降),那麼x0必然往左移動,記爲x0',再在此點做第二條切線,按照此步驟進行訓練計算。

2)若初始點爲x1,此點的導數值從給定的曲線來看必然小於0,此時我們可以嘗試:x1 := x1 + 導數值(爲什麼是加號,這裏就體現了梯度下降),那麼x1必然往右移動,記爲x1',再在此點做第二條切線,按照此步驟進行訓練計算。

按照上述辦法,我們最後得到的x值有可能就在目標x點左右徘徊,可是我們擔心導數值過大,使得x0或x1計算後並沒有向目標x點移動,而是離它越來越遠,所以我們可以嘗試如下計算方式:

x0 := x0 - a*導數值        x1 := x1 + a*導數值  (可通過泰勒一階展開式證明)

這裏的a代表學習率,即步長,如果導數值過大,我們可以根據經驗將a變小,反之則變大

2、多元函數求極小值點

若一個人站在半山腰,他的前面有四條路,如何才能使得自己下山的速度最快呢?

1)上山的路

2)較爲平緩的環形下山公路

3)45°的下山階梯

4)90°的懸崖絕壁

小夥伴你們選什麼,歡迎留言!

博主給出的回答是直接跳崖,自由落體比什麼都快,這裏不要笑,因爲梯度就是這麼想的。

回到問題,如何找到多元函數的極小值點呢?從上面的理論中我們可以看出,梯度表示函數在該點沿所有方向變化率最大的那個方向,你們說是不是選擇直接跳崖呢,因爲90°在函數值上變化最快!

我們從一元函數即可推導出多元函數的計算公式,最快的方向就是\frac{\partial f}{\partial x0}\frac{\partial f}{\partial x1}, ... ,\frac{\partial f}{\partial xn},該方向函數值變化最大:

梯度下降法

公式認識

1、前向函數

2、loss函數

3、梯度下降初始定義

4、梯度計算

5、梯度下降最終定義

代碼認識

#!usr/bin/python3
# coding:utf-8

import numpy as np
import random
 
def batchGradientDescent(x, y, theta, alpha, m, maxInteration):
    x_train = x.transpose()
    for i in range(0, maxInteration):
        hypothesis = np.dot(x, theta)
        # 損失函數
        loss = hypothesis - y
        # 下降梯度
        gradient = np.dot(x_train, loss) / m
        # 求導之後得到theta
        theta = theta - alpha * gradient
    return theta
 
def main():
    trainData = np.array([[1, 4, 2], [2, 5, 3], [5, 1, 6], [4, 2, 8]])
    trainLabel = np.array([19, 26, 19, 20])
    print(trainData)
    print(trainLabel)
    m, n = np.shape(trainData)
    theta = np.ones(n)
    print(theta.shape)
    maxInteration = 500
    alpha = 0.01
    theta = batchGradientDescent(trainData, trainLabel, theta, alpha, m, maxInteration)
    print(theta)
    return
 
if __name__ == "__main__":
    main()

參考

https://blog.csdn.net/walilk/article/details/50978864

https://blog.csdn.net/Eric_LH/article/details/78994461

https://www.cnblogs.com/focusonepoint/p/6394339.html

https://blog.csdn.net/panghaomingme/article/details/79384922

https://blog.csdn.net/weixin_42278173/article/details/81511646

 

任何問題請加唯一QQ2258205918(名稱samylee)!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章