之前采用的窮舉法來求解最優(yōu)的w值,但是當數(shù)據(jù)量大維度多的時候,會導致訓練性能急劇下降
而梯度下降算法的原理:迭代找到目標函數(shù)的最小值,或者收斂到最小值
梯度的概念:
1.在單變量的函數(shù)中,梯度其實就是函數(shù)的微分溪烤,代表著函數(shù)在某個給定點的切線的斜率
2.在多變量函數(shù)中,梯度是一個向量庇勃,向量有方向氛什,梯度的方向就指出了函數(shù)在給定點的上升最快的方向
3.α在梯度下降算法中被稱作為學習率或者步長,意味著我們可以通過α來控制每一步走的距離
隨機梯度下降算法:
之前的梯度下降可能會產生鞍點問題匪凉,當訓練遇到梯度為0的情況時w=w-a*gradient(x_data,y_date)捺檬,w無法繼續(xù)向前迭代再层,有可能會錯過最優(yōu)值,故可以采取隨機梯度下降算法堡纬,將每一個樣本的梯度代入進行迭代聂受,盡可能的將w送到最優(yōu)處。
本次使用的模型為簡單線性回歸模型:y = w*x
1.定義線性回歸模型
#定義模型
def forward(x):
return w*x
#初始隨機猜測一個權值w=1.0
w=-1.0
2.計算損失函數(shù)
#定義單次成本計算函數(shù)
def loss(x,y):
y_pred = forward(x)
return (y-y_pred) ** 2
3.數(shù)據(jù)集
#定義 DataSet-實際w==2
x_date = [1.0,2.0,3.0]
y_date = [2.0,4.0,6.0]
4.定義梯度計算公式
#定義隨機梯度計算公式
def gradient(x, y):
return 2*x*(x*w-y)
5.使用梯度下降算法進行訓練
#通過梯度下降算法來訓練模型---設定為1-100次:左閉右開區(qū)間
#拿所有樣本對反復訓練100次烤镐,每一次都需要訓練所有的樣本對---梯度為樣本點的梯度
for epoch in range(1, 100):
print("epoch=", epoch)
for x, y in zip(x_date, y_date):
loss_val = loss(x, y)
# 每一次訓練用的梯度都是一對樣本對的梯度蛋济,也就是某點的梯度
w = w-0.01*gradient(x, y) #學習率定義為0.01
print("\tx=", x, "y=", y, "grad=", gradient(x, y),"w=", w)
#打印輸出是第幾次訓練,訓練權值和訓練的損失函數(shù)
w_list.append(w)
mse_list.append(loss_val)
print("\tw=", w, "loss=", loss_val)
6.完整代碼及訓練結果
# -*- codeing = utf-8 -*-
'''
梯度下降算法存在的問題:
1.陷入局部最優(yōu)
2.解決鞍點問題
'''
#采用隨機梯度下降算法---計算每一點樣本對的梯度來進行w權值的更新
#優(yōu)點: 時間復雜度高炮叶,但是結果比較準確
#存在的缺點: 由于本次的訓練w值來源于上一個樣本的梯度訓練碗旅,故由于前后關系,無法進行并行計算的方式進行梯度下降訓練
'''
當計算平均梯度遇到鞍點(梯度為0點,即gradient == 0)時镜悉,w=w-a*gradient無法前進祟辟,此時某一隨機樣本的梯度可能不是鞍點,可能繼續(xù)將w向前
'''
import matplotlib.pyplot as plt
#訓練數(shù)據(jù)集---實際w權值=2.0
x_date = [1.0,2.0,3.0]
y_date = [2.0,4.0,6.0]
#初始隨機猜測一個權值w=1.0
w=-1.0
#定義線性回歸模型
def forward(x):
return x*w
#定義單次成本計算函數(shù)
def loss(x,y):
y_pred = forward(x)
return (y-y_pred) ** 2
w_list = []
mse_list = []
#定義隨機梯度計算公式
def gradient(x, y):
return 2*x*(x*w-y)
print("predict before training:", "w=", w, forward(4))
#通過梯度下降算法來訓練模型---設定為1-100次:左閉右開區(qū)間
#拿所有樣本對反復訓練100次侣肄,每一次都需要訓練所有的樣本對---梯度為樣本點的梯度
for epoch in range(1, 100):
print("epoch=", epoch)
for x, y in zip(x_date, y_date):
loss_val = loss(x, y)
# 每一次訓練用的梯度都是一對樣本對的梯度旧困,也就是某點的梯度
w = w-0.01*gradient(x, y) #學習率定義為0.01
print("\tx=", x, "y=", y, "grad=", gradient(x, y),"w=", w)
#打印輸出是第幾次訓練,訓練權值和訓練的損失函數(shù)
w_list.append(w)
mse_list.append(loss_val)
print("\tw=", w, "loss=", loss_val)
print("predict completed:", "w=", w, forward(4))
plt.plot(w_list, mse_list)
plt.ylabel("mean Square error")
plt.xlabel("w")
plt.show()