2012-05-07 4 views
24

Я реализовал алгоритм спуска градиента для минимизации функции затрат, чтобы получить гипотезу для определения того, имеет ли изображение хорошее качество. Я сделал это в Октаве. Идея каким-то образом основана на алгоритме от machine learning class от Andrew Ngспуск градиента кажется неудачным

Поэтому у меня есть 880 значений «y», которые содержат значения от 0,5 до ~ 12. И у меня есть 880 значений от 50 до 300 в «Х», которые должны предсказать качество изображения.

К сожалению, алгоритм, кажется, терпит неудачу, после некоторых итераций значение для theta настолько мало, что theta0 и theta1 становятся «NaN». И моя линейная кривая регрессии имеет странные значения ...

вот код для алгоритма градиентного спуска: (theta = zeros(2, 1);, альфа = 0,01, Итерации = 1500)

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 


    tmp_j1=0; 
for i=1:m, 
    tmp_j1 = tmp_j1+ ((theta (1,1) + theta (2,1)*X(i,2)) - y(i)); 
end 

    tmp_j2=0; 
for i=1:m, 
    tmp_j2 = tmp_j2+ (((theta (1,1) + theta (2,1)*X(i,2)) - y(i)) *X(i,2)); 
end 

    tmp1= theta(1,1) - (alpha * ((1/m) * tmp_j1)) 
    tmp2= theta(2,1) - (alpha * ((1/m) * tmp_j2)) 

    theta(1,1)=tmp1 
    theta(2,1)=tmp2 

    % ============================================================ 

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

А вот вычисление для costfunction:

function J = computeCost(X, y, theta) % 

m = length(y); % number of training examples 
J = 0; 
tmp=0; 
for i=1:m, 
    tmp = tmp+ (theta (1,1) + theta (2,1)*X(i,2) - y(i))^2; %differenzberechnung 
end 
J= (1/(2*m)) * tmp 
end 
+2

я думаю, у пропускаются векторизации лекции - то же самое, что и я;) https://class.coursera.org/ml-007/lecture/30 – HaveAGuess

ответ

24

Я думаю, что ваша computeCost функция является неправильным. я присутствовал класс НГ в прошлом году, и у меня есть следующие реализации (векторизованную):

m = length(y); 
J = 0; 
predictions = X * theta; 
sqrErrors = (predictions-y).^2; 

J = 1/(2*m) * sum(sqrErrors); 

Остальная часть реализации кажется, хорошо для меня, хотя вы могли бы также векторизации их.

theta_1 = theta(1) - alpha * (1/m) * sum((X*theta-y).*X(:,1)); 
theta_2 = theta(2) - alpha * (1/m) * sum((X*theta-y).*X(:,2)); 

Затем вы устанавливаете временную thetas (здесь называемые theta_1 и theta_2) правильно вернуться к «реальной» тэте.

Как правило, более полезно векторизовать вместо циклов, это менее раздражает чтение и отладка.

+0

спасибо;) (я присутствовал на конечно, в прошлом году тоже и хотел отобразить решение по текущей проблеме;), так что ваш ответ должен быть в порядке;)) – Tyzak

+0

Кстати, может быть, я забываю, но должен ли 1-й не быть? theta_1 = theta (1) - alpha * (1/m) * sum (X * theta - y) –

+0

Спасибо, я использовал цикл вместо векторизации и имел ту же проблему, что за жизнь! Согласованные взгляды более умные – HaveAGuess

30

я векторизованы тета вещь ... может может помочь кому-то

theta = theta - (alpha/m * (X * theta-y)' * X)'; 
+0

Я думаю, что это неправильно. –

+7

Это правильный ответ. Другой способ написать это: 'theta = theta - alpha/m * (X '* (X * theta - y)):« Лучше использовать векторную зависимость, когда это возможно. –

+0

ах отлично, я знал, что должен быть способ, но я не мог получить математику на бумаге;) – HaveAGuess

2

Если все в порядке с использованием метода наименьших квадратов стоят функции, то вы можете попробовать использовать нормальное уравнение вместо градиентного спуска. Это намного проще - только одна строка - и вычислительно быстрее.

Вот нормальное уравнение: http://mathworld.wolfram.com/NormalEquation.html

И в форме октав:

theta = (pinv(X' * X)) * X' * y 

Вот учебник, который объясняет, как использовать нормальное уравнение: http://www.lauradhamilton.com/tutorial-linear-regression-with-octave

+0

Вопрос о градиентном спуске. Нормальное уравнение также может использоваться. – naren

2

Хотя не масштабируется как векторизованная версия, основанное на петле вычисление градиентного спуска должно генерировать те же результаты. В приведенном выше примере наиболее вероятным случаем градиентного спуска, неспособным вычислить правильную тету, является значение альфа.

С проверенным набором функций снижения стоимости и градиента и набором данных, аналогичных описанным в вопросе, тета заканчивается значениями NaN сразу после нескольких итераций, если alpha = 0.01. Однако, когда установлено как alpha = 0.000001, спуск градиента работает, как ожидалось, даже после 100 итераций.

0

Используя только векторы здесь является компактной реализацией LR с градиентным спуском в Mathematica:

Theta = {0, 0} 
alpha = 0.0001; 
iteration = 1500; 
Jhist = Table[0, {i, iteration}]; 
Table[ 
    Theta = Theta - 
    alpha * Dot[Transpose[X], (Dot[X, Theta] - Y)]/m; 
    Jhist[[k]] = 
    Total[ (Dot[X, Theta] - Y[[All]])^2]/(2*m); Theta, {k, iteration}] 

Примечания: Конечно, предполагается, что X представляет собой матрицу * 2, с X [[, 1]], содержащими только 1s'

13

Если вы задаетесь вопросом, как, казалось бы, сложный глядя for цикл может быть векторизованную и тесновато в одном выражении одна линия, то, пожалуйста, читайте дальше. Векторизованная форма:

theta = theta - (alpha/m) * (X' * (X * theta - y))

Ниже приводится подробное объяснение того, как мы приходим к этому векторизованному выражению с использованием градиентного алгоритма спуска:

Это градиентный алгоритм спуска для точной настройки значения & thetas : enter image description here

Предположим, что следующие значения х, у и & thetas приведены:

  • м = количество учебных примеров
  • п = число функций + 1

enter image description here

Здесь

  • (обучающих примеров) M = 5
  • п = 4 (функции + 1)
  • X = матрица mxn
  • у = х 1 вектор матрицы
  • θ = пх 1 вектор матрицы
  • х я представляет собой я примере обучения
  • х J является J функции в данном примере учебного

Далее

  • h(x) = ([X] * [θ]) (м х 1 матрица предсказанных значений для нашей обучающей выборки)
  • h(x)-y = ([X] * [θ] - [y]) (м х 1 матрицы ошибок в наших прогнозах)

всех целью машинного обучения является сведение к минимуму ошибки в прогнозах. Исходя из приведенного выше следствия, наши ошибки матрица m x 1 вектор матрицы следующим образом:

enter image description here

Чтобы вычислить новое значение θ J, мы должны получить суммирование всех ошибок (т строк) умноженные на J го значения признака обучающего множества X. То есть, принимать все значения в Е, индивидуально умножать их с J го особенностью соответствующего учебного примера, и добавить их все вместе. Это поможет нам получить новое (и, надеюсь, лучшее) значение θ j. Повторите этот процесс для всех j или количества функций. В матричной форме, это может быть записана в виде:

enter image description here

Это может быть упрощено: enter image description here

  • [E]' x [X] даст нам вектор-строку матрицы, так как Е»1 хт матрица и X - матрица mxn. Но нас интересует получение матрицы столбцов, поэтому мы переносим результирующую матрицу.

Более кратко, то его можно записать в виде: enter image description here

С (A * B)' = (B' * A') и A'' = A, мы также можем написать выше, как

enter image description here

Это исходное выражение мы начали

theta = theta - (alpha/m) * (X' * (X * theta - y)) 
0

Это должно работать: -

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

theta(2,1) = theta(2,1) - (alpha*(1/m))*((X*theta - y)'* X(:,2)); 
Смежные вопросы