Подтвердить что ты не робот

Градиентный спуск, кажется, терпит неудачу

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

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

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

вот код для алгоритма спуска градиента: (theta = zeros(2, 1);, alpha = 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

И вот вычисление для функции затрат:

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
4b9b3361

Ответ 1

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

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

Затем вы устанавливаете временные теты (здесь называемые theta_1 и theta_2) правильно обратно в "настоящую" тету.

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

Ответ 2

i векторизовал тэта-вещь... может помочь кому-то

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

Ответ 3

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

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

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

Это алгоритм спуска градиента для точной настройки значения θ: введите описание изображения здесь

Предположим, что заданы следующие значения X, y и θ:

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

введите описание изображения здесь

Здесь

  • m = 5 (примеры обучения)
  • n = 4 (функции + 1)
  • X = m x n matrix
  • y = m x 1 векторная матрица
  • θ = n x 1 векторная матрица
  • x i - пример обучения я th
  • x j - это функция j th в данном учебном примере

Далее

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

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

введите описание изображения здесь

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

введите описание изображения здесь

Это можно упростить как: введите описание изображения здесь

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

Более лаконично, его можно записать так: введите описание изображения здесь

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

введите описание изображения здесь

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

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

Ответ 4

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

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

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

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

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

Ответ 5

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

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

Ответ 6

Использование только векторов здесь - это компактная реализация 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 является матрицей n * 2, причем X [[, 1]] содержит только 1s '

Ответ 7

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

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