2013-10-16 51 views
0

我在Matlab中學習了這個課程,並且我已經完成了梯度下降實現,但它給出了不正確的結果。在Matlab中梯度下降的結果不正確

代碼:

for iter = 1:num_iters 

sumTheta1 = 0; 
sumTheta2 = 0; 
for s = 1:m 
    sumTheta1 = theta(1) + theta(2) .* X(s,2) - y(s); 
    sumTheta2 = theta(1) + theta(2) .* X(s,2) - y(s) .* X(s,2); 
end 

theta(1) = theta(1) - alpha .* (1/m) .* sumTheta1; 
theta(2) = theta(2) - alpha .* (1/m) .* sumTheta2; 

J_history(iter) = computeCost(X, y, theta); 

end 

這是重要的組成部分。我認爲公式的實現是正確的,即使它沒有被優化。公式是:

theta1 = theta1 - (alpha)(1/m)(summation_i^m(theta1 + theta2*x(i)-y(i))) 
theta2 = theta2 - (alpha)(1/m)(summation_i^m(theta1 + theta2*x(i)-y(i)))(x(i)) 

那麼問題出在哪裏呢?

編輯:CODE更新

function [theta, J_history] = gradientDescent(X, y, theta, alpha, num_iters) 

m = length(y); % number of training examples 
J_history = zeros(num_iters, 1); 


for iter = 1:num_iters 

for s = 1:m 

sumTheta1 = ((theta(1) .* X(s,1)) + (theta(2) .* X(s,2))) - (y(s)); 
sumTheta2 = ((theta(1) .* X(s,1)) + (theta(2) .* X(s,2))) - (y(s)) .* X(s,2); 
end 

temp1 = theta(1) - alpha .* (1/m) .* sumTheta1; 
temp2 = theta(2) - alpha .* (1/m) .* sumTheta2; 

theta(1) = temp1; 
theta(2) = temp2; 

J_history(iter) = computeCost(X, y, theta); 

end 

end 

EDIT(2):固定它,工作碼。

明白了,這是+丹的暗示,做到了這一點,我會接受他的答案,仍然把代碼放在這裏給任何卡住:),歡呼聲。

function [theta, J_history] = gradientDescent(X, y, theta, alpha, num_iters) 

m = length(y); % number of training examples 
J_history = zeros(num_iters, 1); 


for iter = 1:num_iters 

sumTheta1 = 0; 
sumTheta2 = 0; 

for s = 1:m 

sumTheta1 = sumTheta1 + ((theta(1) .* X(s,1)) + (theta(2) .* X(s,2))) - (y(s)); 
sumTheta2 = sumTheta2 + (((theta(1) .* X(s,1)) + (theta(2) .* X(s,2))) - (y(s))) .* X(s,2); 
end 

temp1 = theta(1) - alpha .* (1/m) .* sumTheta1; 
temp2 = theta(2) - alpha .* (1/m) .* sumTheta2; 

theta(1) = temp1; 
theta(2) = temp2; 

% Save the cost J in every iteration  
J_history(iter) = computeCost(X, y, theta); 

end 

end 
+0

你知道Matlab的不理解語法'(阿爾法)(1/M)'對不對?你需要明確地輸入一個乘號,例如'(α*(1/m)*(summation_i^m *(theta1 + theta2 * x(i)-y(i)))* x(i)'。這有意義嗎? –

+1

是的,這是在筆記中說的公式,而不是matlab的實現,matlab代碼在上面。因爲我不知道如何在這裏寫公式。 –

+0

不確定在SO上是否有公認的寫方程。就個人而言,我寧願*不*使用方程式上的代碼高亮顯示,但有些用戶會這樣做。如果您想全力以赴,可以使用Google API - 請參閱[這裏](http://meta.stackexchange.com/questions/76902/how-can-i-write-math-formula-in-a -stack-overflow-question) –

回答

1

乍一看我注意到你的sumTheta1實際上不是相加而是更換自己每次迭代。我想你的意思是:

sumTheta1 = sumTheta1 + theta(1) + theta(2) .* X(s,2) - y(s); 

與同爲sumTheta2

但對於未來的參考,你可以更換這(校正)循環:這個量化的公式

sumTheta1 = sum(theta(1) + theta(2)*X(:,2) - y); 
sumTheta2 = sum(theta(1) + theta(2)*X(:,2) - y.*X(:,2)) 

for s = 1:m 
    sumTheta1 = theta(1) + theta(2) .* X(s,2) - y(s); 
    sumTheta2 = theta(1) + theta(2) .* X(s,2) - y(s) .* X(s,2); 
end 

+0

好吧,我做了改變,它變得更糟,我得到的第一代碼的地方-3.120881 1.112813非常接近最小值,sumTheta(x)添加到循環它爆炸了-73.069510 16.165062 –

1

如果我看到這個公式

theta1 = theta1 - (alpha)(1/m)(summation_i^m(theta1 + theta2*x(i)-y(i))) 

我猜的MATLAB相當於將是:

theta1 = theta1 - alpha/m*(theta1 + theta2)*sum(x-y) 

也許你能確定m如下:

m =length(x); 

不過,你的兩個公式讓我懷疑你是否想計算他們順序或同時進行。

在第二種情況下,創建一個臨時變量並在計算中使用它。

myFactor = alpha/m*(theta1_previous + theta2_previous) 

theta1 = theta1_previous - myFactor*sum(x-y) 
theta2 = theta2_previous - myFactor*sum((x-y).*x) 
+0

漸變下降應該是同時的 – Dan

+0

同時,我認爲在這一行中:theta(1)= theta(1) - alpha。*(1/m)。* sumTheta1; (2)= theta(2) - alpha。*(1/m)。* sumTheta2; –

+0

@ Pedro.Alonso當然有多種方式可以做到這一點。我已經更新了我的答案,一個應該做的伎倆。 –

1

矢量化版本:

for iter = 1:num_iters 
    theta = theta - (alpha .* X'*(X * theta - y) ./m); 
    J_history(iter) = computeCost(X, y, theta); 
end 
+0

我還有一個問題[聊天](http://chat.stackoverflow.com/rooms/41050/logistic-regression) –