1

我想寫一些非常簡單的LMS批梯度下降,但我相信我做錯了梯度。對於theta的元素,theta的數量級與初始值之間的比率是非常不同的,因此theta[2]不會移動(例如,如果alpha = 1e-8)或theta[1]射出(例如如果alpha = .01)。LMS批量梯度下降NumPy

import numpy as np 

y = np.array([[400], [330], [369], [232], [540]]) 
x = np.array([[2104,3], [1600,3], [2400,3], [1416,2], [3000,4]]) 
x = np.concatenate((np.ones((5,1), dtype=np.int), x), axis=1) 
theta = np.array([[0.], [.1], [50.]]) 
alpha = .01 

for i in range(1,1000): 
    h = np.dot(x, theta) 
    gradient = np.sum((h - y) * x, axis=0, keepdims=True).transpose() 
    theta -= alpha * gradient 
    print ((h - y)**2).sum(), theta.squeeze().tolist() 

回答

1

所寫的算法是完全正確的,但沒有特徵縮放,因爲一個特徵將控制梯度計算,所以收斂速度將非常慢。

您可以通過多種方式執行縮放;現在,讓我們只是規模由他們的L^1個規範的功能,因爲它的簡單

import numpy as np 
y = np.array([[400], [330], [369], [232], [540]]) 
x_orig = np.array([[2104,3], [1600,3], [2400,3], [1416,2], [3000,4]]) 
x_orig = np.concatenate((np.ones((5,1), dtype=np.int), x_orig), axis=1) 
x_norm = np.sum(x_orig, axis=0) 
x = x_orig/x_norm 

也就是說,每列的x總和爲1。如果你想在正確的參數以保留很好的猜測,那些必須相應地縮放。

theta = (x_norm*[0., .1, 50.]).reshape(3, 1) 

有了這個,我們可以爲你在原來的職位,在那裏你又會有直到找到一個最佳點,以玩的學習率沒有進行。

alpha = .1 
for i in range(1, 100000): 
    h = np.dot(x, theta) 
    gradient = np.sum((h - y) * x, axis=0, keepdims=True).transpose() 
    theta -= alpha * gradient 

讓我們來看看我們現在,我們已經發現了一些似乎收斂得到。同樣,您的參數將不得不縮放以與原始未縮放功能相關。

print (((h - y)**2).sum(), theta.squeeze()/x_norm) 
# Prints 1444.14443271 [ -7.04344646e+01 6.38435468e-02 1.03435881e+02] 

在這一點上,我們的欺騙和檢查我們的結果

theta, error, _, _ = np.linalg.lstsq(x_orig, y) 
print(error, theta) 
# Prints [ 1444.1444327] [[ -7.04346018e+01] 
#       [ 6.38433756e-02] 
#       [ 1.03436047e+02]] 

的特徵縮放的一般介紹的參考是this Stanford lecture

+0

謝謝,不知道功能縮放!代碼起作用了,唯一的事情就是我要做'x = np.asfarray([[2104,3],[1600,3],[2400,3],[1416,2],[3000,4]] )''因爲數組全部是'int',並且在縮放中它全部被四捨五入爲0. – wizplum

+0

啊,爲了記錄,這種行爲在Python 3中不會發生,但我應該從你的最後一行中猜出你正在運行Python 2。 – fuglede