2012-05-14 2 views
30

Я действительно боролся с этим, как через 2 месяца. Что это отличает их?Реализация Gradient Descent в октаве

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); 

Последнее работает. Я просто не знаю, почему ... Я пытаюсь понять необходимость обратного преобразования матрицы.

+2

Я не думаю, что это правильное выполнение градиентного спуска. Вам нужно обновить. Оба ваши тета в то же время должны быть точными. '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; ' –

ответ

54

Что вы делаете в первом примере, во втором блоке вы пропускали шаг не так ли? Я предполагаю, что вы объединили X с вектором единиц.

temp=X(:,2) * temp 

Последний пример будет работать, но может быть векторизован еще более простым и эффективным.

Я предположил, что у вас есть только 1 функция. он будет работать одинаково с несколькими функциями, поскольку все, что происходит, - это добавить дополнительный столбец к вашей матрице X для каждой функции. В основном вы добавляете вектор из них в x для векторизации перехвата.

Вы можете обновить матрицу 2x1 в одной строке кода. При х конкатенировать вектор тех, которые делают его матрицей nx2, тогда вы можете вычислить h (x), умножив его на тэта-вектор (2x1), это бит (X * theta).

Вторая часть векторизации - это транспонирование (X * theta) - y), которая дает вам 1 * n матрицу, которая при умножении на X (матрица n * 2) будет в основном суммировать оба (h (x) -y) x0 и (h (x) -y) x1. По определению оба эти метода выполняются в одно и то же время. Это приводит к 1 * 2 матрице моей новой теты, которую я просто транспонирую снова, чтобы перевернуть вектор так же, как тета-вектор. Затем я могу сделать простое скалярное умножение путем альфа-и векторного вычитания с тета.

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

Зачем вам нужно транспонировать (1/m) * ((X * theta) - y) '* X в вашем цикле for? –

+0

Тот же вопрос, что и Грэм, почему это все подвыражение трансформируется? – qbert65536

+0

Результат '((1/m) * ((X * theta) - y) '* X)' равен 1x2. 'theta' - 2x1. Таким образом бит между скобками должен быть транспонирован, чтобы иметь одинаковые размеры и вычесть его из 'theta'. – AronVanAmmers

5

В первом случае, если X была матрицей 3x2, а theta были матрицей 2x1, тогда «гипотезы» были бы матрицей 3x1.

Предполагая, что y является матрицей 3x1, вы можете выполнить (гипотезы - y) и получить матрицу 3x1, тогда транспонирование этого 3x1 является матрицей 1x3, назначенной temp.

Тогда матрица 1x3 устанавливается в положение theta (2), но это не должно быть матрицей.

Последние две строки кода работает, потому что, используя мои примеры MXN выше,

(X * theta) 

будет матрица 3х1.

Затем эта матрица 3x1 вычитается на y (матрица 3x1), а результат представляет собой матрицу 3x1.

(X * theta) - y 

Таким образом, транспонирование матрицы 3x1 является матрицей 1x3.

((X * theta) - y)' 

Наконец, 1x3 матрица раз матрица 3х1 будет равна скалярной или 1x1 матрица, которая является то, что вы ищете. Я уверен, что вы уже знали, но для тщательной проверки X (:, 2) является вторым столбцом матрицы 3x2, что делает его матрицей 3x1.

2

При обновлении вам нужно сделать, как

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

Идея состоит в том, чтобы помочь пользователям продвигаться вперед, а не публиковать полные примеры реальных упражнений на дому – 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 
Смежные вопросы