Почему то, что я написал для курса Эндрю Нга, не принято? - PullRequest
0 голосов
/ 26 мая 2018

Курс Эндрю Нга в Coursera, который является курсом машинного обучения Стэнфорда, включает в себя задания по программированию, связанные с реализацией алгоритмов, преподаваемых в классе.Цель этого задания - реализовать линейную регрессию с помощью градиентного спуска с входным набором X, y, theta, alpha (learning rate), and number of iterations.

Я реализовал это решение в Octave, установленном в курсе языке.

function [theta, J_history] = gradientDescent(X, y, theta, alpha, num_iters)

m = length(y); 
J_history = zeros(num_iters, 1);

numJ = size(theta, 1);

for iter = 1:num_iters

    for i = 1:m

        for j = 1:numJ

            temp = theta(j) - alpha /m *  X(i, j) * (((X * theta)(i, 1)) - y(i, 1));

            theta(j) = temp

        end

        prediction = X * theta;

J_history(iter, 1) = computeCost(X,y,theta) 

 end   

end

С другой стороны, вот функция стоимости:

function J = computeCost(X, y, theta)

m = length(y); 

J = 0;

prediction = X * theta;

error = (prediction - y).^2;

J = 1/(2 * m) .* sum(error);

end

Это не проходит функцию submit().Функция submit() просто проверяет данные путем прохождения неизвестного контрольного примера.

Я проверял другие вопросы на StackOverflow, но я действительно не понимаю.:)

Большое спасибо!

Ответы [ 2 ]

0 голосов
/ 26 мая 2018

Ваш градиент кажется правильным, и, как уже указывалось в ответе @Kasinath P, вполне вероятно, что проблема в том, что код слишком медленный.Вам просто нужно векторизовать это.В Matlab / Octave вам обычно нужно избегать циклов for (обратите внимание, что, хотя у вас есть parfor в Matlab, он еще не доступен в октаве).Поэтому с точки зрения производительности всегда лучше написать что-то вроде A*x, а не повторять каждый ряд A с циклом for.Вы можете прочитать о векторизации здесь .

Если я правильно понимаю, X - это матрица размером m*numJ, где m - это число примеров, а numJ - это число элементов (или размер пространства, в котором каждыйВ этом случае вы можете переписать свою функцию стоимости как

(1/(2*m)) * (X*theta-y)'*(X*theta-y);%since ||v||_2^2=v'*v for any vector v in Euclidean space 

Теперь мы знаем из базового матричного исчисления , что для любых двух векторов s и v этоявляются функциями от R^{num_J} до R^m, якобиан s^{t}v задается как

s^{t}Jacobian(v)+v^{t}*Jacobian(s) %this Jacobian will have size 1*num_J.

. Применяя это к вашей функции стоимости, мы получаем

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

Так что если выпросто замените

for i = 1:m
    for j = 1:numJ
        %%% theta(j) updates
    end
end

на

%note that the gradient is the transpose of the Jacobian we've computed 
theta-=alpha*(1/m)*X'*(X*theta-y)

, вы увидите значительное увеличение производительности.

0 голосов
/ 26 мая 2018

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

Этот курс направлен на выполнение векторизованной реализации, поскольку она проста и удобна одновременно.Я знал это, потому что сделал это после того, как много потел.Векторизация хороша:)

...