1. 程式人生 > 實用技巧 >自定義程式碼實現簡單的多元一次線性函式的隨機梯度下降

自定義程式碼實現簡單的多元一次線性函式的隨機梯度下降

import numpy as np
import random

# 隨機選取樣本的一部分作為隨機樣本進行隨機梯度下降的小部分樣本,x為元樣本,row_size為隨機樣本的行數
# 隨機取樣本
def rand_x(x, row_size):
    xrow_lenth = x.shape[0]
    # print('元樣本行數:{}行'.format(xrow_lenth))
    for i in range(row_size):
        # print(i)
        index = random.randint(0, xrow_lenth - 1)
        
# print('index為:', index) # print('x[index,:]:', x[index, :]) if i == 0: result = x[index, :] else: result = np.row_stack((result, x[index, :])) # print('result:', result, result.shape) return result # x2 = rand_x(x, 6) # print(x2) # 簡單的梯度下降優化,x為資料,y_t為標註值,w_p為優化後的引數值,step是梯度下降的步長
def W_update(x, y_t, w_p, step): # 測試輸入值是否正確 # print('開始梯度下降') # print('w_p:', w_p, w_p.shape) # 開始調整引數w_p w_p += 2 * step * (np.matmul((y_t - np.matmul(x, w_p)).T, x)).T # 運用偏導數實現逐步逼近loss的最小值的梯度下降來優化引數w,見手寫推導 ######################函式呼叫實現功能######################## # 模擬資料集 #已知資料的模擬
x_col = 4 # 幾元函式,也就是x的列 x = np.random.randint(95, 100, (200, x_col)) # 隨機生成2000行n元的資料,資料值在70到100之間 w_t = np.array([355.0, 115.0, 4.0, 16.0]).reshape(x_col, 1) # 初始化真實值的引數 y_true = np.matmul(x, w_t) # 計算出真實值的結果向量作為標記值 #計算資料的初始化,和超參定義 w = np.array([0.0, 2.0, 5.0, 1.2]).reshape(x_col, 1) # 初始化需要優化的引數向量,可以隨機賦值 step = 0.000000088 #學習步長 loss = np.matmul((y_true - np.matmul(x, w)).T, y_true - np.matmul(x, w)) # 梯度下降的損失函式 print("開始loss", loss) num = 1 while loss > 10: #當loss小於10則停止 x2 = rand_x(x, 300) #將元樣本進行隨機劃分成小樣本,這裡分為300行 y2_true = np.matmul(x2, w_t) W_update(x2, y2_true, w, step) #開始優化引數w if num % 1000 == 0: #每1000次列印觀察loss和w print('1000次啦@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@') loss = np.matmul((y_true - np.matmul(x, w)).T, y_true - np.matmul(x, w)) # 梯度下降的損失函式 print('此次loss:', loss) print('修改過後的w:', w) num += 1

測試引數真實值:

355.0, 115.0, 4.0, 16.0
實際結果:

引數W優化的演算法推導: