Какая ошибка в итеративной реализации алгоритма градиентного спуска ниже? - PullRequest
0 голосов
/ 23 сентября 2018

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

function [theta] = gradientDescent_i(X, y, theta, alpha, iterations)

    % get the number of rows and columns
    nrows = size(X, 1);
    ncols = size(X, 2);

    % initialize the hypothesis vector
    h = zeros(nrows, 1);

    % initialize the temporary theta vector
    theta_temp = zeros(ncols, 1);

    % run gradient descent for the specified number of iterations
    count = 1;

    while count <= iterations

        % calculate the hypothesis values and fill into the vector
        for i = 1 : nrows
            for j = 1 : ncols
                term = theta(j) * X(i, j);
                h(i) = h(i) + term;
            end
        end

        % calculate the gradient
        for j = 1 : ncols
            for i = 1 : nrows
                term = (h(i) - y(i)) * X(i, j);
                theta_temp(j) = theta_temp(j) + term;
            end
        end

        % update the gradient with the factor
        fact = alpha / nrows;

        for i = 1 : ncols
            theta_temp(i) = fact * theta_temp(i);
        end

        % update the theta
        for i = 1 : ncols
            theta(i) = theta(i) - theta_temp(i);
        end

        % update the count
        count += 1;
    end
end

А ниже векторизованная реализация того же алгоритма:

function [theta, theta_all, J_cost] = gradientDescent(X, y, theta, alpha)

    % set the learning rate
    learn_rate = alpha;

    % set the number of iterations
    n = 1500;

    % number of training examples
    m = length(y);

    % initialize the theta_new vector
    l = length(theta);
    theta_new = zeros(l,1);

    % initialize the cost vector
    J_cost = zeros(n,1);

    % initialize the vector to store all the calculated theta values
    theta_all = zeros(n,2);

    % perform gradient descent for the specified number of iterations
    for i = 1 : n

        % calculate the hypothesis
        hypothesis = X * theta;

        % calculate the error
        err = hypothesis - y;

        % calculate the gradient
        grad = X' * err;

        % calculate the new theta
        theta_new = (learn_rate/m) .* grad;

        % update the old theta
        theta = theta - theta_new;

        % update the cost
        J_cost(i) = computeCost(X, y, theta);

        % store the calculated theta value
        if i < n
            index = i + 1;
            theta_all(index,:) = theta';
    end
end

Ссылкак набору данных можно найти здесь

Имя файла ex1data1.txt

ВОПРОСЫ

Для начального тета = [0, 0] (это вектор!), Скорость обучения 0,01 и выполнение этого в течение 1500 итераций, я получаю оптимальное тета как:

  1. тета0 = -3,6303
  2. theta1 = 1.1664

Выше приведен вывод для векторизованной реализации, которую, я знаю, я реализовал правильно (она прошла все тестовые случаи на Coursera).

Однако, когда я реализовал тот же алгоритм с использованием итеративного метода (1-й код, который я упомянул), полученные тета-значения (альфа = 0,01, итерации = 1500):

  1. theta0 = -0,20720
  2. theta1 = -0,77392

Эта реализация не проходит тестовые случаи, и поэтому я знаю, что реализация неверна.

Однако я не могу понять, в чем я ошибаюсь, поскольку итерационный код выполняет ту же работу, то же самое умножение, что и векторизованный, и когда я пытался отследить результат 1 итерации обоих кодов, значенияПришло то же самое (на ручке и бумаге!), но не удалось, когда я запустил их в Октаве.

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

Вопросы для рассмотрения

  1. Реализация гипотезы верна, поскольку я проверил ее, и оба кода дали одинаковые результаты, поэтому здесь нет проблем.
  2. Я распечатал выходные данные вектора градиента в обоих кодах и понял, что здесь ошибка, потому что выходные данные здесь очень разные!

Кроме того, вот код дляпредварительная обработка данных:

function[X, y] = fileReader(filename)

    % load the dataset
    dataset = load(filename);

    % get the dimensions of the dataset
    nrows = size(dataset, 1);
    ncols = size(dataset, 2);

    % generate the X matrix from the dataset
    X = dataset(:, 1 : ncols - 1);

    % generate the y vector
    y = dataset(:, ncols);

    % append 1's to the X matrix
    X = [ones(nrows, 1), X];
end

1 Ответ

0 голосов
/ 24 сентября 2018

Что не так с первым кодом, так это то, что векторы theta_temp и h не инициализируются должным образом.Для самой первой итерации (когда count значение равно 1) ваш код выполняется правильно, потому что для этой конкретной итерации векторы h и theta_temp были правильно инициализированы в 0.Однако, поскольку они являются временными векторами для каждой итерации градиентного спуска, они не были инициализированы снова равными 0 векторам для последующих итераций.То есть, для итерации 2 значения, которые модифицированы в h(i) и theta_temp(i), просто добавляются к старым значениям.Следовательно, из-за этого код не работает должным образом.Вам необходимо обновить векторы как нулевые векторы в начале каждой итерации, и тогда они будут работать правильно.Вот моя реализация вашего кода (первая, обратите внимание на изменения):

function [theta] = gradientDescent_i(X, y, theta, alpha, iterations)

    % get the number of rows and columns
    nrows = size(X, 1);
    ncols = size(X, 2);

    % run gradient descent for the specified number of iterations
    count = 1;

    while count <= iterations

        % initialize the hypothesis vector
        h = zeros(nrows, 1);

        % initialize the temporary theta vector
        theta_temp = zeros(ncols, 1);


        % calculate the hypothesis values and fill into the vector
        for i = 1 : nrows
            for j = 1 : ncols
                term = theta(j) * X(i, j);
                h(i) = h(i) + term;
            end
        end

        % calculate the gradient
        for j = 1 : ncols
            for i = 1 : nrows
                term = (h(i) - y(i)) * X(i, j);
                theta_temp(j) = theta_temp(j) + term;
            end
        end

        % update the gradient with the factor
        fact = alpha / nrows;

        for i = 1 : ncols
            theta_temp(i) = fact * theta_temp(i);
        end

        % update the theta
        for i = 1 : ncols
            theta(i) = theta(i) - theta_temp(i);
        end

        % update the count
        count += 1;
    end
end

Я запустил код, и он дал те же значения тета, которые вы упомянули.Однако меня интересует, как вы заявили, что вывод вектора гипотез был одинаковым в обоих случаях, когда, очевидно, это было одной из причин сбоя первого кода!

...