Реализация градиентного спуска в октаве

Я на самом деле боролся с этим вот уже как 2 месяца. Что отличает их?

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

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

 Einar Sundgren29 апр. 2013 г., 10:42
Я не думаю, что это правильная реализация градиентного спуска. Вам необходимо обновить. Обе ваши тэты одновременно должны быть точными.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;

Ответы на вопрос(6)

Когда вы обновляете, вам нужно делать как

Start Loop {

temp0 = theta0 - (equation_here);

temp1 = theta1 - (equation_here);


theta0 =  temp0;

theta1 =  temp1;

} End loop
Решение Вопроса

который вы пропустили, не так ли? Я предполагаю, что вы связали X с вектором единиц.

   temp=X(:,2) * temp

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

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

Вы можете обновить матрицу 2х1 в одной строке кода. Если x объединить вектор единиц, сделав его матрицей 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
 Graham Slick27 мар. 2016 г., 16:22
зачем вам нужно транспонировать (1 / m) * ((X * theta) - y) '* X в вашем цикле for?
 qbert6553629 апр. 2016 г., 00:37
Такой же вопрос, как у Грэма, почему все это подвыражение транспонировано?
 AronVanAmmers11 мая 2016 г., 00:23
Результат((1/m) * ((X * theta) - y)' * X) 1x2.theta 2x1. Таким образом, бит между скобками должен быть транспонирован, чтобы иметь одинаковые размеры и вычесть его изtheta.
 kakugiki27 нояб. 2016 г., 01:49
Тот же вопрос, что и выше. Это должно быть theta = theta - (alpha / m) * X '* (X * theta - y)
 Telmo16 мая 2017 г., 23:57
Я думаю, что это связано с правилами вычисления матриц ... A * B = произведение строк A на B строк ... Я имею в виду, концептуально, можно использовать общие формулы для градиентного спуска, но тогда, когда вы ' Играя в матричных полях, вы должны адаптироваться к своим собственным правилам (умножение строк на строки, коммутативные ограничения и т. д.) ... Это только мое предположение, возможно я ошибаюсь ...

если бы X была матрицей 3x2, а тета - матрицей 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, умноженная на матрицу 3x1, будет равна скалярной матрице или матрице 1x1, что вы и ищете. Я уверен, что вы уже знали, но, если быть точным, X (:, 2) - это второй столбец матрицы 3x2, что делает ее матрицей 3x1.

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

Это проще векторизовать с помощью

h = X * theta   % m-dimensional matrix (prediction our hypothesis gives per training example)
std_err = h - y  % an m-dimensional matrix of errors (one per training example)
theta = theta - (alpha/m) * X' * std_err

ПомнитьX, это матрица дизайна, и поэтому каждая строкаX представляет обучающий пример и каждый столбецX представляет данный компонент (скажем, нулевой или первый компонент) во всех учебных примерах. Каждый столбецXоэтому @ - это именно то, что мы хотим умножить поэлементно наstd_err перед суммированием, чтобы получить соответствующий компонент тета-вектора.

.
.
.
.
.
.
.
.
.
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
 EdvardM26 июн. 2015 г., 14:55
idea помогает пользователям двигаться вперед, а не публиковать полные примеры реальных домашних упражнени

Ваш ответ на вопрос