Как именно работает это простое исчисление функции стоимости градиентного спуска ML с использованием Octave MatLab?

#matlab #machine-learning #octave #linear-regression #gradient-descent

#matlab #машинное обучение #octave #линейная регрессия #градиентный спуск

Вопрос:

Я следую курсу машинного обучения на Coursera и выполняю следующее упражнение с использованием Octave (MatLab должен быть таким же).

Упражнение связано с вычислением функции затрат для алгоритма градиентного спуска.

На слайде курса у меня есть, что это функция затрат, которую я должен реализовать с помощью Octave:

Это формула из слайда курса:

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

Итак, J является функцией некоторых ТЕТА-переменных, представленных ТЕТА-матрицей (в предыдущем втором уравнении).

Это правильная реализация MatLab Octave для вычисления J (THETA):

 function J = computeCost(X, y, theta)
%COMPUTECOST Compute cost for linear regression
%   J = COMPUTECOST(X, y, theta) computes the cost of using theta as the
%   parameter for linear regression to fit the data points in X and y

% Initialize some useful values
m = length(y); % number of training examples

% You need to return the following variables correctly 
J = 0;

% ====================== YOUR CODE HERE ======================
% Instructions: Compute the cost of a particular choice of theta
%               You should set J to the cost.

J = (1/(2*m))*sum(((X*theta) - y).^2)

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

end
  

где:

X — это матрица из 2 столбцов из m строк, для всех элементов первого столбца установлено значение 1:

 X =

1.0000    6.1101
1.0000    5.5277
1.0000    8.5186
......    ......
......    ......
......    ......
  

y — вектор из m элементов (как X):

 y =

   17.59200
    9.13020
   13.66200
   ........
   ........
   ........
  

В конечном итоге theta — это вектор из 2 столбцов, имеющий 0 значений, подобных этому:

 theta = zeros(2, 1); % initialize fitting parameters
theta
theta =

   0
   0
  

Хорошо, возвращаясь к моему рабочему решению:

 J = (1/(2*m))*sum(((X*theta) - y).^2)
  

в частности, для этого умножения матриц (умножение между матрицей X и вектором theta): я знаю, что это действительное умножение матрицы, потому что количество столбцов X (2 столбца) равно количеству строк theta (2 строки), поэтому это совершенно допустимое матричное умножение.

Мое сомнение, которое сводит меня с ума (вероятно, это тривиальное сомнение), связано с контекстом предыдущего слайда курса:

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

Как вы можете видеть во втором уравнении, используемом для вычисления текущего значения h_theta (x), он использует транспонированный тета-вектор, а не тета-вектор, как это сделано в коде.

Почему ?!?!

Я подозреваю, что это зависит только от того, как был создан тета-вектор. Он был построен таким образом:

 theta = zeros(2, 1); % initialize fitting parameters
  

это генерирует вектор столбца 2 строки 1 вместо классического вектора столбца 2 строки. Так что, возможно, мне не нужно его переносить. Но я абсолютно не уверен в этом утверждении.

Верна ли моя интуиция или чего мне не хватает?

Ответ №1:

Ваша интуиция верна. Фактически не имеет значения, выполняете ли вы умножение as theta.' * X или as X.' * theta , поскольку это либо генерирует горизонтальный вектор, либо вертикальный вектор гипотезы, представляющий все наблюдения, и то, что вы должны делать дальше, это вычитать y вектор из вектора гипотезы при каждом наблюдении и суммировать результаты. Итак, пока y имеет ту же ориентацию, что и ваша гипотеза, и вы вычитаете в каждой эквивалентной точке, тогда скалярный конечный результат суммирования будет таким же.

Достаточно часто вы увидите X.' * theta версию, предпочитаемую theta.' * X исключительно для удобства, чтобы избежать многократного переноса, просто чтобы соответствовать математической нотации. Но это нормально, поскольку базовая математика на самом деле не меняется, только порядок эквивалентных операций.

Я согласен, что это сбивает с толку, хотя и потому, что это затрудняет следование формуле, когда код выглядит так, как будто он делает что-то еще, а также поскольку он противоречит обычному соглашению о том, что вертикальный вектор представляет «координаты», а горизонтальный вектор представляет наблюдения. В таких случаях, особенно в таких языках, как matlab / octave, где ориентация вектора явно не определена в типе переменной, вдвойне важно документировать то, что вы ожидаете от входных данных, и желательно assert , чтобы в коде были инструкции, подтверждающие, что входные данные были переданы в правильном порядке.ориентация. Очевидно, что здесь они чувствовали, что в этом нет необходимости, потому что этот код в любом случае работает в контролируемых условиях в предопределенной среде упражнений, но это было бы хорошей практикой с точки зрения разработки программного обеспечения. зрения.