[英]Gradient Descent Matlab implementation
我在堆棧溢出中經歷了很多代碼並且在同一行上創建了自己的代碼。 這段代碼有些問題我無法理解。 我存儲值theta1和theta 2以及成本函數用於分析目的。 可以從此Openclassroom頁面下載x和Y的數據。 它具有.dat文件形式的x和Y數據,您可以在記事本中打開它們。
%Single Variate Gradient Descent Algorithm%%
clc
clear all
close all;
% Step 1 Load x series/ Input data and Output data* y series
x=load('D:\Office Docs_Jay\software\ex2x.dat');
y=load('D:\Office Docs_Jay\software\ex2y.dat');
%Plot the input vectors
plot(x,y,'o');
ylabel('Height in meters');
xlabel('Age in years');
% Step 2 Add an extra column of ones in input vector
[m n]=size(x);
X=[ones(m,1) x];%Concatenate the ones column with x;
% Step 3 Create Theta vector
theta=zeros(n+1,1);%theta 0,1
% Create temporary values for storing summation
temp1=0;
temp2=0;
% Define Learning Rate alpha and Max Iterations
alpha=0.07;
max_iterations=1;
% Step 4 Iterate over loop
for i=1:1:max_iterations
%Calculate Hypothesis for all training example
for k=1:1:m
h(k)=theta(1,1)+theta(2,1)*X(k,2); %#ok<AGROW>
temp1=temp1+(h(k)-y(k));
temp2=temp2+(h(k)-y(k))*X(k,2);
end
% Simultaneous Update
tmp1=theta(1,1)-(alpha*1/(2*m)*temp1);
tmp2=theta(2,1)-(alpha*(1/(2*m))*temp2);
theta(1,1)=tmp1;
theta(2,1)=tmp2;
theta1_history(i)=theta(2,1); %#ok<AGROW>
theta0_history(i)=theta(1,1); %#ok<AGROW>
% Step 5 Calculate cost function
tmp3=0;
tmp4=0;
for p=1:m
tmp3=tmp3+theta(1,1)+theta(2,1)*X(p,1);
tmp4=tmp4+theta(1,1)+theta(2,1)*X(p,2);
end
J1_theta0(i)=tmp3*(1/(2*m)); %#ok<AGROW>
J2_theta1(i)=tmp4*(1/(2*m)); %#ok<AGROW>
end
theta
hold on;
plot(X(:,2),theta(1,1)+theta(2,1)*X);
我正在獲得價值
θ為0.0373和0.1900,應為0.0745和0.3800
這個值大約是我期待的兩倍。
我一直在嘗試用矩陣和向量來實現迭代步驟(即不更新theta的每個參數)。 這是我想出的(這里只有漸變步驟):
h = X * theta; # hypothesis
err = h - y; # error
gradient = alpha * (1 / m) * (X' * err); # update the gradient
theta = theta - gradient;
難以掌握的是前面例子的梯度步驟中的“和”實際上是由矩陣乘法X'*err
。 你也可以把它寫成(err'*X)'
我設法創建了一個使用Matlab支持的更多矢量化屬性的算法。 我的算法與你的算法略有不同,但是你提出的是梯度下降過程。 在我執行的執行和驗證(使用polyfit函數)之后,我認為在1500次迭代步驟之后,變量theta(0)= 0.0745和theta(1)= 0.3800中預期的openclassroom(練習2)中的值是錯誤的0.07(我不回應)。 這就是為什么我用一個圖中的數據繪制我的結果,而另一個圖中的數據繪制了所需的結果,我發現數據擬合程序有很大差異。
首先看一下代碼:
% Machine Learning : Linear Regression
clear all; close all; clc;
%% ======================= Plotting Training Data =======================
fprintf('Plotting Data ...\n')
x = load('ex2x.dat');
y = load('ex2y.dat');
% Plot Data
plot(x,y,'rx');
xlabel('X -> Input') % x-axis label
ylabel('Y -> Output') % y-axis label
%% =================== Initialize Linear regression parameters ===================
m = length(y); % number of training examples
% initialize fitting parameters - all zeros
theta=zeros(2,1);%theta 0,1
% Some gradient descent settings
iterations = 1500;
Learning_step_a = 0.07; % step parameter
%% =================== Gradient descent ===================
fprintf('Running Gradient Descent ...\n')
%Compute Gradient descent
% Initialize Objective Function History
J_history = zeros(iterations, 1);
m = length(y); % number of training examples
% run gradient descent
for iter = 1:iterations
% In every iteration calculate hypothesis
hypothesis=theta(1).*x+theta(2);
% Update theta variables
temp0=theta(1) - Learning_step_a * (1/m)* sum((hypothesis-y).* x);
temp1=theta(2) - Learning_step_a * (1/m) *sum(hypothesis-y);
theta(1)=temp0;
theta(2)=temp1;
% Save objective function
J_history(iter)=(1/2*m)*sum(( hypothesis-y ).^2);
end
% print theta to screen
fprintf('Theta found by gradient descent: %f %f\n',theta(1), theta(2));
fprintf('Minimum of objective function is %f \n',J_history(iterations));
% Plot the linear fit
hold on; % keep previous plot visible
plot(x, theta(1)*x+theta(2), '-')
% Validate with polyfit fnc
poly_theta = polyfit(x,y,1);
plot(x, poly_theta(1)*x+poly_theta(2), 'y--');
legend('Training data', 'Linear regression','Linear regression with polyfit')
hold off
figure
% Plot Data
plot(x,y,'rx');
xlabel('X -> Input') % x-axis label
ylabel('Y -> Output') % y-axis label
hold on; % keep previous plot visible
% Validate with polyfit fnc
poly_theta = polyfit(x,y,1);
plot(x, poly_theta(1)*x+poly_theta(2), 'y--');
% for theta values that you are saying
theta(1)=0.0745; theta(2)=0.3800;
plot(x, theta(1)*x+theta(2), 'g--')
legend('Training data', 'Linear regression with polyfit','Your thetas')
hold off
好的結果如下:
使用由我的算法產生的theta(0)和theta(1),該行適合數據。
以theta(0)和theta(1)作為固定值,結果該行不適合數據。
以下是一些評論:
max_iterations
設置為1
。 通常運行梯度下降,直到目標函數的減小低於某個閾值或者梯度的幅度低於某個閾值,這可能是多於一次迭代。
系數1 /(2 * m)在技術上並不正確。 這不應該導致算法失敗,但會有效地降低學習速度。
你沒有計算正確的目標。 正確的線性回歸目標應該是平方殘差平均值的一半,或者是殘差平方和的一半。
您應該利用matlab的矢量化計算,而不是使用for循環。 例如, res=X*theta-y; obj=.5/m*res'res;
res=X*theta-y; obj=.5/m*res'res;
應計算殘差( res
)和線性回歸目標( obj
)。
你需要把temp1 = 0 temp2 = 0作為迭代循環中的第一個注釋; 如果你不這樣做,你當前的臨時會影響下一次迭代,這是錯誤的
根據您期望的Ɵ
(theta)值和程序結果,可以注意到預期值是結果的兩倍。
您可能犯的錯誤是在衍生計算代碼中使用1/(2*m)
代替1/m
。 在導數中,分母2
消失為原始項是( hƟ (x) - y) 2 ,在分化時產生2 *( hƟ (x) - y) 。 2s取消了。
修改這些代碼行:
J1_theta0(i)=tmp3*(1/(2*m)); %#ok<AGROW>
J2_theta1(i)=tmp4*(1/(2*m)); %#ok<AGROW>
至
J1_theta0(i)=tmp3*(1/m); %#ok<AGROW>
J2_theta1(i)=tmp4*(1/m); %#ok<AGROW>
希望能幫助到你。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.