首頁 > 軟體

Python實現梯度下降法的範例程式碼

2022-08-08 14:01:13

1.首先讀取資料集

導包並讀取資料,資料自行任意準備,只要有兩列,可以分為自變數x和因變數y即可即可。

import numpy as np
import matplotlib.pyplot as plt

data = np.loadtxt("data.csv", delimiter=",")

x_data = data[:, 0]
y_data = data[:, 1]

2.初始化相關引數

# 初始化 學習率 即每次梯度下降時的步長 這裡設定為0.0001
learning_rate = 0.0001

# 初始化 截距b 與 斜率k
b = 0
k = 0

# 初始化最大迭代的次數 以50次為例
n_iterables = 50

3.定義計算代價函數–>MSE

使用均方誤差 MSE (Mean Square Error)來作為效能度量標準

假設共有m個樣本資料,則均方誤差:

將該公式定義為代價函數,此外為例後續求導方便,則使結果在原mse的基礎上,再乘以1/2。

def compute_mse(b,  k,  x_data, y_data):
    total_error = 0
    for i in range(len(x_data)):
        total_error += (y_data[i] - (k * x_data[i] + b)) ** 2

    # 為方便求導:乘以1/2
    mse_ = total_error / len(x_data) / 2
    return mse_

4.梯度下降

分別對上述的MSE表示式(乘以1/2後)中的k,b求偏導,

更新b和k時,使用原來的b,k值分別減去關於b、k的偏導數與學習率的乘積即可。至於為什麼使用減號,可以這麼理解:以斜率k為例,當其導數大於零的時候,則表示均方誤差隨著斜率的增大而增大,為了使均方誤差減小,則不應該使斜率繼續增大,所以需要使其減小,反之當偏導大於零的時候也是同理。其次,因為這個導數衡量的是均方誤差的變化,而不是斜率和截距的變化,所以這裡需要引入一個學習率,使得其與偏導數的乘積能夠在一定程度上起到控制截距和斜率變化的作用。

def gradient_descent(x_data, y_data, b,  k,  learning_rate,  n_iterables):
    m = len(x_data)
    # 迭代
    for i in range(n_iterables):
        # 初始化b、k的偏導
        b_grad = 0
        k_grad = 0

        # 遍歷m次
        for j in range(m):
            # 對b,k求偏導
            b_grad += (1 / m) * ((k * x_data[j] + b) - y_data[j])
            k_grad += (1 / m) * ((k * x_data[j] + b) - y_data[j]) * x_data[j]

        # 更新 b 和 k  減去偏導乘以學習率
        b = b - (learning_rate * b_grad)
        k = k - (learning_rate * k_grad)
        # 每迭代 5 次  輸出一次圖形
        if i % 5 == 0:
            print(f"當前第{i}次迭代")
            print("b_gard:", b_grad, "k_gard:", k_grad)
            print("b:", b, "k:", k)
            plt.scatter(x_data, y_data, color="maroon", marker="x")
            plt.plot(x_data, k * x_data + b)
            plt.show()
    return b, k

5.執行

print(f"開始:截距b={b},斜率k={k},損失={compute_mse(b,k,x_data,y_data)}")
print("開始迭代")
b, k = gradient_descent(x_data, y_data, b, k, learning_rate, n_iterables)
print(f"迭代{n_iterables}次後:截距b={b},斜率k={k},損失={compute_mse(b,k,x_data,y_data)}")

程式碼執行過程產生了一系列的影象,部分影象如下圖所示,隨著迭代次數的增加,代價函數越來越小,最終達到預期效果,如下圖所示:

第5次迭代:

第10次迭代:

第50次迭代:

執行過程的輸出結果如下圖所示:

可以看到,隨著偏導數越來越小,斜率與截距的變化也越來越細微。

到此這篇關於Python實現梯度下降法的範例程式碼的文章就介紹到這了,更多相關Python梯度下降法內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com