【機器學習筆記04】隨機梯度下降
阿新 • • 發佈:2018-12-12
梯度下降
梯度下降是一個尋找函式機值的方式,屬於最優化裡的基礎演算法,在低維度的情況下非常容易理解。 例如存在函式存在導數dy=2x,若當前點在x=1點,設dx的步長為0.1。此時我們通過負梯度計算下一個x點,我們可以知道x=0.8比x=1更接近函式的最小值。 在多維情況下理解為考慮更多下降的方向。
(隨機)梯度下降演算法
存線上性迴歸問題如下
1 存在代價函式如下(歐式距離):
2 對代價函式求$\theta$
的偏導數:
3 根據代價函式求得的偏導數,更新引數
,其中是一個常量
4 迭代上述過程
備註:這裡要注意的是若屬於隨機梯度下降演算法,則其代價函式為: ,也就是說每個訓練樣本都會使得引數隨著負梯度方向下降,而不是像傳統的梯度下降一樣需要累加所有的樣本。
隨機梯度下降程式實現(純python)
# -*- coding: utf-8 -*-
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
def init_train_data():
"""
初始化二元線性函式y = 2x + 3x的訓練資料
"""
global x1arr
global x2arr
global yarr
global LEN
LEN = 500
x1arr = np.random.rand(1,LEN)
x2arr = np.random.rand(1,LEN)
yarr = np.zeros(LEN)
for i in range(0,LEN):
yarr.data[i] = 2 * x1arr.data[0,i] + 3*x2arr.data[0,i] + np.random.rand()
def draw_train_data():
"""
繪製訓練資料
"""
fig = plt.figure()
ax = Axes3D(fig)
ax.set_xlabel('x1')
ax.set_ylabel('x2')
ax.set_zlabel('y')
global x1arr
global x2arr
global yarr
global weight
#分佈雜湊點,點為紅色的三角形
ax.scatter(x1arr[0], x2arr[0], yarr, c = 'r', marker = '^')
x1 = np.arange(0, 1, 0.05)
x2 = np.arange(0, 1, 0.05)
x1, x2 = np.meshgrid(x1, x2)
y = weight[0]*x1 + weight[1]*x2
ax.plot_surface(x1, x2, y, rstride=1, cstride=1, cmap=plt.cm.coolwarm) # 用取樣點(x,y,z)去構建曲面
plt.show()
def do_linear_regression_with_sgd(iternum):
"""
利用隨機梯度下降法進行訓練
"""
#此時y = a1*x1 + a2*x2
global x1arr
global x2arr
global yarr
global weight
weight = np.array([1.0,1.0])
step = 0.01
for t in range(1, iternum):
# 取一個訓練樣本
i = t % (LEN - 1)
#對代價函式求相當於a1的偏導數,為(f(x)-y)*x1
da1 = (weight[0]*x1arr[0,i] + weight[1]*x2arr[0,i] - yarr[i])*x1arr[0,i]
da2 = (weight[0] * x1arr[0,i] + weight[1] * x2arr[0,i] - yarr[i]) * x2arr[0,i]
#更新weight,注意這裡是減,為負梯度方向
#最終weight更新值為[ 2.70433803 3.21959271]
weight[0] -= step * da1
weight[1] -= step * da2
return
"""
說明:
隨機梯度下降程式碼實現,對應的筆記《03.隨機梯度下降》
作者:fredric
日期:2018-8-5
"""
if __name__ == '__main__':
init_train_data()
do_linear_regression_with_sgd(1000)
draw_train_data()