2012-05-14 12 views
30

En realidad, hace 2 meses que estoy luchando contra esto. ¿Qué es lo que los hace diferentes?Implementación de Gradient Descent en octava

hypotheses= X * theta 
temp=(hypotheses-y)' 
temp=X(:,1) * temp 
temp=temp * (1/m) 
temp=temp * alpha 
theta(1)=theta(1)-temp 

hypotheses= X * theta 
temp=(hypotheses-y)' 
temp=temp * (1/m) 
temp=temp * alpha 
theta(2)=theta(2)-temp 



theta(1) = theta(1) - alpha * (1/m) * ((X * theta) - y)' * X(:, 1); 
theta(2) = theta(2) - alpha * (1/m) * ((X * theta) - y)' * X(:, 2); 

Esto último funciona. No estoy seguro por qué ... Me cuesta entender la necesidad de la matriz inversa.

+2

no creo que se trata de una aplicación adecuada de descenso de gradiente. Debes actualizar Tanto sus thetas al mismo tiempo para ser precisos. 'tmpTheta1 = theta (1) - alpha * (1/m) * ((X * theta) - y) '* X (:, 1); tmpTheta2 = theta (2) - alpha * (1/m) * ((X * theta) - y) '* X (:, 2); ' ' theta (1) = tmpTheta1; ' ' theta (2) = tmpTheta2; ' –

Respuesta

54

Lo que está haciendo en el primer ejemplo en el segundo bloque te has perdido un paso no es así? Supongo que concatenaste X con un vector de unos.

temp=X(:,2) * temp 

El último ejemplo funcionará, pero se puede vectorizar aún más para ser más simple y eficiente.

Supongo que solo tiene 1 función. funcionará de la misma manera con múltiples funciones, ya que todo lo que sucede es que agrega una columna adicional a su matriz X para cada característica. Básicamente se agrega un vector de unos a x para vectorizar el intercepto.

Puede actualizar una matriz 2x1 de thetas en una línea de código. Con x concatenar un vector de unos que lo convierten en una matriz nx2, entonces puedes calcular h (x) multiplicando por el vector theta (2x1), este es (X * theta) bit.

La segunda parte de la vectorización es transponer (X * theta) - y) que le da una matriz 1 * n que multiplicada por X (una matriz n * 2) básicamente agregará ambos (h (x) -y) x0 y (h (x) -y) x1. Por definición, ambos thetas se hacen al mismo tiempo. Esto da como resultado una matriz 1 * 2 de mi nueva theta que acabo de transponer de nuevo para darle la vuelta al vector y que tenga las mismas dimensiones que el vector theta. Entonces puedo hacer una multiplicación escalar simple por resta alfa y vectorial con theta.

X = data(:, 1); y = data(:, 2); 
m = length(y); 
X = [ones(m, 1), data(:,1)]; 
theta = zeros(2, 1);   

iterations = 2000; 
alpha = 0.001; 

for iter = 1:iterations 
    theta = theta -((1/m) * ((X * theta) - y)' * X)' * alpha; 
end 
+0

¿por qué necesita transponer (1/m) * ((X * theta) - y) '* X en su bucle for? –

+0

La misma pregunta que Grahm, ¿por qué se tranpone toda la subexpresión? – qbert65536

+0

El resultado de '((1/m) * ((X * theta) - y) '* X)' es 1x2. 'theta' es 2x1. Entonces, el bit entre paréntesis debe transponerse para tener las mismas dimensiones y restarlo de 'theta'. – AronVanAmmers

5

En la primera, si X fuera una matriz de 3x2 y theta una matriz de 2x1, entonces la "hipótesis" sería una matriz de 3x1.

Suponiendo que y es una matriz de 3x1, entonces puede realizar (hipótesis - y) y obtener una matriz de 3x1, luego la transposición de esa 3x1 es una matriz de 1x3 asignada a la temperatura.

Luego, la matriz 1x3 se establece en theta (2), pero esto no debe ser una matriz.

Las dos últimas líneas de su código funciona porque, usando mis ejemplos mxn anterior,

(X * theta) 

habría una matriz de 3x1.

Luego, esa matriz 3x1 se resta por y (una matriz 3x1) y el resultado es una matriz 3x1.

(X * theta) - y 

Por lo tanto, la transposición de la matriz 3x1 es una matriz de 1x3.

((X * theta) - y)' 

Por último, un par de veces de matriz 1x3 una matriz de 3x1 será igual a una matriz escalar o 1x1, que es lo que busca. Estoy seguro de que ya lo sabías, pero para ser minucioso, la X (:, 2) es la segunda columna de la matriz de 3x2, por lo que es una matriz de 3x1.

2

Al actualizar lo que necesita hacer como

Start Loop { 

temp0 = theta0 - (equation_here); 

temp1 = theta1 - (equation_here); 


theta0 = temp0; 

theta1 = temp1; 

} End loop 
-8
. 
. 
. 
. 
. 
. 
. 
. 
. 
Spoiler alert 












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

for iter = 1:num_iters 

% ====================== YOUR CODE HERE ====================== 
% Instructions: Perform a single gradient step on the parameter vector 
%    theta. 
% 
% Hint: While debugging, it can be useful to print out the values 
%  of the cost function (computeCost) and gradient here. 
% ========================== BEGIN =========================== 


t = zeros(2,1); 
J = computeCost(X, y, theta); 
t = theta - ((alpha*((theta'*X') - y'))*X/m)'; 
theta = t; 
J1 = computeCost(X, y, theta); 

if(J1>J), 
    break,fprintf('Wrong alpha'); 
else if(J1==J) 
    break; 
end; 


% ========================== END ============================== 

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

idea es ayudar a los usuarios a avanzar, no publicar ejemplos completos de ejercicios reales en el hogar – EdvardM

0
function [theta, J_history] = gradientDescent(X, y, theta, alpha, num_iters) 
% Performs gradient descent to learn theta. Updates theta by taking num_iters 
% gradient steps with learning rate alpha. 

% Number of training examples 
m = length(y); 
% Save the cost J in every iteration in order to plot J vs. num_iters and check for convergence 
J_history = zeros(num_iters, 1); 

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

end 
Cuestiones relacionadas